public inbox for cygwin@cygwin.com
 help / color / mirror / Atom feed
* Timezone manipulation within Perl script
@ 2007-12-14 21:26 roman.vasicek
  2007-12-15  0:57 ` Reini Urban
  2007-12-15  1:05 ` Brian Dessent
  0 siblings, 2 replies; 4+ messages in thread
From: roman.vasicek @ 2007-12-14 21:26 UTC (permalink / raw)
  To: cygwin

[-- 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? ' ' => ' '
    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/ / /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/

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2007-12-15  8:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-12-14 21:26 Timezone manipulation within Perl script roman.vasicek
2007-12-15  0:57 ` Reini Urban
2007-12-15  1:05 ` Brian Dessent
2007-12-15  8:51   ` roman.vasicek

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).