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? ' ' => ' '
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/
next 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).