DateTime-Format-Epoch
view release on metacpan or search on metacpan
lib/DateTime/Format/Epoch.pm view on Meta::CPAN
package DateTime::Format::Epoch;
use 5.00503; #qr
use strict;
use vars qw($VERSION);
$VERSION = '0.16';
use DateTime 0.22;
use DateTime::LeapSecond;
use Math::BigInt 'lib' => 'GMP,Pari,FastCalc';
use Params::Validate qw/validate BOOLEAN OBJECT/;
sub _floor {
my $x = shift;
my $ix = int $x;
if ($ix <= $x) {
return $ix;
} else {
return $ix - 1;
}
}
my %units_per_second = (
seconds => 1,
milliseconds => 1000,
microseconds => 1e6,
nanoseconds => 1e9,
);
sub new {
my $class = shift;
my %p = validate( @_,
{ epoch => {type => OBJECT,
can => 'utc_rd_values'},
unit => {callbacks =>
{'valid unit' =>
sub { exists $units_per_second{$_[0]}
or $_[0] > 0 }},
default => 'seconds'},
type => {regex => qr/^(?:int|float|bigint)$/,
default => 0},
local_epoch => {type => BOOLEAN,
default => 0},
dhms => {type => BOOLEAN,
default => 0},
skip_leap_seconds => {type => BOOLEAN,
default => 1},
start_at => {default => 0},
} );
$p{epoch} = $p{epoch}->clone if $p{epoch}->can('clone');
$p{unit} = $units_per_second{$p{unit}} || $p{unit};
$p{unit} = 1 if $p{dhms};
if (!$p{type}) {
$p{type} = ($p{unit} > 1e6 ? 'bigint' : 'int');
}
($p{epoch_rd_days}, $p{epoch_rd_secs}) = $p{epoch}->utc_rd_values;
$p{epoch_class} = ref $p{epoch};
if (!$p{skip_leap_seconds}) {
$p{leap_secs} =
DateTime::LeapSecond::leap_seconds( $p{epoch_rd_days} );
}
my $self = bless \%p, $class;
return $self;
}
sub format_datetime {
my ($self, $dt) = @_;
unless (ref $self) {
$self = $self->new;
}
$dt = $dt->clone->set_time_zone('floating')
if $self->{local_epoch} &&
$self->{epoch}->can('time_zone') &&
$self->{epoch}->time_zone->is_floating &&
$dt->can('time_zone') &&
!$dt->time_zone->is_floating;
my ($rd_days, $rd_secs) = $dt->utc_rd_values;
my $delta_days = $rd_days - $self->{epoch_rd_days};
my $delta_secs = $rd_secs - $self->{epoch_rd_secs};
my $secs = $delta_days * 86_400 + $delta_secs;
if (!$self->{skip_leap_seconds}) {
$secs += DateTime::LeapSecond::leap_seconds( $rd_days )
- $self->{leap_secs};
}
( run in 0.618 second using v1.01-cache-2.11-cpan-39bf76dae61 )