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.
Related
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)));
I have been trying to convert Date of birth from my DB into DATE FORMat but i am facing the problem of there are some negative values in DOB fields which when i check from online FROM_UNIXTIME calclator then it give different result and if i check it with FROM_UNIXTIME(-957632400) then it always returns NULL for negative values . KIndly let me know how can i get date format from such UNIX format like from -957632400
We can do this instead:
FROM_UNIXTIME(0) + INTERVAL -957632400 SECOND
The FROM_UNIXTIME function is limited by the allowable range for the TIMESTAMP datatype, which is the standard 32-bit unsigned int range 1970-01-01 thru 2038-01-something. Other software has been updated to support 64-bit signed integers, but MySQL doesn't yet provide that functionality (at least not in 5.1.x).
The workaround in MySQL is avoid using the TIMESTAMP datatype and using the DATETIME datatype instead, when we need a larger range (e.g. dates before Jan 1, 1970).
We can use the DATE_ADD function to subtract seconds from Jan 1, 1970, like this:
SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)
N.B. You will probably need to account for timezone "offsets" from UTC in doing those types of calculations. MySQL is going to interpret DATETIME values as being specified in the time_zone setting of the current MySQL session, rather than UTC (time_zone = '+00:00')
FOLLOWUP:
Q: Okay, Means if we select dates below '1970-01-01 00:00:00' then the negative value saves in the db else it would be positive. Right? – soft genic
A: Uhhh, no. If you select date/datetime values before Jan 1, 1970, MySQL will return DATE or DATETIME values before Jan 1, 1970. If you store DATE or DATETIME values before Jan 1, 1970, then MySQL will store DATE or DATETIME value before Jan 1, 1970, within the allowable range supported by those datatypes. (something like 0001-01-01 thru 9999 ?)
If you need to store really really big positive and negative integers in the database, you would likely store those in a column defined as BIGINT.
The internal representation of a DATE column requires 3-bytes of storage, and DATETIME requires 8-bytes of storage (up to MySQL version 5.6.4. The internal representation and storage of DATE and DATETIME values changed in 5.6.4)
So no, MySQL does not store date values before 1970 as "negative integers".
If you think about it a bit, MySQL is free to implement whatever storage mechanism they want. (And each storage engine is free to serialize that representation to disk however it wants.)
Why 3 bytes for a date?
One option MySQL has (and I'm not representing that this is the way it is done) could be to break up the date into it's year month and day components.
The representation of integer values in the range - requires -
0 - 9999 - 14 bits
0 - 12 - 4 bits
0 - 31 - 5 bits
That's a total of 23 bits, which happens to handily fits into 3 bytes. This just demonstrates that it's not necessary for MySQL to represent date values before Jan 1. 1970 as negative integers, so we shouldn't make the assumption that it does. (But we'd really only be concerned with this level of detail if we were working on a storage engine for MySQL.)
From DATETIME to unix timestamp:
SELECT TIMESTAMPDIFF(SECOND, FROM_UNIXTIME(0), '1956-12-24 01:06:49');
From timestamp to DATETIME:
SELECT DATE_ADD(convert_tz(FROM_UNIXTIME(0), ##session.time_zone,'+00:00'), INTERVAL -410914391 SECOND);
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.
I want to ask about changing a datetime value of PHP with datetime value from MySQL data.
I have try to do this at PHP:
$sitgl = date('Y-m-d', strtotime(2012-01-12));
$sijam = date('H:i:s', strtotime(13:00:00));
$awal = $sitgl.' '.$sijam;
$awal2 = date('Y-m-d H:i:s', strtotime($awal));
$debrangkat = strtotime($awal2);
And I'm trying to convert same datetime at MySQL like this (convert it to seconds):
SELECT date_start_book, time_start_book, (TO_DAYS(CAST(date_start_book AS DATE))*86400) + TIME_TO_SEC(CAST(time_start_book AS TIME)) FROM `t_request_queue` WHERE `request_id` = '1301-0087'
which is date_start_book value is 2012-01-12 and time_start_book value is 13:00:00
My question is: why the PHP code return value : 1357970400 but the MySQL value return 63525214800 ?
what must I do to make both of value is same? Is strtotime() not return a seconds or why?
First of all as others have suggested that php code is really hurting brain. You could make that Unix Timestamp in just one line. But to answer your real question. MYSQL TO_DAYS works different than PHP UNIX Timestamp
According to MySQL Website
Given a date date, returns a day number (the number of days since year 0).
mysql> SELECT TO_DAYS(950501);
-> 728779
mysql> SELECT TO_DAYS('2007-10-07');
-> 733321
TO_DAYS() is not intended for use with values that precede the advent of the Gregorian calendar (1582), because it does not take into account the days that were lost when the calendar was changed. For dates before 1582 (and possibly a later year in other locales), results from this function are not reliable
And according to PHP Website timestamp is
Returns the current time measured in the number of seconds since the
Unix Epoch (January 1 1970 00:00:00 GMT).
And hence the difference in two values. Their starting point is way too distant from each other. MySQL starts from year 0 and PHP starts from year 1970.
Suggestion
I would suggest you save php's timestamp in mysql rather than a formatted date time. This will help you stay consistent and allow you to perform any date or time comparisons easily.
Finally, I change the PHP to datetime and at query I'm using ADD_DAYS to add a date with a seconds then I compare it with the PHP datetime result.
So many thanks to all contributor.
Hi i am working on facebook Graph API where i need all the posts information of a group. So I did it and saw [created_date'] => '2013-01-25T00:11:02+0000' what does this date and time represent i mean i know 2013-01-25 is date and 00:11:02 is time but what does T and +0000 represent.
BTW where is the server of facebook. Which timestamp should i use to match facebook time?
Thank you.
T = TIME and the +0000 is timezone offset. Facebook uses localized timezones. You can request a Unix timestamp instead of the string by adding the parameter: date_format=U to your graph API call.
Please see this link for more information.
The date format is called ISO 8601. The letter T is used to separate date and time unambiguously and +0000 is used to signify the timezone offset, in this case GMT or UTC.
That said, you generally don't need to worry so much about the actual contents; rather you should know how to work with them. To use such a date, you can use strtotime() to convert it into a time-stamp:
$ts = strtotime('2013-01-25T00:11:02+0000');
To convert the time-stamp back into a string representation, you can simply use gmdate() with the predefined date constant DATE_ISO8601:
echo gmdate(DATE_ISO8601, $ts);
Alternatively, using DateTime:
// import date
$d = DateTime::createFromFormat(DateTime::ISO8601, '2013-01-25T00:11:02+0000');
// export date
echo $dd->format(DateTime::ISO8601), PHP_EOL;
This is a standard format, specifically ISO 8601.
As much as I don't like linking to it, http://www.w3schools.com/schema/schema_dtypes_date.asp does have a good "human-understandable" explanation:
The dateTime is specified in the following form "YYYY-MM-DDThh:mm:ss"
where:
YYYY indicates the year
MM indicates the month
DD indicates the day
T indicates the start of the required time section
hh indicates the hour
mm indicates the minute
ss indicates the second
To specify a time zone, you can either enter a dateTime in UTC time by
adding a "Z" behind the time - like this:
2002-05-30T09:30:10Z
or you can specify an offset from the UTC time by adding a positive or
negative time behind the time - like this:
2002-05-30T09:30:10-06:00
or
2002-05-30T09:30:10+06:00
Therefore, in your case the +0000 indicates a time offset of 0 from UTC.