PHP DateTime CreateFromFormat Issue - php

function validateDate($date, $format = 'm-Y') {
$d = DateTime::createFromFormat($format, $date);
return $d && $d->format($format) == $date;
}
validateDate('09-2017', 'm-Y');
function was copied from this answer or php.net
I'm very puzzled to why this returns false while it returns true for the previous months. Any ideas?

It's because you're not supplying a day, so it's using the current day by default. Current day is 31, but September only has 30 days, so it skips to October 1st.
Look at this example:
function validateDate($date, $format = 'm-Y') {
$d = DateTime::createFromFormat($format, $date);
echo $d->format("d-".$format); // added the day for debugging
return $d && $d->format($format) == $date;
}
var_dump(validateDate('08-2017', 'm-Y')); // 31-08-2017, true
var_dump(validateDate('09-2017', 'm-Y')); // 01-10-2017, there's no 31-09-2017, false
function was copied from this answer or php.net
This is a little rudimentary, but you can detect if there's no d in the format and manually set it to 1 to avoid this:
<?php
function validateDate($date, $format = 'm-Y') {
if (strpos($format, "d") === false) {
$format = "d ".$format;
$date = "01 ".$date;
}
$d = DateTime::createFromFormat($format, $date);
return $d && $d->format($format) === $date;
}
var_dump(validateDate('08-2017', 'm-Y')); // 31-08-2017, true
var_dump(validateDate('09-2017', 'm-Y')); // 01-09-2017, true

If you are not supplying a day. current one is used; just like explained in previous answer.
But this can be quickly solved with one format sign: !, which resets all fields (year, month, day, hour, minute, second, fraction and timezone information) to the Unix Epoch; see format table.
Fix:
function validateDate($date, $format = 'm-Y') {
$d = DateTime::createFromFormat('!'.$format, $date);
return $d && $d->format($format) == $date;
}
function was copied from this answer or php.net

Related

Check Date if Saturday or Sunday [duplicate]

This function seems to only return false. Are any of you getting the same? I'm sure I'm overlooking something, however, fresh eyes and all that ...
function isweekend($date){
$date = strtotime($date);
$date = date("l", $date);
$date = strtolower($date);
echo $date;
if($date == "saturday" || $date == "sunday") {
return "true";
} else {
return "false";
}
}
I call the function using the following:
$isthisaweekend = isweekend('2011-01-01');
If you have PHP >= 5.1:
function isWeekend($date) {
return (date('N', strtotime($date)) >= 6);
}
otherwise:
function isWeekend($date) {
$weekDay = date('w', strtotime($date));
return ($weekDay == 0 || $weekDay == 6);
}
Another way is to use the DateTime class, this way you can also specify the timezone.
Note: PHP 5.3 or higher.
// For the current date
function isTodayWeekend() {
$currentDate = new DateTime("now", new DateTimeZone("Europe/Amsterdam"));
return $currentDate->format('N') >= 6;
}
If you need to be able to check a certain date string, you can use DateTime::createFromFormat
function isWeekend($date) {
$inputDate = DateTime::createFromFormat("d-m-Y", $date, new DateTimeZone("Europe/Amsterdam"));
return $inputDate->format('N') >= 6;
}
The beauty of this way is that you can specify the timezone without changing the timezone globally in PHP, which might cause side-effects in other scripts (for ex. Wordpress).
If you're using PHP 5.5 or PHP 7 above, you may want to use:
function isTodayWeekend() {
return in_array(date("l"), ["Saturday", "Sunday"]);
}
and it will return "true" if today is weekend and "false" if not.
Here:
function isweekend($year, $month, $day)
{
$time = mktime(0, 0, 0, $month, $day, $year);
$weekday = date('w', $time);
return ($weekday == 0 || $weekday == 6);
}
The working version of your code (from the errors pointed out by BoltClock):
<?php
$date = '2011-01-01';
$timestamp = strtotime($date);
$weekday= date("l", $timestamp );
$normalized_weekday = strtolower($weekday);
echo $normalized_weekday ;
if (($normalized_weekday == "saturday") || ($normalized_weekday == "sunday")) {
echo "true";
} else {
echo "false";
}
?>
The stray "{" is difficult to see, especially without a decent PHP editor (in my case). So I post the corrected version here.
For guys like me, who aren't minimalistic, there is a PECL extension called "intl".
I use it for idn conversion since it works way better than the "idn" extension and some other n1 classes like "IntlDateFormatter".
Well, what I want to say is, the "intl" extension has a class called "IntlCalendar" which can handle many international countries (e.g. in Saudi Arabia, sunday is not a weekend day). The IntlCalendar has a method IntlCalendar::isWeekend for that. Maybe you guys give it a shot, I like that "it works for almost every country" fact on these intl-classes.
EDIT: Not quite sure but since PHP 5.5.0, the intl extension is bundled with PHP (--enable-intl).
This works for me and is reusable.
function isThisDayAWeekend($date) {
$timestamp = strtotime($date);
$weekday= date("l", $timestamp );
if ($weekday =="Saturday" OR $weekday =="Sunday") { return true; }
else {return false; }
}
As opposed to testing the explicit day of the week string or number, you can also test using the relative date this weekday of the supplied date.
A direct comparison between the values is not possible without a workaround, as the use of weekday resets the time of the supplied date to 00:00:00.0000.
DateTimeInterface objects
$date->setTime(0, 0, 0) != $date->modify('this weekday');
DateTimeInterface Method
A simple method to implement to ensure the supplied date object is not changed.
function isWeekend(DateTimeInterface $date): bool
{
if ($date instanceof DateTime) {
$date = DateTimeImmutable::createFromMutable($date);
}
return $date->setTime(0,0,0) != $date->modify('this weekday');
}
isWeekend(new DateTimeImmutable('Sunday')); //true
strtotime method
With strtotime you can compare with the date('Yz') format. If the Yz value changes between the supplied date and this weekday, the supplied date is not a weekday.
function isWeekend(string $date): bool
{
return date('Yz', strtotime($dateValue)) != date('Yz', strtotime($dateValue . ' this weekday'));
}
isWeekend('Sunday'); //true
Example
https://3v4l.org/TSAVi
$sunday = new DateTimeImmutable('Sunday');
foreach (new DatePeriod($sunday, new DateInterval('P1D'), 6) as $date) {
echo $date->format('D') . ' is' . (isWeekend($date) ? '' : ' not') . ' a weekend';
}
Result
Sun is a weekend
Mon is not a weekend
Tue is not a weekend
Wed is not a weekend
Thu is not a weekend
Fri is not a weekend
Sat is a weekend

dateinterval::format enforcing leading zeros on month day

I'm running a date validation in PHP:
public function isValidDate($date) {
$valid = false;
$valid_formats = array(
'Y-m-d',
'm-d-Y',
'Y/m/d',
'm/d/Y'
);
foreach ($valid_formats as $format) {
if (!$valid) {
$d = \DateTime::createFromFormat($format, $date);
$valid = $d && $d->format($format) == $date;
}
}
return $valid;
}
What's odd is that if the format is m/d/Y, and I pass 1/1/2016 to it, it is false, because when I run $d->format(m/d/Y), I get a result of 01/01/2016.
Any ideas on why it is enforcing the leading zeros?
Thats because you have not defined a valid format that matches a date with only one character day and month fields
function isValidDate($date) {
$valid = false;
$valid_formats = array(
'Y-m-d',
'm-d-Y',
'Y/m/d',
'm/d/Y',
'j/n/Y', // <- NEW day/month 1/1
'n/j/Y' // <- NEW month/day 1/1
);
foreach ($valid_formats as $format) {
if (!$valid) {
$d = \DateTime::createFromFormat($format, $date);
$valid = $d && $d->format($format) == $date;
}
}
return $valid;
}
echo isValidDate('1/1/2016') ? 'VALID' : 'INVALID';
There may be others you need to add as well!
I found the answer, from W3Schools.
It seems the official documentation is missing some format options:
d - Day of the month; with leading zeros
j - Day of the month; without leading zeros
m - Month (01-12)
n - Month (1-12)
'j' and 'n' are missing from http://php.net/manual/en/dateinterval.format.php

Find out whether string has date in it

I have a string "scbdemo2016-10-21:getlastweekReadBooks4795".
How to find out the above string has date in it and to validate the date is current day date.
Easily done with regular expressions:
$isToday = stringDateToday("scbdemo2016-10-21:getlastweekReadBooks4795");
function stringDateToday($string) {
$reg = "/\d{4}-\d{2}-\d{2}/";
$date = new DateTime();
preg_match($reg, $string, $matches);
if (isset($matches[0])) {
return $matches[0] == $date->format("Y-m-d");
}
return false;
}
stringDateToday() will return true if the date in the string is today. The date can be anywhere in the string.
EDIT:
As suggested in the comments, you may want to change new DateTime() to new DateTime('now', new DateTimeZone('Europe/London')) to specify timezone.
Here is your code, but it only works with string that has : character, anyways
function checkdata($date, $format)
{
$format=strstr(preg_replace("/[a-zA-Z]+/", '',$format),":",true);
// date_default_timezone_set('UTC');
$d = DateTime::createFromFormat($format, $date);
if($d && $d->format($format) === $date) {
return true;
} else {
return false;
}
}
$data="scbdemo2016-10-21:getlastweekReadBooks4795";
if(checkdata($data,'Y-m-d'))
echo "Yes";
else
echo "NO";

unable to validate date

i am trying to validate date which is in between 1996 & 1900 for date of birth field. And also it should be in correct date format
but this below function is giving me output always false.
what i am doing wrong ?
function validateDate($date) {
$this->load->helper('date');
$datestring1 = "%Y-%m-%d";
$date1 = "1996-01-01";
$date2 = "1990-01-01";
$d = DateTime::createFromFormat('Y-m-d', $date);
return $d && $d->format('Y-m-d') == $date && $date > $date2 && $date < $date1;
}
I don't know what is wrong with your function but this should work
function validate($date){
$d = DateTime::createFromFormat('Y-m-d', $date);
if($d === false) return false;
$y = intval($d->format('Y'));
return $y >= 1990 && $y < 1996;
}
If you want 1988-07-25 to be a valid entry (as shown in your screenshot), your "date2" should be "1980" or something earlier instead of "1990".
You can try this
function validation($date){ //yyyy-mm-dd
$date_element = explode('-', $date);
if(is_array($date_element) and isset($date_element[0]) and ($date_element[0] >= 1990 and $date_element[0] <= 1996)){
return true;
}
return false;
}

php date string to timestamp - inverse_date()

I'm looking for a function that does the inverse of date(). Meaning:
$timestamp = inverse_date($format_string, $date_string);
$d = date($format_string, $timestamp);
if ($d === $date_string) {
echo 'This is what I want';
}
Problems I've run into so far:
strtotime - guesses format, so it might not be good for all formats
strptime - uses strftime's formatting that is different from date's
SOLUTION:
function inverse_date($format_string, $date_string) {
$dateTime = date_create_from_format($format_string, $date_string);
$value_ts = date_format($dateTime, 'U');
return $value_ts;
}
Thanks to Till Helge Helwig for the link.
function inverse_date($format_string, $date_string) {
$dateTime = date_create_from_format($format_string, $date_string);
$value_ts = date_format($dateTime, 'U');
return $value_ts;
}

Categories