Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
import DateTime-Format-Epoch 0.05 from CPAN
git-cpan-module:   DateTime-Format-Epoch
git-cpan-version:  0.05
git-cpan-authorid: PIJLL
git-cpan-file:     authors/id/P/PI/PIJLL/DateTime-Format-Epoch-0.05.tar.gz
  • Loading branch information
Eugene van der Pijll authored and schwern committed Dec 10, 2009
1 parent a60b11e commit 4cc3edf
Show file tree
Hide file tree
Showing 9 changed files with 152 additions and 31 deletions.
6 changes: 6 additions & 0 deletions Changes
@@ -1,5 +1,11 @@
Revision history for Perl module DateTime::Format::Epoch

0.05 2003-07-18
- Changed API of DT::F::E::TAI64 (the format_datetime_as_string()
method is replaced by a parameter to the constructor)
- Added dhms parameter to new(), to return '2d, 4h, 15m, 45s'
values

0.04 2003-06-19
- Added start_at parameter to new()
- Added DateTime::Format::Epoch::TAI64
Expand Down
2 changes: 2 additions & 0 deletions MANIFEST
Expand Up @@ -14,10 +14,12 @@ t/004_nano.t
t/005_leap.t
t/006_local.t
t/007_parse.t
t/008_dhms.t
t/101_load.t
t/102_format.t
t/201_load.t
t/202_format.t
t/301_load.t
t/302_format.t
t/303_parse.t
Makefile.PL
37 changes: 35 additions & 2 deletions lib/DateTime/Format/Epoch.pm
Expand Up @@ -4,7 +4,7 @@ use strict;

use vars qw($VERSION);

$VERSION = 0.04;
$VERSION = 0.05;

use DateTime 0.12;
use DateTime::LeapSecond;
Expand Down Expand Up @@ -40,6 +40,8 @@ sub new {
default => 0},
local_epoch => {type => BOOLEAN,
default => 0},
dhms => {type => BOOLEAN,
default => 0},
skip_leap_seconds => {type => BOOLEAN,
default => 1},
start_at => {default => 0},
Expand All @@ -52,6 +54,7 @@ sub new {
}

$p{unit} = $units_per_second{$p{unit}};
$p{unit} = 1 if $p{dhms};

($p{epoch_rd_days}, $p{epoch_rd_secs}) = $p{epoch}->utc_rd_values;
$p{epoch_class} = ref $p{epoch};
Expand Down Expand Up @@ -103,12 +106,28 @@ sub format_datetime {

$secs += $self->{start_at};

if ($self->{dhms}) {
my $mins = int($secs / 60);
$secs -= $mins * 60;
my $hours = int($mins / 60);
$mins -= $hours * 60;
my $days = int($hours / 24);
$hours -= $days * 24;

return $days, $hours, $mins, $secs;
}

return $secs;
}

sub parse_datetime {
my ($self, $str) = @_;

if ($self->{dhms}) {
my (undef, $d, $h, $m, $s) = @_;
$str = (($d * 24 + $h) * 60 + $m) + $s;
}

$str -= $self->{start_at};

my $delta_days = _floor( $str / (86_400 * $self->{unit}) );
Expand Down Expand Up @@ -199,7 +218,7 @@ epoch. It can also do the reverse.
Constructor of the formatter/parser object. It can take the following
parameters: "epoch", "unit", "type", "skip_leap_seconds", "start_at",
and "local_epoch".
"local_epoch" and "dhms".
The epoch parameter is the only required parameter. It should be a
DateTime object (or at least, it has to be convertible to a DateTime
Expand Down Expand Up @@ -227,11 +246,25 @@ true value. In this case, you should submit an epoch with a floating
timezone. The exact epoch used in C<format_datetime> will then depend on
the timezone of the object you pass to C<format_datetime>.
Most often, the time since an epoch is given in seconds. In some
circumstances however it is expressed as a number of days, hours, minutes
and seconds. This is done by NASA, for the so called Mission Elapsed
Time. For example, 2/03:45:18 MET means it has been 2 days, 3 hours, 45
minutes, and 18 seconds since liftoff. If you set the dhms parameter to
true, format_datetime returns a four element list, containing the number
of days, hours, minutes and seconds, and parse_datetime accepts the same
four element list.
=item * format_datetime($datetime)
Given a DateTime object, this method returns the number of seconds since
the epoch.
=item * parse_datetime($secs)
Given a number of seconds, this method returns the corresponding
DateTime object.
=back
=head1 SUPPORT
Expand Down
2 changes: 1 addition & 1 deletion lib/DateTime/Format/Epoch/MacOS.pm
Expand Up @@ -4,7 +4,7 @@ use strict;

use vars qw($VERSION @ISA);

$VERSION = 0.04;
$VERSION = 0.05;

use DateTime;
use DateTime::Format::Epoch;
Expand Down
84 changes: 59 additions & 25 deletions lib/DateTime/Format/Epoch/TAI64.pm
Expand Up @@ -4,14 +4,17 @@ use strict;

use vars qw($VERSION @ISA);

$VERSION = 0.04;
$VERSION = 0.05;

use DateTime;
use DateTime::Format::Epoch;

use Params::Validate qw/validate/;
use Math::BigInt;

@ISA = qw/DateTime::Format::Epoch/;

# Epoch is 1970-01-01 00:00:00 TAI, is 1969-12-31T23:59:49 or
# Epoch is 1970-01-01 00:00:00 TAI, is 1969-12-31T23:59:51 or
# 1969-12-31T23:59:50 (not clear)
my $epoch = DateTime->new( year => 1969, month => 12, day => 31,
hour => 23, minute => 59, second => 51 );
Expand All @@ -20,22 +23,46 @@ my $start = Math::BigInt->new(1) << 62;

sub new {
my $class = shift;

return $class->SUPER::new( epoch => $epoch,
unit => 'seconds',
type => 'bigint',
skip_leap_seconds => 0,
start_at => $start );
my %p = validate( @_,
{ format => { regex => qr/^string|number$/,
default => 'number' },
});

my $self = $class->SUPER::new( epoch => $epoch,
unit => 'seconds',
type => 'bigint',
skip_leap_seconds => 0,
start_at => $start );
$self->{is_string} = ($p{format} eq 'string');

return $self;
}

sub format_datetime_as_string {
sub format_datetime {
my ($self, $dt) = @_;

my $str = $self->format_datetime($dt)->as_hex;
my ($n) = $str =~ /^0x(\w+)$/ or die "Internal error";
my $n = $self->SUPER::format_datetime($dt);

if ($self->{is_string}) {
my $str = $n->as_hex;
my ($hex) = $str =~ /^0x(\w+)$/
or die "Unknown BigInt format '$str'\n";
my $retval = pack "H*", $hex;
$n = "0" x (8 - length$retval) . $retval;
}

return $n;
}

sub parse_datetime {
my ($self, $n) = @_;

my $retval = pack "H*", $n;
return "0" x (8 - length$retval) . $retval;
if ($self->{is_string}) {
my $hexstr = '0x' . unpack 'H*', $n;
$n = Math::BigInt->new($hexstr);
}

return $self->SUPER::parse_datetime($n);
}

1;
Expand All @@ -51,11 +78,20 @@ DateTime::Format::Epoch::TAI64 - Convert DateTimes to/from TAI64 values
my $formatter = DateTime::Format::Epoch::TAI64->new();
my $dt2 = $formatter->parse_datetime( ???? );
# 2003-04-28T00:00:00
my $dt = $formatter->parse_datetime( '4611686019483526367' );
# 2003-06-20T19:49:59
$formatter->format_datetime($dt);
# 4611686019483526367
my $str_frmt = DateTime::Format::Epoch::TAI64->new(
format => 'string' );
$formatter->format_datetime_as_string($dt2);
# ????
$dt = $str_frmt->parse_datetime( "\x40\0\0\0\x3e\xf3\x69\x6a" );
# 2003-06-20T19:49:59
$str_frmt->format_datetime($dt);
# "\x40\0\0\0\x3e\xf3\x69\x6a"
=head1 DESCRIPTION
Expand All @@ -67,25 +103,23 @@ expect the universe to be closed).
=head1 METHODS
Most of the methods are the same as those in L<DateTime::Format::Epoch>.
Apart from one new method, the only difference is the constructor.
The only difference is the constructor.
=over 4
=item * new()
Constructor of the formatter/parser object. It has no parameters.
=item * format_datetime_as_string( $dt )
=item * new( [format => 'string'] )
Returns the TAI64 value as an 8 byte string.
Constructor of the formatter/parser object. If the optional format
parameter is set to 'string', TAI64 values will be expected to be 8
byte strings.
=back
=head1 BUGS
Before the introduction of the leap seconds in 1972, the relation
between TAI and UTC was irregular. In this module, it is assumed that
the difference TAI-UTC was 10 seconds constantly. Any errors introduced
the difference TAI-UTC was 9 seconds constantly. Any errors introduced
by this assumption come from the irregularity of UTC, and are not
TAI64's fault or mine.
Expand Down
2 changes: 1 addition & 1 deletion lib/DateTime/Format/Epoch/Unix.pm
Expand Up @@ -4,7 +4,7 @@ use strict;

use vars qw($VERSION @ISA);

$VERSION = 0.04;
$VERSION = 0.05;

use DateTime;
use DateTime::Format::Epoch;
Expand Down
32 changes: 32 additions & 0 deletions t/008_dhms.t
@@ -0,0 +1,32 @@
use strict;
BEGIN { $^W = 1 }

use Test::More tests => 6;
use DateTime;
use DateTime::Format::Epoch;

my $dt = DateTime->new( year => 1970, month => 1, day => 1 );

my $f = DateTime::Format::Epoch->new( epoch => $dt, dhms => 1,
skip_leap_seconds => 0 );

isa_ok($f, 'DateTime::Format::Epoch' );

ok(eq_array([$f->format_datetime($dt)], [0,0,0,0]),
'Epoch = 0/0:0:0');

$dt->set( hour => 1 );
ok(eq_array([$f->format_datetime($dt)], [0,1,0,0]),
'Epoch + 1hour');

$dt->set( day => 2, hour => 0 );
ok(eq_array([$f->format_datetime($dt)], [1,0,0,0]),
'Epoch + 1 day');

$dt = DateTime->new( year => 1972, month => 1, day => 2 );
ok(eq_array([$f->format_datetime($dt)], [365*2+1,0,0,1]),
'Leap second counted');

$dt = DateTime->new( year => 1969, month => 12, day => 22, hour => 22 );
ok(eq_array([$f->format_datetime($dt)], [-9, -2, 0, 0]),
'Epoch - 9days 2hours');
4 changes: 2 additions & 2 deletions t/302_format.t
Expand Up @@ -5,13 +5,13 @@ use Test::More tests => 2;
use DateTime;
use DateTime::Format::Epoch::TAI64;

my $f = DateTime::Format::Epoch::TAI64->new();
my $f = DateTime::Format::Epoch::TAI64->new( format => 'string' );

isa_ok($f, 'DateTime::Format::Epoch::TAI64' );

# example from http://cr.yp.to/proto/tai64.txt
my $dt = DateTime->new( year => 1997, month => 10, day => 3,
hour => 18, minute => 14, second => 48,
time_zone => 'UTC' );
is($f->format_datetime_as_string($dt), "\x40\0\0\0\x34\x35\x36\x37",
is($f->format_datetime($dt), "\x40\0\0\0\x34\x35\x36\x37",
'1997-10-3 as string');
14 changes: 14 additions & 0 deletions t/303_parse.t
@@ -0,0 +1,14 @@
use strict;
BEGIN { $^W = 1 }

use Test::More tests => 2;
use DateTime;
use DateTime::Format::Epoch::TAI64;

my $f = DateTime::Format::Epoch::TAI64->new( format => 'string' );

isa_ok($f, 'DateTime::Format::Epoch::TAI64' );

# example from http://cr.yp.to/proto/tai64.txt
is($f->parse_datetime("\x40\0\0\0\x34\x35\x36\x37")->datetime,
'1997-10-03T18:14:48', '1997-10-3 as string');

0 comments on commit 4cc3edf

Please sign in to comment.