Something "strange" just happened with a site I'm developing that left me confused about time with Perl again.
Part of the web application I'm building includes a web blog, and there's a user-friendly way of specifying what time the blog should be posted with, where the hours/minutes/days/months etc are in individual text boxes, with JavaScript automatically keeping them up-to-date if the user wants it to.
So, when submitted, the site needs to turn the human-readable values they gave and turn it into an epoch time stamp when it saves the entry to the database.
The idea is that all blog entries are saved with Unix time stamps, so then the remote user (who might have their own time zone specified, or else they default to the server's time zone) can see the time stamps on the posts adjusted to match their own time zone. The user's time zone is saved as an offset of GMT time (e.g. -28800 for Pacific time), and the code to calculate the time stamp is as follows:
So the time stamp adjusted for the user would be called like:
Anyway...
The issue I noticed was that, after transferring all the code to the other server, that if I posted a blog entry with the current time, it would actually start showing up with a time that was 3 hours in the past.
I found out that the problem was that my dev server had a Pacific time zone, and my production server was Eastern time. So, when the code did Time::Local::timelocal to turn my user-supplied time into unix time, it did so in the Eastern time zone, so that the resulting unix time is what `time()` would've been, on the east coast, when the date/time is what I gave it via the web front-end.
When I changed the server's time zone to Pacific, it worked; what also worked is getting it to show the correct time in different time zones. If I change the time zone back to Eastern after this point, it still shows the correct time. So it appears that all my code dealing with time zones is working fine, and the only weak link is turning the user-supplied time into unix time, and it seems like this is highly timezone-dependent.
So the question is: is there a way to make Time::Local give local time for a specific time zone? The idea is that if I can get the server to calculate unix time using the same time zone that the end user is probably using, that it would work correctly (i.e. so if server time is Eastern, and the end user is on Pacific, the time that the end user submits with the blog entry will be calculated into unix time in the Pacific time zone, instead of in Eastern).
Also if anyone sees any flaws in any of my other time-related code, feel free to point it out.
Cuvou.com | My personal homepage
Part of the web application I'm building includes a web blog, and there's a user-friendly way of specifying what time the blog should be posted with, where the hours/minutes/days/months etc are in individual text boxes, with JavaScript automatically keeping them up-to-date if the user wants it to.
So, when submitted, the site needs to turn the human-readable values they gave and turn it into an epoch time stamp when it saves the entry to the database.
The idea is that all blog entries are saved with Unix time stamps, so then the remote user (who might have their own time zone specified, or else they default to the server's time zone) can see the time stamps on the posts adjusted to match their own time zone. The user's time zone is saved as an offset of GMT time (e.g. -28800 for Pacific time), and the code to calculate the time stamp is as follows:
Code:
sub getTimestamp {
my ($format,$epoch) = @_;
# If no epoch time was given, use the current time.
if (!defined $epoch || (defined $epoch && $epoch =~ /[^0-9]/)) {
$epoch = time();
}
# Format the time.
return Time::Format::time_format ($format,$epoch);
}
sub getLocalTimestamp {
my ($format,$epoch,$tz) = @_;
# If no epoch time, use the current time.
if (!defined $epoch || (defined $epoch && $epoch =~ /[^0-9]/)) {
$epoch = time();
}
# Get the current GMT time based on the server's localtime.
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime ($epoch);
# Get the adjust epoch time back from this.
my $gm = Time::Local::timelocal ($sec,$min,$hour,$mday,$mon,$year);
$gm = $epoch unless defined $tz;
# Offset the epoch time.
if (defined $tz) {
# Need to apply daylight saving time?
if (isDST()) {
$tz += 3600;
}
$gm += $tz;
}
# Format the time.
return getTimestamp ($format,$gm);
}
sub isDST {
my ($isdst) = (localtime(time()))[8];
return $isdst ? 1 : undef;
}
So the time stamp adjusted for the user would be called like:
Code:
my $ts = getLocalTimestamp ("Weekday, Month dd yyyy @ H:mm:ss AM", $epoch, $tz);
Anyway...
The issue I noticed was that, after transferring all the code to the other server, that if I posted a blog entry with the current time, it would actually start showing up with a time that was 3 hours in the past.
I found out that the problem was that my dev server had a Pacific time zone, and my production server was Eastern time. So, when the code did Time::Local::timelocal to turn my user-supplied time into unix time, it did so in the Eastern time zone, so that the resulting unix time is what `time()` would've been, on the east coast, when the date/time is what I gave it via the web front-end.
When I changed the server's time zone to Pacific, it worked; what also worked is getting it to show the correct time in different time zones. If I change the time zone back to Eastern after this point, it still shows the correct time. So it appears that all my code dealing with time zones is working fine, and the only weak link is turning the user-supplied time into unix time, and it seems like this is highly timezone-dependent.
So the question is: is there a way to make Time::Local give local time for a specific time zone? The idea is that if I can get the server to calculate unix time using the same time zone that the end user is probably using, that it would work correctly (i.e. so if server time is Eastern, and the end user is on Pacific, the time that the end user submits with the blog entry will be calculated into unix time in the Pacific time zone, instead of in Eastern).
Also if anyone sees any flaws in any of my other time-related code, feel free to point it out.
Cuvou.com | My personal homepage
Code:
perl -e '$|=$i=1;print" oo\n<|>\n_|_";x:sleep$|;print"\b",$i++%2?"/":"_";goto x;'