| Current Path : /proc/thread-self/root/proc/self/root/usr/share/doc/perl-Time-Moment/eg/ |
| Current File : //proc/thread-self/root/proc/self/root/usr/share/doc/perl-Time-Moment/eg/excel.pl |
#!/usr/bin/perl
use strict;
use warnings;
# Convert between Excel serial dates and Time::Moment
use Time::Moment;
use constant EXCEL_EPOCH => Time::Moment->from_string('1899-12-30T00Z')->rd;
sub moment_from_excel {
@_ == 1 or die q/Usage: moment_from_excel(date)/;
my ($date) = @_;
return Time::Moment->from_rd($date + ($date < 61), epoch => EXCEL_EPOCH);
}
sub moment_to_excel {
@_ == 1 or die q/Usage: moment_to_excel(moment)/;
my ($moment) = @_;
my $date = $moment->rd - EXCEL_EPOCH;
return $date - ($date < 61);
}
my @tests = (
[ '1899-12-31T00:00:00Z', 0 ],
[ '1900-01-01T00:00:00Z', 1 ],
[ '1900-02-27T00:00:00Z', 58 ],
[ '1900-02-28T00:00:00Z', 59 ],
[ '1900-03-01T00:00:00Z', 61 ],
[ '1900-03-02T00:00:00Z', 62 ],
[ '1969-12-31T23:59:58Z', 25568.9999768519 ],
[ '1969-12-31T23:59:58.500Z', 25568.9999826389 ],
[ '1969-12-31T23:59:58.800Z', 25568.9999861111 ],
[ '1969-12-31T23:59:58.900Z', 25568.9999872685 ],
[ '1969-12-31T23:59:58.980Z', 25568.9999881944 ],
[ '1969-12-31T23:59:58.990Z', 25568.9999883102 ],
[ '1969-12-31T23:59:58.998Z', 25568.9999884028 ],
[ '1969-12-31T23:59:58.999Z', 25568.9999884143 ],
[ '1969-12-31T23:59:59Z', 25568.9999884259 ],
[ '1969-12-31T23:59:59.001Z', 25568.9999884375 ],
[ '1969-12-31T23:59:59.002Z', 25568.9999884490 ],
[ '1969-12-31T23:59:59.010Z', 25568.9999885417 ],
[ '1969-12-31T23:59:59.020Z', 25568.9999886574 ],
[ '1969-12-31T23:59:59.100Z', 25568.9999895834 ],
[ '1969-12-31T23:59:59.200Z', 25568.9999907408 ],
[ '1969-12-31T23:59:59.300Z', 25568.9999918982 ],
[ '1969-12-31T23:59:59.400Z', 25568.9999930556 ],
[ '1969-12-31T23:59:59.490Z', 25568.9999940973 ],
[ '1969-12-31T23:59:59.499Z', 25568.9999942014 ],
[ '1969-12-31T23:59:59.500Z', 25568.9999942130 ],
[ '1969-12-31T23:59:59.501Z', 25568.9999942245 ],
[ '1969-12-31T23:59:59.510Z', 25568.9999943287 ],
[ '1969-12-31T23:59:59.600Z', 25568.9999953704 ],
[ '1969-12-31T23:59:59.700Z', 25568.9999965278 ],
[ '1969-12-31T23:59:59.800Z', 25568.9999976852 ],
[ '1969-12-31T23:59:59.900Z', 25568.9999988426 ],
[ '1969-12-31T23:59:59.980Z', 25568.9999997686 ],
[ '1969-12-31T23:59:59.990Z', 25568.9999998843 ],
[ '1969-12-31T23:59:59.998Z', 25568.9999999768 ],
[ '1969-12-31T23:59:59.999Z', 25568.9999999885 ],
[ '1970-01-01T00:00:00Z', 25569 ],
[ '1970-01-01T00:00:00.001Z', 25569.0000000115 ],
[ '1970-01-01T00:00:00.002Z', 25569.0000000232 ],
[ '1970-01-01T00:00:00.010Z', 25569.0000001157 ],
[ '1970-01-01T00:00:00.020Z', 25569.0000002314 ],
[ '1970-01-01T00:00:00.100Z', 25569.0000011574 ],
[ '1970-01-01T00:00:00.200Z', 25569.0000023148 ],
[ '1970-01-01T00:00:00.300Z', 25569.0000034722 ],
[ '1970-01-01T00:00:00.400Z', 25569.0000046296 ],
[ '1970-01-01T00:00:00.490Z', 25569.0000056713 ],
[ '1970-01-01T00:00:00.499Z', 25569.0000057755 ],
[ '1970-01-01T00:00:00.500Z', 25569.0000057870 ],
[ '1970-01-01T00:00:00.501Z', 25569.0000057986 ],
[ '1970-01-01T00:00:00.510Z', 25569.0000059027 ],
[ '1970-01-01T00:00:00.600Z', 25569.0000069444 ],
[ '1970-01-01T00:00:00.700Z', 25569.0000081018 ],
[ '1970-01-01T00:00:00.800Z', 25569.0000092592 ],
[ '1970-01-01T00:00:00.900Z', 25569.0000104166 ],
[ '1970-01-01T00:00:00.980Z', 25569.0000113426 ],
[ '1970-01-01T00:00:00.990Z', 25569.0000114583 ],
[ '1970-01-01T00:00:00.998Z', 25569.0000115510 ],
[ '1970-01-01T00:00:00.999Z', 25569.0000115625 ],
[ '1970-01-01T00:00:01Z', 25569.0000115741 ],
[ '1970-01-01T00:00:01.001Z', 25569.0000115857 ],
[ '1970-01-01T00:00:01.002Z', 25569.0000115972 ],
[ '1970-01-01T00:00:01.010Z', 25569.0000116898 ],
[ '1970-01-01T00:00:01.020Z', 25569.0000118056 ],
[ '1970-01-01T00:00:01.100Z', 25569.0000127315 ],
[ '1970-01-01T00:00:01.200Z', 25569.0000138889 ],
[ '9999-12-31T23:59:58Z', 2958465.9999768520 ],
[ '9999-12-31T23:59:58.500Z', 2958465.9999826388 ],
[ '9999-12-31T23:59:58.800Z', 2958465.9999861112 ],
[ '9999-12-31T23:59:58.900Z', 2958465.9999872684 ],
[ '9999-12-31T23:59:58.980Z', 2958465.9999881946 ],
[ '9999-12-31T23:59:58.990Z', 2958465.9999883100 ],
[ '9999-12-31T23:59:58.998Z', 2958465.9999884027 ],
[ '9999-12-31T23:59:58.999Z', 2958465.9999884143 ],
[ '9999-12-31T23:59:59Z', 2958465.9999884260 ],
[ '9999-12-31T23:59:59.001Z', 2958465.9999884376 ],
[ '9999-12-31T23:59:59.002Z', 2958465.9999884493 ],
[ '9999-12-31T23:59:59.010Z', 2958465.9999885415 ],
[ '9999-12-31T23:59:59.020Z', 2958465.9999886574 ],
[ '9999-12-31T23:59:59.100Z', 2958465.9999895832 ],
[ '9999-12-31T23:59:59.200Z', 2958465.9999907408 ],
[ '9999-12-31T23:59:59.300Z', 2958465.9999918980 ],
[ '9999-12-31T23:59:59.400Z', 2958465.9999930556 ],
[ '9999-12-31T23:59:59.490Z', 2958465.9999940973 ],
[ '9999-12-31T23:59:59.499Z', 2958465.9999942016 ],
[ '9999-12-31T23:59:59.500Z', 2958465.9999942128 ],
[ '9999-12-31T23:59:59.501Z', 2958465.9999942244 ],
[ '9999-12-31T23:59:59.510Z', 2958465.9999943287 ],
[ '9999-12-31T23:59:59.600Z', 2958465.9999953704 ],
[ '9999-12-31T23:59:59.700Z', 2958465.9999965276 ],
[ '9999-12-31T23:59:59.800Z', 2958465.9999976852 ],
[ '9999-12-31T23:59:59.900Z', 2958465.9999988424 ],
[ '9999-12-31T23:59:59.980Z', 2958465.9999997686 ],
[ '9999-12-31T23:59:59.990Z', 2958465.9999998841 ],
[ '9999-12-31T23:59:59.998Z', 2958465.9999999767 ],
[ '9999-12-31T23:59:59.999Z', 2958465.9999999884 ],
);
use Test::More 0.88;
use Test::Number::Delta 1.06 relative => 1E-10;
foreach my $test (@tests) {
my ($string, $date) = @$test;
my $tm = moment_from_excel($date);
is($tm->to_string, $string, "moment_from_excel($date)");
delta_ok(moment_to_excel($tm), $date, "moment_to_excel($tm)");
}
done_testing();
eval {
require DateTime::Format::Excel;
require Benchmark;
{
print "\nComparing DateTime::Format::Excel and Time::Moment\n";
my $date = 30188.010650613425;
Benchmark::cmpthese( -10, {
'DateTime' => sub {
my $dt = DateTime::Format::Excel->parse_datetime($date);
},
'Time::Moment' => sub {
my $tm = moment_from_excel($date);
},
});
}
};