Re: User's time
by thospel (Hermit) on Oct 16, 2004 at 07:36 UTC
|
Doing a fixed offset and then using localtime is a bad idea since it doesn't account for differences in daylight saving.
Even if both source and target area do daylight saving, they likely will not have them over the same periods of time.
The proper solution is to run localtime for a different timezone. At least on unices this can normally be done by setting the TZ environment variable. You can do that before even calling
the program or at the very beginning of the program (probably even inside a BEGIN) if you want everything reported in Singapore time,
or locally if you only want specific calls in Singapore time:
{
local $ENV{TZ} = "Singapore";
print scalar localtime;
}
I could use "Singapore" as timezone name directly here since
I have an entry named like that in my timezone database. That won't work on all operating systems though. Since Singapore doesn't do daylight saving, this one is probably more portable:
{
# Strangely enough I must use GMT-8 on my linux, even
# though the official timezone name is GMT+8 (or UTC+8)
local $ENV{TZ} = "GMT-8";
print scalar localtime;
}
For other places you'd use their official timezone name that does have daylight saving, e.g. "CET" for central Europe.
And in case you are on a system that doesn't react to TZ,
you can (ab)use the fact that Singapore does no daylight saving by indeed working with an offset, but relative to gmtime:
print scalar gmtime(8*3600+time);
Though that wouldn't of course generalize to places that do have daylight saving, or if Singapore ever introduces it. | [reply] [d/l] [select] |
|
|
local $ENV{TZ} = "GMT-8";
| [reply] [d/l] |
Re: User's time
by kvale (Monsignor) on Oct 16, 2004 at 03:55 UTC
|
You would find the time difference $offset in hours,
then
$time += $offset * 3600;
my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(t
+ime);
| [reply] [d/l] [select] |
|
|
| [reply] |
|
|
$offset_sec = $timezone_hr_offset *3600; # offset may be negative
@time_vals = localtime( time + $offset_sec );
| [reply] [d/l] |
|
|
Re: User's time
by Your Mother (Archbishop) on Oct 16, 2004 at 04:28 UTC
|
This is probably a case for JavaScript, la. Feed it the UTC/GMT of whatever timestamp you want and use their computers' time to adjust it (or <noscript>present the UTC version</noscript> so it works for everyone regardless of JS). The best way around that is to do what PM does which is to let users set their TZ and store it with or parallel to their account info. Webusers can be from every timezone unless your site is an intranet or Singapore only setup or some such.
update: short demo of JS/perl solution, Perl + JavaScript to display "correct" local times for datetimes. Also linked below.
| [reply] [d/l] |
|
|
Unless the time is largely used to determine the content, I would agree that you better get the date/time from the user's box. JavaScript is one way. To hardcode user date in the content makes the solution less portable. What if the user is traveling?
The following script displays date in dd/mm/yy format, you can easily change it to different formats:
<script language="JavaScript">
var date = new Date();
var d = date.getDate();
var day = (d < 10) ? '0' + d : d;
var m = date.getMonth() + 1;
var month = (m < 10) ? '0' + m : m;
var yy = date.getYear();
var year = (yy < 1000) ? yy + 1900 : yy;
document.write(day + "/" + month + "/" + year);
</script>
| [reply] [d/l] |
|
|
Thanks, I got it to work with the solution by kvale and graff :)
| [reply] |
Re: User's time
by Cody Pendant (Prior) on Oct 16, 2004 at 05:12 UTC
|
I don't know if Singapore has daylight-saving time, I believe not, but what should kiat do, if anything, about the fact that "local time" even for the US server changes twice a year? Will the $hour value change, or only the $idst flag?
($_='kkvvttuubbooppuuiiffssqqffssmmiibbddllffss')
=~y~b-v~a-z~s; print
| [reply] |
Re: User's time
by steves (Curate) on Oct 16, 2004 at 12:26 UTC
|
I've never tested it but I thought you could pretty much
count on clients sending an HTTP
Date header with PUT and POST messages.
If so, that would eliminate the need for JavaScript.
| [reply] |
|
|
That is a good observation and probably a great way to auto-set a user's TZ setting but it only fixes half the "problem" some of the time. On a regular website (where you're not voting via POST constantly like here, most BB sites seem to take votes via GET) then you only get the post on login which happens maybe 1x daily or 1x 2 years.
Next is visitors who don't ever register. They never POST so the TZ will always be undetermined by the server but it will almost certainly be known by the client's machine; hence the need for client side something like JavaScript.
I'm not saying there's a wrong or right way to solve this, just trying to demonstrate what different users will see. Singapore users might get the right time, and whatever slice of Indonesia, etc is in the same TZ, but the other 23 TZs in the world will see datetimes out of sync with their own time. You just have to decide if this is important or not in your situation.
This is one I've considered for a site I'm working on and I will sheepishly admit that while I favor a client-side JS solution converting server side UTCs, I have yet to do the legwork to share the function() to do it. Maybe I've embarrassed myself into doing it today. :)
update: fixed bad paren, missing word, apostrophe.
update 2: well, I gave it a shot: Perl + JavaScript to display "correct" local times for datetimes. I'll give it a couple weeks of thought before I start using it in live stuff but I think I like it. Thanks for unintentionally prodding me to finally work on it.
| [reply] |
|
|
This is a very good point. I used this site to see
what the two browsers I have installed send back (Netscape
7.2 and IE 6.0, both on Win2K). Neither sends a Date
header for a GET. In addition, my O'Reilly HTTP:
The Definitive Gude says that sent dates may not contain
time zones and may not be GMT. So I'd have to vote for a JS
method. The only other intriguing idea, just for the pure
geekiness of it, is to take the IP address from the HTTP
header and do a look up at one of these
IP geographic location sites.
| [reply] |
|
|
Seems like a good solution, thanks steves!
| [reply] |