Is there a way to determine whether a given date in an arbitrary time zone occurs during daylight savings time (e.g., when you have something like the number of epoch seconds given by a client's time() call such as 1022704935, or perhaps just a date string such as '2002-05-29 08:00:00', and the client is in MST7MDT) other than a convoluted procedure involving localtime()[8]?

I have searched the CPAN, but to no avail. And using localtime has provided me with nothing but frustration, since (so far as I can tell) the only way to determine whether it is daylight savings time in a particular time zone is:

  1. Convert the date to epoch seconds
  2. Set $ENV{TZ} to the timezone in question.
  3. Add or subtract the number of seconds from the epoch seconds depending on the offset from the local timezone setting. Determining the offset involves knowing whether it is daylight savings time or not, so we have a bit of a chicken-and-egg problem here several times a year ...
  4. Get $isdst = localtime($epoch_seconds)[8]
  5. Reset $ENV{TZ} to its original value so it doesn't muck up any other date calculations elsewhere in the code

The reason for dealing with the offset is that localtime() likes to adjust the return value according to the offset between the machine's time zone and that given by $ENV{TZ}:

#!/usr/bin/perl use strict; my $time = time(); print "Localtime is [".localtime($time)."[ when \$ENV{TZ} is [$ENV{TZ} +] based on time [$time]\n"; $ENV{TZ} = 'GMT'; print "Localtime is now [".localtime($time)."] when \$ENV{TZ} is [$ENV +{TZ}[ based on time [$time]\n";
yields
Localtime is [Wed May 29 14:42:15 2002] when $ENV{TZ} is [] based on t +ime [1022704935] Localtime is now [Wed May 29 20:42:15 2002] when $ENV{TZ} is [GMT] bas +ed on time [1022704935]
Even Date::Manip likes to implicitly convert epoch seconds. For example,
#!/usr/bin/perl use strict; use Date::Manip; print &UnixDate(&ParseDate("epoch ".time()),"%Y-%m-%d %H:%M:%S")."\n";
gives
[starky@freak bin]$ unset TZ [starky@freak bin]$ ./dm-test.pl 2002-05-29 15:11:01 [starky@freak bin]$ export TZ=GMT [starky@freak bin]$ ./dm-test.pl 2002-05-29 21:11:15

It just seems to be an overly convoluted process. I'm convinced there's an easier way but cannot seem to find it. I feel like I'm just being daft here or there's something about time zones I'm simply not clued in to ...

Edit by tye to change PRE tags to CODE tags


In reply to Determining Daylight Savings Time by Starky

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.