Page 1 of 1
Times and timezones
Posted: Tue Sep 02, 2008 4:06 pm
by Ambush Commander
I'm trying to make a very locale-aware website with respect to times and dates. Because I am only storing Unix timestamps, this is surprisingly difficult. Here are the requirements:
[*] Input times are Unix timestamps, with no extra information. This cannot be fudged.
[*] Timezones are location-specific; i.e. not EST or EDT, but America/New_York
[*] The current time should be displayed appropriately as EST or EDT, depending on the year
[*] The tricky part: past times on backdated entries should have a timezone appropriate for the time of the year they were posted. Even if it's EDT now, if it was originally posted as EST it should still display as EST.
Points 1 and 4 are slaying me. Is there any easy way to do this with PHP's timezone support?
Re: Times and timezones
Posted: Tue Sep 02, 2008 4:35 pm
by andyhoneycutt
If you're storing a timestamp for the record creation, you could easily just say something like:
Code: Select all
$was_dst = false;
if( date("I",$row['some_time']) ) // DST in effect
{
// code here to switch your locale, or stored locale since
// date() is only going to tell you if the local server thinks the
// date is DST.
if( $all_of_the_above_checks out ) $was_dst = true;
}
return $was_dst;
As far as #1 goes, I'm not sure I see the problem with working with timestamps in this example. Any more info?
Re: Times and timezones
Posted: Tue Sep 02, 2008 9:47 pm
by Christopher
If you have a timestamp and a locale like "America/New_York" you should be able to convert the locale to UTC (all Unix system can do this) which would give you something like -5 hours (from GMT). You need to store that with the timestamp I suppose. Then you just do $timestamp - (-5 * 60 *60) to get the GMT. Once you get the timezone offset you can get to any other timezone.
Re: Times and timezones
Posted: Tue Sep 02, 2008 10:52 pm
by Ambush Commander
Thanks for the replies.
As far as #1 goes, I'm not sure I see the problem with working with timestamps in this example. Any more info?
So this actually works reasonably well, albeit slightly clunky. (And heaven forbid there's a time-shift that's not daylight savings time related). The next step, then, is: given America/New_York and $dst == 1 or 0, what are the three letter codes for it? I could hard-code it (EST, EDT), but does timezone give me a facility to find this out (maybe timezone_transitions_get())? Also, that means I have to run the detection code on every output of a DateTime, which also kinda sucks. (maybe a subclass is in order?)
Any suggestions here?
If you have a timestamp and a locale like "America/New_York" you should be able to convert the locale to UTC (all Unix system can do this) which would give you something like -5 hours (from GMT). You need to store that with the timestamp I suppose. Then you just do $timestamp - (-5 * 60 *60) to get the GMT. Once you get the timezone offset you can get to any other timezone.
Ah; I am starting off with a UTC timestamp (that's what I thought Unix timestamp meant). The problematic part is getting it into the appropriate timezone.
Re: Times and timezones
Posted: Wed Sep 03, 2008 12:29 am
by Christopher
Ambush Commander wrote:Ah; I am starting off with a UTC timestamp (that's what I thought Unix timestamp meant). The problematic part is getting it into the appropriate timezone.
e.g., /usr/share/zoneinfo/America/New_York
Re: Times and timezones
Posted: Wed Sep 03, 2008 7:55 am
by Ambush Commander
That certainly isn't very portable

Re: Times and timezones
Posted: Wed Sep 03, 2008 9:30 am
by andyhoneycutt
Ambush Commander wrote:The next step, then, is: given America/New_York and $dst == 1 or 0, what are the three letter codes for it?
Any suggestions here?
Take a look at
this page. I'm thinking you could build a static object (an array I would suggest) based on the information on this page, flip the keys with the values, so you'd end up with the keys being "America/New_York" and the values being "EST" or whatever. That should give your abbreviations.
-Andy
Re: Times and timezones
Posted: Fri Sep 05, 2008 8:29 am
by ssssss
I'm confused about a couple of things.
Aren't timestamps created based on the time zone set for the server? I think you have to specifically create a GMT time zone (using gmdate() or date_default_timezone_set() for example) or convert to get one. Correct me if I'm wrong here. If so, then all of your existing timestamps have time zone data, they're just all the same. They're the time zone set for your server.
Regarding number 2, I think if you've got the time zone and the timestamp (you have both), you can figure out whether it's an EST or EDT time. Use date('I'). That's a capital letter "i". Or see the date() documentation.
Regarding number 3, I'm pretty certain that that is the default behavior, based on the time zone set for your server.
Re: Times and timezones
Posted: Fri Sep 05, 2008 11:40 am
by Ambush Commander
So, part of your confusion results from the nomenclature, specifically, "timestamp". The timestamp I am referring to is called the Unix timestamp, which is basically the number of seconds since the Unix epoch (January 1, 1970, iirc). This value is completely timestamp independent, and you use a function like date() to get it into human readable form.
What you're talking about is the output of date(). The input is timezone independent, but the output can changed based on whether or not the server has a timezone set or not. gmdate() is date() with GMT set as the timezone.
So what I'm trying to do is I'm trying to output a time as either EST/EDT, and the current proposed solution is to run the Unix timestamp through date() once to determine if it's DST or not, and then set the appropriate timezone and do it again. Clunky to say the least.
Re: Times and timezones
Posted: Mon Sep 08, 2008 9:13 am
by ssssss
You're right. I was thinking that time() was time zone dependent like date(). That is not the case.
So you've got GMT timestamps. Do you have more than one time zone you're working with, or is it just NYC?
I think if you've got the time zone set, that date() will handle the Daylight savings stuff for you. EST/DST is location and time specific, and I'm pretty sure that given the time and location (time zone), PHP will figure it out for you and display the correct time.
Code: Select all
date_default_timezone_set('America/New_York');
echo "Eastern - ", date_default_timezone_get(), "\n";
echo time(), " = ";
echo date('g:i A, I'), "\n\n";
date_default_timezone_set('America/Chicago');
echo "Central - ", date_default_timezone_get(), "\n";
echo time(), " = ";
echo date('g:i A, I'), "\n\n";
date_default_timezone_set('America/Denver');
echo "Mountain - ", date_default_timezone_get(), "\n";
echo time(), " = ";
echo date('g:i A, I'), "\n\n";
date_default_timezone_set('America/Phoenix');
echo "Mountain (Arizona / No Daylight Savings Time) - ", date_default_timezone_get(), "\n";
echo time(), " = ";
echo date('g:i A, I'), "\n\n";
date_default_timezone_set('America/Los_Angeles');
echo "Pacific - ", date_default_timezone_get(), "\n";
echo time(), " = ";
echo date('g:i A, I'), "\n\n";
Re: Times and timezones
Posted: Mon Sep 08, 2008 12:51 pm
by Ambush Commander
Right. The problem is that when you use date with the second parameter (an integer timestamp), the displayed timezone is the current one, so you get times like 3:00 EDT on a date when DST was not in effect.
Re: Times and timezones
Posted: Mon Sep 08, 2008 1:40 pm
by Christopher
Right, but you can just use getdate() to see if the month/day is DST or not, and then display EST or EDT. I think I am missing something in this thread...
Re: Times and timezones
Posted: Mon Sep 08, 2008 3:05 pm
by Ambush Commander
No, you're right. I slightly don't like doing that because: 1. it's hacky and 2. I need to know the DST and non-DST timezone names in advance, or do some tricky stuff with PHP's tz databases.
Re: Times and timezones
Posted: Mon Sep 08, 2008 3:52 pm
by ssssss
Do actually want anything more than the "T" format from date()?
That will display the EST/EDT or whatever for the time zone you want, as long as you know what time zone you want, and you set it first:
Code: Select all
date_default_timezone_set('America/New_York');
If you don't know what time zone you want to display, PHP ain't going to know either. Is that the challenge?
PHP WILL know whether the time is DST or not depending on the time zone you set. So I don't understand your comment:
The problem is that when you use date with the second parameter (an integer timestamp), the displayed timezone is the current one, so you get times like 3:00 EDT on a date when DST was not in effect.
Re: Times and timezones
Posted: Mon Sep 08, 2008 4:01 pm
by Ambush Commander
Well, what do you know! Apparently, T does account for EST/EDT according to the timezone

) A little more research showed that the reason why I've been complaining about this is that when you new DateTime('@12938284'), it ignores the default timezone and sets it as UTC, so you have to setTimezone the object.
Thanks ssssss; this topic is resolved.
