Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I parse microseconds with Time::Piece strptime?

Tags:

perl

I have a timestamp that looks like 25-OCT-10 04.11.00.000000 AM. I'm trying to convert this to a time format with

Time::Piece->strptime("25-OCT-10 04.11.00.000000 AM","%d-%b-%y %I.%M.%S.%6N %p")

but it keeps throwing errors. I've tried %OS, %SZ. They dont seem to work. Can someone tell me what I'm doing wrong?

like image 334
Aks Avatar asked Oct 25 '10 05:10

Aks


2 Answers

Time::Piece doesn't support sub-second times. Try DateTime instead, for example, DateTime::Format::Strptime:

use DateTime::Format::Strptime;

my $parser = DateTime::Format::Strptime->new(
  pattern => '%d-%b-%y %I.%M.%S.%6N %p',
);

my $dt = $parser->parse_datetime("25-OCT-10 04.11.00.000000 AM");
like image 155
cjm Avatar answered Sep 28 '22 08:09

cjm


strptime won't read that. strptime works with a structure that only goes down to integer seconds, and it doesn't have any formats for recognizing non-integer numerics -- and there's no such format as N in Time::Piece's strptime. If you know that you're always expecting .000000 for a number of microseconds then you could try using ..."%I.%M.%S.000000 %p", otherwise strptime just isn't for you.

How about DateTime::Format::CLDR? A format of "dd-MMM-yy hh.mm.ss.SSSSSS a" seems to work perfectly well with that format.

use DateTime::Format::CLDR;
my $parser = DateTime::Format::CLDR->new(
    pattern => "dd-MMM-yy hh.mm.ss.SSSSSS a",
    locale => "en_US",
);
my $dt = $parser->parse_datetime("25-OCT-10 04.11.00.000100 AM");

say $dt->iso8601; # 2010-01-25T04:11:00

Edit: just noticed that this doesn't recognize months properly if they're all uppercase -- it recognizes "Oct" but not "OCT". A fixed version is available here and has been sent upstream for merge :)

Update: DateTime::Format::CLDR 1.11 is properly case-insensitive.

like image 20
hobbs Avatar answered Sep 28 '22 07:09

hobbs