atoomic / perl-TimeDate

time & date parsing and formatting perl library
http://search.cpan.org/dist/TimeDate/
1 stars 4 forks source link

Incorrect Time-Zone for Standard Time During Cross Over (Fall Back) [rt.cpan.org #80649] #10

Open atoomic opened 4 years ago

atoomic commented 4 years ago

Migrated from rt.cpan.org#80649 (status was 'new')

Requestors:

From gofish@evilbill.org on 2012-11-05 21:30:19 :

When converting a time-stamp into a date-time string with a time zone
(either %Z or %z), it does not get the time-zone correct for what looks
like the hour after the fall-back when hour gets repeated. This is
compounded by str2time not returning the same time-stamp even using the
incorrect time-zone.

My system time is set to America/Los_Angeles and no TZ variable is set.

Here is demonstration of it failing:

#!/usr/bin/perl
use strict;
use Date::Format;
use Date::Parse;
foreach my $ts ( 1352019262, 1352021105, 1352024705 ){
    my $dt = time2str( "%Y-%m-%d %X %Z", $ts );
    my $ts_new = str2time( $dt );
    printf "%d -> %s -> %d (%s)\n", $ts, $dt, $ts_new, ( $ts == $ts_new
? "OK" : "ERROR" );
}

Which produces:

1352019262 -> 2012-11-04 01:54:22 PDT -> 1352019262 (OK)
1352021105 -> 2012-11-04 01:25:05 MST -> 1352017505 (ERROR)
1352024705 -> 2012-11-04 02:25:05 PST -> 1352024705 (OK)

This is happening with DateTime v. 1.20 in Fedora 16 and a much older
version on CentOS 5.8.

A C program works fine:

#include <time.h>
#include <stdio.h>
#include <stdlib.h>

int
main(int argc, char *argv[])
{
  char outstr[200];
  char format[] = "%Y-%m-%d %X %Z";
  time_t t;
  struct tm *tmp;

  t = (time_t)atoi(argv[1]);
  tmp = localtime(&t);
  if (tmp == NULL) {
    perror("localtime");
    exit(EXIT_FAILURE);
  }

  if (strftime(outstr, sizeof(outstr), format, tmp) == 0) {
    fprintf(stderr, "strftime returned 0");
    exit(EXIT_FAILURE);
  }

  printf("%d is \"%s\"\n", t, outstr);
  exit(EXIT_SUCCESS);
} /* main */

gcc ./time-test.c -o time-test
./time-test 1352019262

1352019262 is "2012-11-04 01:54:22 PDT"
1352021105 is "2012-11-04 01:25:05 PST"
1352024705 is "2012-11-04 02:25:05 PST"