This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Perl mktime/gmtime peculiarities (Inc. Testcase)


Hi All,

I'm writing an application in Perl that processes a logfile with timestamps
with differing timezones - One in UTC, and one in BST. For the uninitiated,
BST, or British Summer Time is UTC, with Daylight savings time running from
1am on the last Sunday of March until 1am UTC/2am BST on the Last Sunday in
October; So in 2008 this means BST runs from 01:00:00 AM 30th March through
to 01:00:00 AM 26th October.

Test Program:
#!/usr/bin/perl

use POSIX;
use Time::Local; 

print "Timezone: " . $ENV{TZ} . "\n\n";
&dateTimeToTimestamp("2008-03-30T00:59:59");
&dateTimeToTimestamp("2008-03-30T01:00:00");
&dateTimeToTimestamp("2008-03-30T01:00:01");
&dateTimeToTimestamp("2008-03-30T02:00:00");
&dateTimeToTimestamp("2008-10-26T00:59:59");
&dateTimeToTimestamp("2008-10-26T01:00:00");
&dateTimeToTimestamp("2008-10-26T01:00:01");
&dateTimeToTimestamp("2008-10-26T01:00:02");
&dateTimeToTimestamp("2008-10-26T01:30:00");
&dateTimeToTimestamp("2008-10-26T01:30:01");
&dateTimeToTimestamp("2008-10-26T01:30:01");
&dateTimeToTimestamp("2008-10-26T01:45:00");
&dateTimeToTimestamp("2008-10-26T01:50:00");
&dateTimeToTimestamp("2008-10-26T01:55:00");
&dateTimeToTimestamp("2008-10-26T01:55:59");
&dateTimeToTimestamp("2008-10-26T01:56:00");
&dateTimeToTimestamp("2008-10-26T01:57:00");
&dateTimeToTimestamp("2008-10-26T01:58:00");
&dateTimeToTimestamp("2008-10-26T01:59:58");
&dateTimeToTimestamp("2008-10-26T01:59:59");
&dateTimeToTimestamp("2008-10-26T02:00:00");
&dateTimeToTimestamp("2008-10-26T02:00:01");
&dateTimeToTimestamp("2008-10-26T02:59:59");
&dateTimeToTimestamp("2008-10-26T03:00:00");
&dateTimeToTimestamp("2008-10-26T03:00:01");

sub dateTimeToTimestamp {
	print $_[0] . "       ";
	$_[0] =~ /(\d{4})-(\d{2})-(\d{2})([ |T])(\d{2}):(\d{2}):(\d{2})/;
	my($year, $mon, $day, $GMT, $hour, $min, $sec) = ($1, $2, $3, $4, $5, $6,
$7);
	print "UTC\t" . timegm($sec, $min, $hour, $day, $mon - 1, $year - 1900) .
"\t";
	print "BST\t" . mktime($sec, $min, $hour, $day, $mon - 1, $year - 1900, 0,
0) . "\n";
}

For which I get the output:

2008-03-30T00:59:59       UTC   1206838799      BST     1206838799
2008-03-30T01:00:00       UTC   1206838800      BST
2008-03-30T01:00:01       UTC   1206838801      BST
2008-03-30T02:00:00       UTC   1206842400      BST     1206838800

------------------------------------------------ << Added for clarity

2008-10-26T00:59:59       UTC   1224982799      BST     1224979199
2008-10-26T01:00:00       UTC   1224982800      BST     1224979200
2008-10-26T01:00:01       UTC   1224982801      BST     1224979201
2008-10-26T01:00:02       UTC   1224982802      BST     1224979202
2008-10-26T01:30:00       UTC   1224984600      BST     1224981000
2008-10-26T01:30:01       UTC   1224984601      BST     1224981001
2008-10-26T01:30:01       UTC   1224984601      BST     1224981001
2008-10-26T01:45:00       UTC   1224985500      BST     1224981900
2008-10-26T01:50:00       UTC   1224985800      BST     1224982200
2008-10-26T01:55:00       UTC   1224986100      BST     1224982500
2008-10-26T01:55:59       UTC   1224986159      BST     1224982559
2008-10-26T01:56:00       UTC   1224986160      BST     1224986160 <<< BST
Ends at 01:56:00??
2008-10-26T01:57:00       UTC   1224986220      BST     1224986220
2008-10-26T01:58:00       UTC   1224986280      BST     1224986280
2008-10-26T01:59:58       UTC   1224986398      BST     1224986398
2008-10-26T01:59:59       UTC   1224986399      BST     1224986399
2008-10-26T02:00:00       UTC   1224986400      BST     1224986400
2008-10-26T02:00:01       UTC   1224986401      BST     1224986401
2008-10-26T02:59:59       UTC   1224989999      BST     1224989999
2008-10-26T03:00:00       UTC   1224990000      BST     1224990000
2008-10-26T03:00:01       UTC   1224990001      BST     1224990001

So we can see that on the 30th of March, 1AM fails to exist in BST, as it
gets shifted forwards an hour - All is good.

My confusion is what happens on the 26th of October, as the time seems to go
back at 01:56:00am instead of 02:00:00am. I can see the output change as I
change timezones in Windows, but am confused as to where this 4 minute
disparity comes from.

Any assistance gratefully received - It's driving me mad!

Kind Regards,

Neil Saunders.

-- 
View this message in context: http://www.nabble.com/Perl-mktime-gmtime-peculiarities-%28Inc.-Testcase%29-tp18811603p18811603.html
Sent from the Cygwin list mailing list archive at Nabble.com.


--
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/


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]