-1

I have date time strings in the format 2017-01-12T17:23:14.000-0800

In Perl, is there any easy way to parse two dates like these and find the difference without individually extracting all the fields in the string?

For example given 2017-01-12T17:23:14.000-0800 and 2017-01-13T17:23:14.000-0800, the difference I want would be 1 day (any reasonable format for this output is okay).

Borodin
  • 126,100
  • 9
  • 70
  • 144
user2605633
  • 105
  • 2
  • 7
  • Search for modules that work with date-times. The big boy of the lot is [DateTime](http://search.cpan.org/~drolsky/DateTime-1.42/lib/DateTime.pm), but there are others. – zdim Feb 17 '17 at 20:49
  • Possible answer - http://stackoverflow.com/questions/17040842/how-to-compare-dates-using-perl – jmag Feb 17 '17 at 20:50
  • Possible duplicate of [How to compare dates using perl?](http://stackoverflow.com/questions/17040842/how-to-compare-dates-using-perl) – Tanktalus Feb 17 '17 at 20:55

2 Answers2

6
use DateTime::Format::Strptime qw( );

my $format = DateTime::Format::Strptime->new(
   pattern  => '%Y-%m-%dT%H:%M:%S.%3N%Z',
   on_error => 'croak',
);

my $dt1 = $format->parse_datetime('2017-01-12T17:23:14.000-0800');
my $dt2 = $format->parse_datetime('2017-01-13T17:23:14.000-0800');

my ($y, $m, $d, $H, $M, $S) =
   ( $dt2 - $dt1 )->in_units(qw( years months days hours minutes seconds ));

Alternatives

my ($y, $m, $d) = $dt2->delta_md($dt1)->in_units(qw( years months days ));

my ($m, $d) = $dt2->delta_md($dt1)->in_units(qw( months days ));

my $d = $dt2->delta_days($dt1)->in_units(qw( days ));

my $S = $dt2->delta_ms($dt1)->in_units(qw( seconds ));
ikegami
  • 367,544
  • 15
  • 269
  • 518
0

Time::Moment supports the specified string representation. Since it's not a well-formed ISO 8601 representation we need to pass the lenient option to the from_string constructor.

my $tm1 = Time::Moment->from_string('2017-01-12T17:23:14.000-0800', lenient => 1);
my $tm2 = Time::Moment->from_string('2017-01-13T17:23:14.000-0800', lenient => 1);

say $tm1->delta_days($tm2);

Output:

1

In the interest of full disclosure, I am the author of Time::Moment.

chansen
  • 2,446
  • 15
  • 20