Times and timezones
Moderator: General Moderators
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
Times and timezones
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?
[*] 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?
- andyhoneycutt
- Forum Contributor
- Posts: 468
- Joined: Wed Aug 27, 2008 10:02 am
- Location: Idaho Falls
Re: Times and timezones
If you're storing a timestamp for the record creation, you could easily just say something like:
As far as #1 goes, I'm not sure I see the problem with working with timestamps in this example. Any more info?
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;
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Re: Times and timezones
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.
(#10850)
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
Re: Times and timezones
Thanks for the replies.
Any suggestions here?
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?)As far as #1 goes, I'm not sure I see the problem with working with timestamps in this example. Any more info?
Any suggestions here?
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.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.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Re: Times and timezones
e.g., /usr/share/zoneinfo/America/New_YorkAmbush 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.
(#10850)
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
Re: Times and timezones
That certainly isn't very portable 
- andyhoneycutt
- Forum Contributor
- Posts: 468
- Joined: Wed Aug 27, 2008 10:02 am
- Location: Idaho Falls
Re: Times and timezones
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.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?
-Andy
Re: Times and timezones
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.
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.
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
Re: Times and timezones
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.
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
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.
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";
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
Re: Times and timezones
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.
- Christopher
- Site Administrator
- Posts: 13596
- Joined: Wed Aug 25, 2004 7:54 pm
- Location: New York, NY, US
Re: Times and timezones
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...
(#10850)
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
Re: Times and timezones
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
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:
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:
Code: Select all
echo date('g:i A, T', $ts)Code: Select all
date_default_timezone_set('America/New_York');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.
- Ambush Commander
- DevNet Master
- Posts: 3698
- Joined: Mon Oct 25, 2004 9:29 pm
- Location: New Jersey, US
Re: Times and timezones
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.
Thanks ssssss; this topic is resolved.