Skip to content

Commit

Permalink
Merge pull request #2 from mbeijen/ntp
Browse files Browse the repository at this point in the history
Added NTP epoch formatter.
  • Loading branch information
chorny committed Apr 12, 2015
2 parents 8891d0e + 88d068e commit 79037ea
Show file tree
Hide file tree
Showing 5 changed files with 139 additions and 0 deletions.
25 changes: 25 additions & 0 deletions example/ntptime.pl
@@ -0,0 +1,25 @@
#!/usr/bin/env perl

use strict;
use warnings;
use v5.10;

use DateTime::Format::Epoch::NTP;
use Socket;

my $hostname = 'pool.ntp.org';
socket(SOCKET, PF_INET, SOCK_DGRAM, getprotobyname('udp'));
my $ipaddr = inet_aton($hostname);
my $portaddr = sockaddr_in(123, $ipaddr);
my $bstr = "\010" . "\0"x47;
send(SOCKET, $bstr, 0, $portaddr);
$portaddr = recv(SOCKET, $bstr, 1024, 0);
my @words = unpack("N12",$bstr);
my $ntptime = $words[10];

my $dt = DateTime::Format::Epoch::NTP->parse_datetime( $ntptime );

$dt->set_time_zone('Europe/Moscow');

say "NTPTime $ntptime is in Moscow: " . $dt->hms;
say $dt->datetime;
88 changes: 88 additions & 0 deletions lib/DateTime/Format/Epoch/NTP.pm
@@ -0,0 +1,88 @@
package DateTime::Format::Epoch::NTP;

use strict;
use warnings;

use vars qw($VERSION @ISA);

$VERSION = '0.14';

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

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

my $epoch = DateTime->new( year => 1900, month => 1, day => 1,
time_zone => 'UTC' );

sub new {
my $class = shift;

return $class->SUPER::new( epoch => $epoch,
unit => 'seconds',
type => 'int',
skip_leap_seconds => 1 );
}

1;
__END__
=head1 NAME
DateTime::Format::Epoch::NTP - Convert DateTimes to/from NTP epoch seconds
=head1 SYNOPSIS
use DateTime::Format::Epoch::NTP;
my $dt = DateTime::Format::Epoch::NTP->parse_datetime( 3629861151 );
print $dt->datetime; # '2015-01-10T06:45:51'
my $formatter = DateTime::Format::Epoch::NTP->new();
my $dt = DateTime->new( year => 2015, month => 1, day => 10,
time_zone => 'Europe/Amsterdam' );
print $formatter->format_datetime($dt); # '3629833200'
=head1 DESCRIPTION
This module can convert a DateTime object (or any object that can be
converted to a DateTime object) to the number of seconds since the NTP
epoch.
The NTP epoch uses UTC; if you parse an NTP date your DateTime object
will be using the UTC timezone.
=head1 METHODS
Most of the methods are the same as those in L<DateTime::Format::Epoch>.
The only difference is the constructor.
=over 4
=item * new()
Constructor of the formatter/parser object. It has no parameters.
=back
=head1 SUPPORT
Support for this module is provided via the datetime@perl.org email
list. See http://lists.perl.org/ for more details.
=head1 AUTHOR
Eugene van der Pijll <pijll@gmx.net>
=head1 COPYRIGHT
Copyright (c) 2015 Michiel Beijen. This program is free software; you can
redistribute it and/or modify it under the same terms as Perl itself.
=head1 SEE ALSO
L<DateTime>
datetime@perl.org mailing list
=cut
2 changes: 2 additions & 0 deletions t/502_format.t
Expand Up @@ -6,6 +6,7 @@ use Test::More qw/no_plan/;
use DateTime;
use DateTime::Format::Epoch::JD;
use DateTime::Format::Epoch::MJD;
use DateTime::Format::Epoch::NTP;
use DateTime::Format::Epoch::TJD;
use DateTime::Format::Epoch::RJD;
use DateTime::Format::Epoch::Lilian;
Expand All @@ -16,6 +17,7 @@ my $dt = DateTime->new( year => 2004, month => 8, day => 28 );
my %dates = (
JD => 2453245.5,
MJD => 53245,
NTP => 3302640000,
TJD => 13245,
RJD => 53245.5,
Lilian => 154086,
Expand Down
5 changes: 5 additions & 0 deletions t/701_load.t
@@ -0,0 +1,5 @@
# t/001_load.t - check module loading

use Test::More tests => 1;

BEGIN { use_ok( 'DateTime::Format::Epoch::NTP' ); }
19 changes: 19 additions & 0 deletions t/702_format.t
@@ -0,0 +1,19 @@
use strict;
BEGIN { $^W = 1 }

use Test::More tests => 4;
use DateTime;
use DateTime::Format::Epoch::NTP;

my $f = DateTime::Format::Epoch::NTP->new();

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

my $dt = DateTime->new( year => 2015, month => 1, day => 10,
time_zone => 'Europe/Amsterdam' );
is($f->format_datetime($dt), '3629833200', 'Format DateTime as NTP epoch time');

$dt = DateTime::Format::Epoch::NTP->parse_datetime( 3629848426 );

is($dt->iso8601(), '2015-01-10T03:13:46', 'read NTP time');
is($dt->time_zone_long_name(), 'UTC', 'NPT time timezone is UTC');

0 comments on commit 79037ea

Please sign in to comment.