PHP: setcookie() to expire after the year 2038 - php

Currently I'm converting all my PHP unix timestamps to work beyond 2k38 issue.
I noticed that setcookie() expire date parameter uses the unix timestamp. Is there a way to set expire date with alternative method, maybe using the DateTime class somehow?
From the PHP document about expire date:
Note: You may notice the expire parameter takes on a Unix timestamp,
as opposed to the date format Wdy, DD-Mon-YYYY HH:MM:SS GMT, this is
because PHP does this conversion internally.

You cannot change the function signature. Well, not at least without fiddling with strange PHP extensions. But since the cookie spec does not use Unix timestamps at all you can simply write your own function and call header() manually:
Set-Cookie: lang=en-US; Expires=Wed, 09 Jun 2099 10:18:14 GMT
Set-Cookie: lang=en-US; Max-Age=8640000
... and hope that browsers are able to process the date:
If the expiry-time is later than the last date the user agent can
represent, the user agent MAY replace the expiry-time with the last
representable date.
Or you can simply use seecookie() anyway. As far as I know, it'll only be an issue in some 32-bit versions of PHP.

Related

querystring GMT datetime in Summer

I need to send a querystring parameter to our API server which is taking times in GMT format.
I am a bit confused about what values I need to send during the summertime, since the dates are in GMT format.
Let's assume we are in London (UK), it's 3PM, and it's the 15th of May
2016.
Is the correct date value:
?date=2016-05-15T15:00:00Z
or
?date=2016-05-15T15:00:00+01:00
or
?date=2016-05-15T16:00:00Z (assuming I always want to use the Z "Zulu Time")
Since London is in BST on that date, then 2016-05-15T15:00:00+01:00 would be the most fully qualified correct form.
If you were to normalize that to UTC, then it would become 2016-05-15T14:00:00Z. Z is equivalent to +00:00, so you have to adjust the hour by the inverse of the original offset.
2016-05-15T15:00:00Z is incorrect, as that is an hour later.
As to which of the two correct forms are more correct for your particular API, there's no way to answer that as you gave no details about how the API is designed, what language it's implemented in, what code is parsing the input, etc. In many cases, either would be accepted. However if the API requires to know local time as well as the universal time, then only the 2016-05-15T15:00:00+01:00 for would convey both.
Also, recognized that there's no such thing as "GMT format". GMT is a time zone, equivalent to UTC+00:00. What you actually have here is a string in ISO8601 extended format, also specified under RFC3339. This is commonly said to be the "ISO format".

PHP: strtotime and dates beyond 19 Jan 2038

Am using the strtotime function to find the difference between two given dates like this:
$diff_in_mill_seconds = strtotime($ToDate) - strtotime($FromDate);
$difference_in_years = round($diff_in_mill_seconds / (365*60*60*24),1);
This script fails when the $ToDate is beyond 2038-01-19.
The official PHP Documentation says:
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
The PHP Documentation also says:
Using this function for mathematical operations is not advisable. It is better to use DateTime::add() and DateTime::sub() in PHP 5.3 and later, or DateTime::modify() in PHP 5.2.
I cannot use DateTime::add() and DateTime::sub() as the PHP version on the server is 5.2.
So, how do I calculate the difference between two dates (beyond 2038-01-19) in years using php 5.2?
It's the UNIX Y2K38 bug. It has been fixed in 64bit implementations of PHP or by using DateTime::diff, which does not use integers internally and hence does not suffer from the problem.
You need either. There's no real fix without switching platforms.

How do I force strtotime() to return date instead of time when given ambiguous $time?

Good evŠµning!
echo date('r', strtotime('10.01.11'));
Prints: Sun, 05 Feb 2012 10:01:11
Expected: Mon, 10 Jan 2011 00:00:00
How do I force strtotime() to parse the input string as a date only? I have to convert a bunch of dates in different format. DateTime::format is not an option since I don't know all the formats the script will run into, and it's not even installed on the server (and i don't have privileges to do it).
Tried
strtotime('day 10.01.11'),
strtotime('10.01.11 00:00:00'),
strtotime('10.01.11 midnight')
- nothing worked.
Any help is much appreciated
How do I force strtotime() to parse the input string as a date only?
You don't. strtotime uses very well-defined parsing formats. What it generates will depend entirely on what you give it.
'10.01.11' is parsed as a time format, as it will always interpret three pairs of digits separated by periods as a time. It will recognize dates when separated by dashes, slashes or spaces. Annoyingly, there's an example there on the date format page that uses dots, but there doesn't seem to be a sure-fire way to force date parsing instead of time parsing. Sigh, PHP.
If you need that specific format to be interpreted as a date instead of a time, you have two options.
First, you can use a different date parsing method. If the expected format never changed, you could use DateTime::createFromFormat() or the horrifying strptime. You've indicated in comments that the format will vary and your PHP version is old enough not to have DateTime, so this might not work for you.
Second, you can pre-process the data. At least in this example, a conversion of . to / may do the trick, though 10/01/11 can be ambiguous as a date to humans. There's nothing wrong with a little regex sniffing to determine how to best process data.
There's also a third option: if you're getting this information from users, make your application begin forcing users to enter dates in a normal, consistent, parseable format. It may take some time to train your users to use YYYY-MM-DD, but it's probably the most sane long-term bet.
Is modifying the input an option for you?
$str = '10.01.11';
$str = str_replace('.', '/', $str);
echo date('r', strtotime($str));
However, this will still output Sat, 01 Oct 2011 00:00:00, according to the MM.DD.YY pattern (US standard).
EDIT: Depending on you usage, you might consider creating a list of regex patterns and parse the date accordingly. It is very hard to make a code like this to be open to all possibilities.
Tested, this works:
$date = DateTime::createFromFormat('d.m.y', '10.01.11');
echo $date->format('r');
http://codepad.viper-7.com/OH7Kyn
why don't you add the time set to 00:00:00 by default?
e.g.
echo date('D, d M Y H:i:s', strtotime('10.01.11'));
also strtotime uses the american date format so this will be translated into 1st of october 2011. it's easier to use the iso date format
I don't think strtotime knows how to parse those dates. To avoid potential ambiguity, it's best to use ISO 8601 (YYYY-MM-DD) dates.

PHP unix time conversion

I want to convert 12/31/2099 to Unix time using PHP. I tried strtotime('12/31/2099') but the function returns null.
I tried converting it to Unix time using an online conversion tool which gives 4102358400 which, when turned into a date gives 01/18/2038.
How can I convert dates to Unix time and again convert it back to a readable format like 12/31/2099?
In old versions of PHP ( < 5.1.0), strtotime supported a max date of Tue, 19 Jan 2038 03:14:07 UTC. To bypass this limitation, upgrade to 5.1.0 or later.
64-bit versions are unaffected by this limitation.
For more information, see the Notes: at http://www.php.net/strtotime
32-bit Unix timestamps run out in 2038, so if you're on a 32-bit system, that would cause a problem.
The unix timestamp of a point in time is the number of seconds since 1970-01-01 00:00:00 UTC to this point in time. On 2038-01-18 this will overflow a 32bit signed int - call it the Y2K bug of the unices.
Mind though, that this is a problem of the implementation, not the algotithm: Most current implementations use an unsigned 32bit int, but it is to be expected that 32bit ints will be a thing of the past some time before 2038
Usual workarounds include an if-branch to detect whether a date is after the wraparound and adjust accordingly.

How can I work with dates before 1900 in PHP?

I am using PHP and jQuery to build an interactive timeline which needs to display dates between 1500 and 2020. I usually use PHP's strtotime function when working with dates, but it does not work for dates pre-1900.
The dates will come from a MySQL database, and are formatted as strings such as "January 31, 1654" (this may not be the ideal format, but I can't change how they are stored). I am using PHP to parse the dates, basically converting them into pixel values which determine where they are displayed on the timeline.
What is the easiest way to parse these historical dates?
The DateTime class, here, might help (quoting):
Each component of date (e.g. year) is
internally stored as 64-bit number so
all imaginable dates (including
negative years) are supported.
But note that:
It's only exists in PHP >= 5.2
And several methods only exist in PHP >= 5.3
So: beware of which methods you're using, if you're developping on PHP 5.3 and want your software to be compatible with PHP 5.2
Another solution (especially, if using Zend Framework in your application) would be the Zend_Date component (quoting):
Although PHP 5.2 docs state, "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," Zend_Date supports a
nearly unlimited range, with the help
of the BCMath extension
Using the wonderful Carbon Library, dates in the past are not a problem:
$date = Carbon::now();
$date->subCenturies(23);
echo $date->format('Y-m-d');
// -0282-03-15
This works for dates where humans have been around. For everything else, using a date (with day and month, set on the AC/BC scale) does not make a lot of sense.

Categories