time zone offset calc with localtime and gmtime

Discussion in 'Perl Misc' started by Leendert Bottelberghs, Apr 4, 2005.

  1. Hi there,

    I want to calculate the time zone offset (as an integer), and I don't want
    to depend on other modules.
    I want to verify if the following code is correct:

    <code>
    my @lctime = localtime();
    my @gmtime = gmtime();
    # index 2 represent the hours
    # index 8 represent isdst (daylight saving time boolean (0/1))

    $tzoffset = (($lctime[2] - $lctime[8])-($gmtime[2] - $gmtime[8]))%24);

    </code>

    I figured that if DST is applied locally, the clock is one hour ahead of
    "normal" GMT (which hasn't DST applied), so this hour has to be deducted
    from the time difference. If the GMT has DST set on, this hour has to be
    added to the time difference, hence the double deduction.

    Can anyone tell me if my my assumptions are correct?

    TIA,

    -leendert bottelberghs
     
    Leendert Bottelberghs, Apr 4, 2005
    #1
    1. Advertising

  2. Leendert Bottelberghs wrote:
    > I want to calculate the time zone offset (as an integer), and I don't want
    > to depend on other modules.


    Why not?

    > I figured that if DST is applied locally, the clock is one hour ahead of
    > "normal"


    That may be true in many countries, but can you rely on it?

    > If the GMT has DST set on,


    AFAIK, that's never happening.

    --
    Gunnar Hjalmarsson
    Email: http://www.gunnar.cc/cgi-bin/contact.pl
     
    Gunnar Hjalmarsson, Apr 4, 2005
    #2
    1. Advertising

  3. On Mon, 04 Apr 2005 17:34:31 +0200, Gunnar Hjalmarsson wrote:
    >> I want to calculate the time zone offset (as an integer), and I don't
    >> want to depend on other modules.

    >
    > Why not?


    For different reasons:
    - I use this in a module that will be used in mod_perl. I want to keep the
    number of loaded modules as concise as possible, because of the server
    memory overhead; - I want to be able to distribute this module without
    people having to install other modules;


    >> I figured that if DST is applied locally, the clock is one hour ahead
    >> of "normal"

    >
    > That may be true in many countries, but can you rely on it?


    I truly don't know. That's part of the reason I posted this ;) Anyone...?

    >> If the GMT has DST set on,

    >
    > AFAIK, that's never happening.


    I thought so. Thanx for your response,

    -leendert bottelberghs
     
    Leendert Bottelberghs, Apr 4, 2005
    #3
  4. Leendert Bottelberghs

    Geoff Guest

    On Mon, 04 Apr 2005 17:07:04 +0200, "Leendert Bottelberghs"
    <> wrote:

    >Hi there,
    >
    >I want to calculate the time zone offset (as an integer), and I don't want
    >to depend on other modules.
    >I want to verify if the following code is correct:
    >
    ><code>
    >my @lctime = localtime();
    >my @gmtime = gmtime();
    ># index 2 represent the hours
    ># index 8 represent isdst (daylight saving time boolean (0/1))
    >
    >$tzoffset = (($lctime[2] - $lctime[8])-($gmtime[2] - $gmtime[8]))%24);
    >
    ></code>
    >
    >I figured that if DST is applied locally, the clock is one hour ahead of
    >"normal" GMT (which hasn't DST applied), so this hour has to be deducted
    >from the time difference. If the GMT has DST set on, this hour has to be
    >added to the time difference, hence the double deduction.
    >
    >Can anyone tell me if my my assumptions are correct?
    >
    >TIA,
    >
    >-leendert bottelberghs
    >


    $tzoffset, if you are going to make it an integer should be in units
    of 1 second, not hours. There a places in the world where the offset
    is not a whole hour. (e.g., Newfoundland, Tehran, Kabul, Rangoon,
    Kathmandu, Darwin)
     
    Geoff, Apr 4, 2005
    #4
  5. Leendert Bottelberghs

    Mothra Guest

    "Leendert Bottelberghs" <> wrote in
    message news:p...
    > I truly don't know. That's part of the reason I posted this ;) Anyone...?


    You may want to bring this up on the DateTime mailing list
    .

    Mothra
     
    Mothra, Apr 4, 2005
    #5
  6. Leendert Bottelberghs

    Joe Smith Guest

    Leendert Bottelberghs wrote:

    > - I use this in a module that will be used in mod_perl. I want to keep the
    > number of loaded modules as concise as possible, because of the server
    > memory overhead; - I want to be able to distribute this module without
    > people having to install other modules;


    Well, is it safe to use the modules that come bundled with perl, so
    you might as well use them.
    -Joe
     
    Joe Smith, Apr 5, 2005
    #6
  7. Leendert Bottelberghs

    Joe Smith Guest

    Leendert Bottelberghs wrote:

    > I want to calculate the time zone offset (as an integer)


    The international standard for time zone offset is a five-character
    string. A plus or minus sign, two digits for hours, two digits for
    minutes.

    Date: Mon, 04 Apr 2005 17:07:04 +0200
    NNTP-Posting-Date: Mon, 4 Apr 2005 15:06:45 +0000 (UTC)
    US-Pacific-Date: Mon, 04 Apr 2005 08:06:45 -0800 (PDT)

    The last two digits are not always "00".

    grep ' [-+][0-9][0-9][1-9]' /usr/lib/perl5/site_perl/5.8.3/Date/Manip.pm
    #"nst -0330 ". # Newfoundland Standard nst=North Sumatra +0630
    "nft -0330 ". # Newfoundland
    "ndt -0230 ". # Newfoundland Daylight
    "it +0330 ". # Iran
    "ist +0530 ". # Indian Standard
    "nst +0630 ". # North Sumatra nst=Newfoundland Std -0330
    "acst +0930 ". # Australian Central Standard
    "cast +0930 ". # Central Australian Standard
    "acdt +1030 ". # Australian Central Daylight
    "cadt +1030 ". # Central Australian Daylight

    -Joe
     
    Joe Smith, Apr 5, 2005
    #7
  8. On Tue, 05 Apr 2005 00:35:32 -0700, Joe Smith wrote:
    > Leendert Bottelberghs wrote:
    >
    >> - I use this in a module that will be used in mod_perl. I want to keep the
    >> number of loaded modules as concise as possible, because of the server
    >> memory overhead; - I want to be able to distribute this module without
    >> people having to install other modules;

    >
    > Well, is it safe to use the modules that come bundled with perl, so
    > you might as well use them.


    You're absolutely right. Which standard module would you recommend?

    -leendert
     
    Leendert Bottelberghs, Apr 5, 2005
    #8
  9. On Tue, 05 Apr 2005 00:46:45 -0700, Joe Smith wrote:
    > Leendert Bottelberghs wrote:
    >> I want to calculate the time zone offset (as an integer)

    > The international standard for time zone offset is a five-character
    > string. A plus or minus sign, two digits for hours, two digits for
    > minutes.


    Youre right. So I have to use POSIX to be able to calculate the difference
    in seconds. I now have the following to calculate and format the time
    offset:

    <code>
    # calculate the time difference in seconds;
    my $secoffset = timelocal(localtime()) - timelocal(gmtime());

    # translate it to minutes and apply the DLT difference
    my $minoffset = ($secoffset / 60) + ((gmtime)[8] - (localtime)[8])*60;

    # translate it to "hour-format", so that 90 will be 130,
    # and -90 will be -130
    my $tzoffset = int($minoffset/60)*100 +
    ($minoffset/abs($minoffset))*($minoffset%60);

    # apply final formatting, including +/- sign and 4 digits.
    my $tzstr = sprintf "%+05d", $tzoffset;

    </code>

    Maybe I'll use Date::Manip after all.

    -leendert bottelberhs
     
    Leendert Bottelberghs, Apr 5, 2005
    #9
  10. Leendert Bottelberghs

    Mothra Guest

    "Leendert Bottelberghs" <> wrote in
    message news:p...

    > Maybe I'll use Date::Manip after all.
    >
    > -leendert bottelberhs


    Yor are reinventing what we already have done in the DateTime Project

    use strict;
    use warnings;
    use diagnostics;
    use DateTime;


    my $dt = DateTime->now(time_zone => 'America/Chicago');

    print $dt->offset();


    printed results
    me.pl
    -18000

    Hope this helps
     
    Mothra, Apr 5, 2005
    #10
  11. On Tue, 05 Apr 2005 06:20:15 -0700, Mothra wrote:
    >
    > Yor are reinventing what we already have done in the DateTime Project


    I know, and I'm not entirely happy with it. But there are good reasons for
    it. First of all, I couldn't get the DateTime module installed with CPAN.
    Besides the fact that it depends on about a douzen other modules (and it
    installs about 60), it just wouldn't compile (running RH8, perl 5.8.0). It
    returned:

    <snippet>
    /usr/bin/make -- NOT OK
    Running make test
    Can't test without successful make
    Running make install
    make had returned bad status, install seems impossible
    </snippet>

    The second reason I already mentioned: it depends on loads of other
    modules. Since the module I'm writing is part of a larger project, I don't
    want to force other people (on varying OSs) to install this large amount
    of third-party modules.

    > use strict;
    > use warnings;
    > use diagnostics;
    > use DateTime;
    >
    >
    > my $dt = DateTime->now(time_zone => 'America/Chicago');
    >
    > print $dt->offset();


    Do you have to specify the timezone manually? And can the offset be
    formatted in the "standard" timezone-offset way automatically with this
    module?

    Thanx for you time and response,

    -leendert bottelberghs
     
    Leendert Bottelberghs, Apr 5, 2005
    #11
  12. Leendert Bottelberghs

    Mothra Guest

    "Leendert Bottelberghs" <> wrote in
    message news:p...
    > On Tue, 05 Apr 2005 06:20:15 -0700, Mothra wrote:
    > >
    > > Yor are reinventing what we already have done in the DateTime Project

    >
    > I know, and I'm not entirely happy with it. But there are good reasons for
    > it. First of all, I couldn't get the DateTime module installed with CPAN.
    > Besides the fact that it depends on about a dozen other modules (and it
    > installs about 60), it just wouldn't compile (running RH8, perl 5.8.0). It
    > returned:


    Please report your failures to the DateTime Mailing list
    if you are having problems installing DateTime
    we need to know about it.

    >
    > The second reason I already mentioned: it depends on loads of other
    > modules. Since the module I'm writing is part of a larger project, I don't
    > want to force other people (on varying OSs) to install this large amount
    > of third-party modules.


    You would be better off installing DateTime that reinventing the wheel. As
    far
    as I know it is the only suite of modules that incorporate the Olson
    Timezone
    Database. Timezone conversion is fully supported (along with offsets)

    >
    > > use strict;
    > > use warnings;
    > > use diagnostics;
    > > use DateTime;
    > >
    > >
    > > my $dt = DateTime->now(time_zone => 'America/Chicago');
    > >
    > > print $dt->offset();

    >
    > Do you have to specify the timezone manually? And can the offset be
    > formatted in the "standard" timezone-offset way automatically with this
    > module?


    Yes, you can use the naming convention provided with datetime or
    you can specify an offset. I ran into a similar issue when writting the
    tests
    for the Sunrise module. I could not use the standard naming provided with
    DateTime I had to use the offset, something like this

    use strict;
    use warnings;
    use diagnostics;
    use DateTime;
    use DateTime::TimeZone;
    use POSIX qw(floor ceil);

    use vars qw($long $lat $offset $dt);

    $dt = DateTime->now;

    while (<DATA>) {
    /(\w+),\s+(\w+)\s+(\d+)\s+(\d+)\s+(\w)\s+(\d+)\s+(\d+)\s+(\w)\s+sunrise:\s+(
    \d+:\d+)\s+sunset:\s+(\d+:\d+)/;

    $lat = sprintf( "%.3f", ( $3 + ( $4 / 60 ) ) );
    $long = sprintf( "%.3f", -( $6 + ( $7 / 60 ) ) );
    if ( $long < 0 ) {
    $offset =
    DateTime::TimeZone::eek:ffset_as_string( ceil( ( $long / 15 ) ) * 60
    *
    60 );
    }
    elsif ( $long > 0 ) {
    $offset =
    DateTime::TimeZone::eek:ffset_as_string( floor( ( $long / 15 ) ) * 60
    *
    60 );
    }

    }

    $dt->set_time_zone($offset);

    print $dt->offset;
    __DATA__
    Darwin, Australia 12 28 S 130 51 E sunrise: 05:36 sunset: 17:00

    I hope this helps
     
    Mothra, Apr 5, 2005
    #12
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Stephen
    Replies:
    1
    Views:
    1,228
    Purl Gurl
    May 19, 2004
  2. KW
    Replies:
    1
    Views:
    1,852
    Eric Sosman
    Dec 8, 2004
  3. Replies:
    0
    Views:
    606
  4. Replies:
    4
    Views:
    544
    Trevor Squires
    Feb 1, 2006
  5. Kaye Ng

    ruby calc.rb or just calc.rb

    Kaye Ng, Jul 26, 2010, in forum: Ruby
    Replies:
    7
    Views:
    419
    Kaye Ng
    Jul 28, 2010
Loading...

Share This Page