Hi,

I'm writing a Perl application for an embedded system, so I can't use
DateTime and DateTime::TimeZone modules.
I'm using only the system local timezone and it may have daylight saving
changes.

I need a function that will return an epoch time given a floating date+time
(year, month, day, hour, minute, second) and an absolute epoch time.
Unfortunately Time::Local doesn't seem to have this feature.

Any suggestion on other modules, or on how to implement this?

Here is below a broken implementation and a test suite with TODOs:

use strict;
use warnings;
use Test::More;

use Time::Local;

sub timelocal_after
{
my ($sec, $min, $hour, $mday, $mon, $year, $after) = @_;
 my $time = timelocal($sec, $min, $hour, $mday, $mon, $year);
  # FIXME handle ambiguous times correctly
 return ($time >= $after) ? $time : undef
}



# Dates from 2012-10-28T02:00:00 to (non included) 2012-10-28T03:00:00
# are ambiguous
$ENV{TZ} = 'Europe/Paris';

# 2012-10-28T01:59:59 => 2012-10-27T23:59:59Z
is(timelocal_after(59, 59, 1, 28, 9, 112, 1), 1351382399);
is(timelocal_after(59, 59, 1, 28, 9, 112, 1351382399), 1351382399);
is(timelocal_after(59, 59, 1, 28, 9, 112, 1351382399+1), undef);

# Resolved to the earlier time
# 2012-10-28T02:00:00 => 2012-10-28T00:00:00Z
is(timelocal_after(0, 0, 2, 28, 9, 112, 1), 1351382400);
is(timelocal_after(0, 0, 2, 28, 9, 112, 1351382400), 1351382400);
# Resolved to the later
# 2012-10-28T02:00:00 => 2012-10-28T01:00:00Z
{
local $TODO = "Fix timelocal_after";
is(timelocal_after(0, 0, 2, 28, 9, 112, 1351382400+1), 1351382400+3600);
is(timelocal_after(0, 0, 2, 28, 9, 112, 1351382400+3600), 1351382400+3600);
# Past
is(timelocal_after(0, 0, 2, 28, 9, 112, 1351382400+3601), undef);
}

# 2012-10-28T02:59:59 => 2012-10-28T00:59:59Z
is(timelocal_after(59, 59, 2, 28, 9, 112, 1), 1351385999);
is(timelocal_after(59, 59, 2, 28, 9, 112, 1351382400), 1351385999);
is(timelocal_after(59, 59, 2, 28, 9, 112, 1351385999), 1351385999);
# 2012-10-28T02:59:59 => 2012-10-28T01:59:59Z
{
local $TODO = "Fix timelocal_after";
is(timelocal_after(59, 59, 2, 28, 9, 112, 1351385999+1), 1351385999+3600);
is(timelocal_after(59, 59, 2, 28, 9, 112, 1351385999+3600),
1351385999+3600);
}
is(timelocal_after(59, 59, 2, 28, 9, 112, 1351385999+3601), undef);


# Offset changed to UTC+0100
# 2012-10-28T03:00:00 => 2012-10-28T02:00:00Z
is(timelocal_after(0, 0, 3, 28, 9, 112, 1), 1351385999+3601);

done_testing;

Reply via email to