I am using Laravel 5.8 and trying to validate a date field. The name of the field is date_of_birth and the validation is like the following,
$validatedData = $request->validate([
'date_of_birth' => 'date|before:today',
]);
I was using only date rule but when it failed to validate i was trying with date|before:today.
Both of the date rules are failing to for any year grater than 9999. The validation i passing as success and MySQL is showing the error as an invalid date.
Did i made any mistake on date validation or is it a bug?
if you try and convert a date higher than 10000 with DateTime natively the following occurs
$date = new DateTime("9999-12-31");
var_dump($date->format('Y-m-d'));
$date_2 = new DateTime("10000-01-01");
var_dump($date_2->format('Y-m-d'));
RESULT:
string(10) "9999-12-31"
string(10) "2000-01-01"
Notice that values higher than the year 10,000 present unexpected results.
However, if you are using a 64-bit version of PHP you can look for dates ~293billion years in either direction, see https://php.net/strtotime
The valid range of a timestamp is typically from Fri, 13 Dec 1901 20:45:54 UTC to Tue, 19 Jan 2038 03:14:07 UTC. (These are the dates that correspond to the minimum and maximum values for a 32-bit signed integer.)
Prior to PHP 5.1.0, not all platforms support negative timestamps, therefore your date range may be limited to no earlier than the Unix epoch. This means that e.g. dates prior to Jan 1, 1970 will not work on Windows, some Linux distributions, and a few other operating systems.
For 64-bit versions of PHP, the valid range of a timestamp is effectively infinite, as 64 bits can represent approximately 293 billion years in either direction.
You could probably create a custom validation rule, which validates the date against the number of seconds (assuming 64 bit PHP)
UPDATE: Looked at the documentation for validation and found
before:date
The field under validation must be a value preceding the given date. The dates will be passed into the PHP strtotime function. In addition, like the after rule, the name of another field under validation may be supplied as the value of date.
Interestingly, strtotime("10000-01-01 00:00:00") returns false, whilst strtotime("9999-12-31 23:59:59") returns an integer. the validation rule cannot parse the date.
Related
just less than 1900,more than is normal.
php version is 7
example:
date_default_timezone_set('PRC');
$sbegintime = strtotime('1900-01-01 00:00:00');
var_dump($sbegintime);exit;
php7.3:-2209017600
php7.2:-2209017943
why?
Demo ~ https://3v4l.org/MHvIs
The famous SO question relating to a historical event in China wherein the clocks were set back 352 seconds on New Years Day, 1928, meaning you can get unexpected results when dealing with dates before that time. Apparantly PHP has updated the timezone offset for that timezone (for pre 1928 dates) , from +8:00 to +8:05. (Some other change that I can't find right now, but is mentioned in the linked question, accounts for the offset changing from 352 to 343).
/* php7.2 (+8:00) */
(new DateTime('1900-01-01 00:00:00', new DateTimezone("PRC")))->format(\DateTime::ATOM);
// 1900-01-01T00:00:00+08:00"
/* php7.3: (+8:05) */
(new DateTime('1900-01-01 00:00:00', new DateTimezone("PRC")))->format(\DateTimeInterface::ATOM);
// "1900-01-01T00:00:00+08:05"
The php7.3 changes don't call out this change specifically, but if you look at the changes to php7.2.12 it says
"Upgraded timelib to 2017.08."
and for 7.3.8 it says
"Updated timelib to 2018.02."
Since timelib is the underlying library supporting PHP DateTime, a change implemented between those versions would be resposible, unfortunately I can't find a changelog.
this notes from php strtotime documentation could help you.
The valid range of a timestamp is typically from Fri, 13 Dec 1901
20:45:54 UTC to Tue, 19 Jan 2038 03:14:07 UTC. (These are the dates
that correspond to the minimum and maximum values for a 32-bit signed
integer.)
Prior to PHP 5.1.0, not all platforms support negative timestamps,
therefore your date range may be limited to no earlier than the Unix
epoch. This means that e.g. dates prior to Jan 1, 1970 will not work
on Windows, some Linux distributions, and a few other operating
systems.
I am trying to find the retirement date from joining date at the age of 58 years in php.
$retire_date = date('Y-m-d', strtotime($joining_date. '+58 years'));
it's showing 1970-01-01 , Up to "+40 years" it's showing correctly.can anyone contribute to find this one
The valid range of a timestamp is typically from Fri, 13 Dec 1901 20:45:54 UTC to Tue, 19 Jan 2038 03:14:07 UTC. (These are the dates that correspond to the minimum and maximum values for a 32-bit signed integer.) Additionally, not all platforms support negative timestamps, therefore your date range may be limited to no earlier than the Unix epoch. This means that e.g. dates prior to Jan 1, 1970 will not work on Windows, some Linux distributions, and a few other operating systems. PHP 5.1.0 and newer versions overcome this limitation though.
For 64-bit versions of PHP, the valid range of a timestamp is effectively infinite, as 64 bits can represent approximately 293 billion years in either direction.
If the number of the year is specified in a two digit format, the values between 00-69 are mapped to 2000-2069 and 70-99 to 1970-1999. See the notes below for possible differences on 32bit systems (possible dates might end on 2038-01-19 03:14:07).
Source
Beside of autista_z's answer,
you can stumple upon this if you use an incorrect date format or something like this
below an example
$joining_date = "1976-14-02";
$timeToAdd = "+ 58 years";
$objDateTime = DateTime::createFromFormat("Y-m-d",$joining_date);
$objDateTime->modify($timeToAdd);
echo "My Retire Date is ".$objDateTime->format("Y-m-d")."<br />";
$retire_date = date('Y-m-d', strtotime($joining_date.$timeToAdd));
echo $retire_date;
die;
This leads with strtotime to a result like 1970-01-01.
This is also the reason why i prefer the Datetime function createFromFormat if you know your format, because the outcome is absolutely predictable.
(in this particulary example you'll see - datetime tries to find a correct value and interprets it as 1977-02-02)
Although it doesn't really explain why +40 years would work, but maybe you tested it with different data.
$retire_date = date('Y-m-d', strtotime('+58 years', strtotime($joining_date)));
Correct answer
I think this will work for you.
$retire_date = date('Y-m-d', strtotime('+58 years', strtotime($joining_date)));
This question already has answers here:
How to calculate the difference between two dates using PHP?
(34 answers)
PHP: strtotime is returning false for a future date?
(5 answers)
Closed 8 years ago.
I need to calculate age in php.
I use this solution:
$birthdate = '1986-09-16';
$_age = floor( (strtotime(date('Y-m-d')) - strtotime($birthDate)) / 31556926);
from here
Everything works fine, but for example if
$birthday = '1194-01-06' or
$birthday = '1900-01-01'
result is always 44.
if $birthday = '1910-11-09' everything is fine again and result is 103. Why?
Note: I don't want to use diff() function, because of some issues.
EDIT:
Earlier i had problems with diff(), some
Warning range()
showed during processing and after refreshing of website everything was fine again... i could not find solution to fix it and somewhere i read that using of diff() could cause it. So i tried other solution and it worked... until now.
Finally I used this solution:
$birthDate = from database in timestamp format...
$birth = new \DateTime($birthDate);
$now = new \DateTime;
$age = $now->diff($birth)->y;
and I randomly get
Warning
range(): step exceeds the specified range
again.
It's because you're using date that is using timestamp that has a default value of time() that is based on EPOCH that started on January 1 1970 00:00:00 GMT - it's 44 years since 1970.
More on this can be found in the PHP Manual: http://php.net/manual/en/function.date.php
Integer limit issue, either:
Your OS doesn't handle negative timestamps
The maximum integer values for signed integers on a 32 bit system
strtotime()
The valid range of a timestamp is typically from Fri, 13 Dec 1901 20:45:54 UTC to Tue, 19 Jan 2038 03:14:07 UTC. (These are the dates that correspond to the minimum and maximum values for a 32-bit signed integer.)
Additionally, not all platforms support negative timestamps, therefore your date range may be limited to no earlier than the Unix epoch (1 Jan 1970).
Have you read strtotime() manual (https://php.net/manual/en/function.strtotime.php)?
The function expects to be given a string containing an English date format and will try to parse that format into a Unix timestamp (the number of seconds since January 1 1970 00:00:00 UTC), relative to the timestamp given in now, or the current time if now is not supplied.
PHP has strtotime() which assumes the input given is a string that represents a valid time. Before using strtotime(), how can I verify that the string about to be given to it is in one of its valid formats?
strtotime() returns false if it can't understand your date format, so you can check its return value. The function doesn't have any side effects, so trying to call it won't hurt.
// $format = ...
if (($timestamp = strtotime($format)) !== false) {
// Obtained a valid $timestamp; $format is valid
} else {
// $format is invalid
}
Be warned, however, that strtotime() only supports the same range of Unix timestamps as the server architecture does. This means it will incorrectly return false for certain date ranges. From the manual:
Note:
The valid range of a timestamp is typically from Fri, 13 Dec 1901 20:45:54 UTC to Tue, 19 Jan 2038 03:14:07 UTC. (These are the dates that correspond to the minimum and maximum values for a 32-bit signed integer.) Additionally, not all platforms support negative timestamps, therefore your date range may be limited to no earlier than the Unix epoch. This means that e.g. dates prior to Jan 1, 1970 will not work on Windows, some Linux distributions, and a few other operating systems. PHP 5.1.0 and newer versions overcome this limitation though.
For 64-bit versions of PHP, the valid range of a timestamp is effectively infinite, as 64 bits can represent approximately 293 billion years in either direction.
Because server architectures can vary, you may be limited to 32-bit Unix timestamps depending on your use case, even though 64-bit timestamps cover a practically infinite period of time.
Actually you can't check that before executing the function, but you could take a look at the official php.net page. The only thing you can do is checking whether your function returns "false".
Here's a link strtotime().
There are a lot of examples of what you can do with strtotime().
In .net, there are the static properties DateTime.MinDate, and DateTime.MaxDate that conveniently return the minimum and maximum valid dates for a DateTime object.
I'm dabbling in web programming right now, using php + mysql + javascript. There doesn't seem to be the same convenient min/max date values in that programming environment? For example, the max value of a date object in mysql is 9999-12-31, but the php function strtotime() doesn't like that value.
I would like a cross-language minimum date (to be used to mean 'not set yet' for example), and a cross-language maximum date (to be used to mean 'good forever'). That means there could be those min dates and max dates stored in a database, which php would retrieve (and it would have to differentiate between 'normal' dates and min/max date), and eventually they would trickle down to some javascript (which, again would have to differentiate between 'normal' dates and min/max date).
So, which date value do you use for min/max dates when working in php + mysql + javascript? And how do you store these constants -- it'd be nice to define them only in one place and have them be available in each of php + mysql + javascript...
Thanks
For the JavaScript side, the range is a lot bigger:
The date is measured in milliseconds since midnight 01 January, 1970 UTC. A day holds 86,400,000 milliseconds. The Date object range is -100,000,000 days to 100,000,000 days relative to 01 January, 1970 UTC.
So you could do this in your JavaScript:
var min_date = new Date(-100000000*86400000);
var max_date = new Date( 100000000*86400000);
I'll just answer the PHP portion of the question. According to the PHP date() documentation:
The valid range of a timestamp is typically from Fri, 13 Dec 1901 20:45:54 GMT to Tue, 19 Jan 2038 03:14:07 GMT. (These are the dates that correspond to the minimum and maximum values for a 32-bit signed integer)
PHP uses 32 bit integer values to represent date/time — that means you can use the PHP_INT_MAX constant to derive the integer values associated with the min/max dates:
echo date('m/d/Y G:i:s', PHP_INT_MAX + 1); // minimum valid date
echo date('m/d/Y G:i:s', PHP_INT_MAX); // maximum valid date
OUTPUT:
12/13/1901 15:45:52
01/18/2038 22:14:07
Not sure why that's off by 2 seconds on the min date they quoted, but you get the general idea.
For the 'not set yet' logical value, maybe a null value is better.