public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
From: roman.vasicek@email.cz
To: cygwin@cygwin.com
Subject: Timezone manipulation within Perl script
Date: Fri, 14 Dec 2007 21:26:00 -0000	[thread overview]
Message-ID: <9761.12995-16991-2031106093-1197667559@email.cz> (raw)

[-- Attachment #1: Type: text/plain, Size: 1363 bytes --]

Hi all,
I want to ask you how convert time between different timezones in perl script running under cygwin. I have an application which store datetime information in Zulu/GMT. I need to provide date in user timezone. How to do the correct conversion? I want to be able to offer Timezone info like 'Europe/Prague'. Following code snippet will provide correct output when running under Active state Perl (time will differ 1 or 2 hours depending on input date), but when running under cygwin perl no conversion will be done. Can anyone help me?

        $ENV{TZ}    = 'Zulu';
        POSIX::tzset();
        $time       = timegm($second, $minute, $hour, $day, $month, $year);

        $ENV{TZ}    = 'Europe/Prague';
        POSIX::tzset();
        ($second, $minute, $hour, $day, $month, $year)   = POSIX::localtime($time);

Attached program will produce under ActiveState PERL

 Winter (delta should be +1 h)
 ZULU : 2007-12-13 11:47:02 Zulu
 LOCAL: 2007-12-13 12:47:02 Europe/Prague

 Summer (delta should be +2 h)
 ZULU : 2007-06-13 11:47:02 Zulu
 LOCAL: 2007-06-13 13:47:02 Europe/Prague

and under CygWin PERL output will be

 Winter (delta should be +1 h)
 ZULU : 2007-12-13 11:47:02 Zulu
 LOCAL: 2007-12-13 11:47:02 Europe/Prague

 Summer (delta should be +2 h)
 ZULU : 2007-06-13 11:47:02 Zulu
 LOCAL: 2007-06-13 11:47:02 Europe/Prague


Best Regards,
Roman

[-- Attachment #2: test-1.pl --]
[-- Type: application/x-perl, Size: 3109 bytes --]

#!/usr/bin/perl -w
#

use strict;
use POSIX   qw();
use Time::Local;

my $zulu;
my $local;
my $zone;

sub format_datetime {
    my $datetime    = shift;            # YYYYMMDDhh:mm:ss - Date::Manip compatible format
    my $timezone    = shift || 'GMT';   # expect GMT by default
    my $html_req    = shift || 0;       # output for HTML page? ' ' => '&nbsp;'
    my $result      = '';

    if ($datetime =~ /^(\d{4})(\d{2})(\d{2})(\d{2}):(\d{2}):(\d{2})$/) {
        my $year    = $1;
        my $month   = $2;
        my $day     = $3;
        my $hour    = $4;
        my $minute  = $5;
        my $second  = $6;

        $result = sprintf("%d-%02d-%02d %02d:%02d:%02d %s", $1, $2, $3, $4, $5, $6, $timezone);
        $result =~ s/ /&nbsp;/g if ($html_req);
    }

    return $result;
}

sub is_zulu {
    my $zulu    = shift;
    my $result  = 0;

    if ($zulu =~ /^(\d{14})Z$/) {
        $result = 1
    }

    return $result;
}

sub zulu_to_datetime {
    my $zulu    = shift;
    my $result  = '';

    if (is_zulu($zulu)) {
        $result = join(':', $zulu =~ /^(\d{10})(\d{2})(\d{2})/);
    }

    return $result;
}

sub zulu_to_local_datetime {
    my $zulu        = shift;
    my $time_zone   = shift || 'Europe/Prague';
    my $result      = '';
    my $time;
    my $year;
    my $month;
    my $day;
    my $hour;
    my $minute;
    my $second;

    if (is_zulu($zulu)) {
        ($year, $month, $day, $hour, $minute, $second)  = $zulu =~ /^(\d+)(\d{2})(\d{2})(\d{2})(\d{2})(\d{2})/;

        # fix offset
        $month--;
        $year   -= 1900;

        my $already = 0;
        my $original_time_zone;

        # save environment settings
        if (exists $ENV{TZ}) {
            $already            = 1;
            $original_time_zone = $ENV{TZ};
        }

        # do datetime conversion dependint to target timezone
        $ENV{TZ}    = 'Zulu';
        POSIX::tzset();
        $time       = timegm($second, $minute, $hour, $day, $month, $year);
        $ENV{TZ}    = $time_zone;
        POSIX::tzset();
        ($second, $minute, $hour, $day, $month, $year)   = POSIX::localtime($time);

        # fix offset
        $month++;
        $year   += 1900;

        # output formating
        $result = sprintf "%d%02d%02d%02d:%02d:%02d", $year, $month, $day, $hour, $minute, $second;

        # revert environment settings back
        if ($already) {
            $ENV{TZ}    = $original_time_zone;
        } else {
            delete $ENV{TZ};
        }
        POSIX::tzset();
    }

    return $result;
}


$zulu   = '20071213114702Z';
$local  = zulu_to_local_datetime($zulu);
$zone   = 'Europe/Prague';

# should be +1 hour
print "\n", "Winter (delta should be +1 h)", "\n";
print "ZULU : ", format_datetime(zulu_to_datetime($zulu), 'Zulu'), "\n";
print "LOCAL: ", format_datetime($local, $zone), "\n";

$zulu = '20070613114702Z';
$local = zulu_to_local_datetime($zulu, $zone);

# should be +2 hour
print "\n", "Summer (delta should be +2 h)", "\n";
print "ZULU : ", format_datetime(zulu_to_datetime($zulu), 'Zulu'), "\n";
print "LOCAL: ", format_datetime($local, $zone), "\n";


[-- Attachment #3: Type: text/plain, Size: 218 bytes --]

--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/

             reply	other threads:[~2007-12-14 21:26 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-12-14 21:26 roman.vasicek [this message]
2007-12-15  0:57 ` Reini Urban
2007-12-15  1:05 ` Brian Dessent
2007-12-15  8:51   ` roman.vasicek

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=9761.12995-16991-2031106093-1197667559@email.cz \
    --to=roman.vasicek@email.cz \
    --cc=cygwin@cygwin.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).