use strict; use warnings; use POSIX qw(strftime); use Time::Local; sub iso2epoc { my $iso = shift; # check input and separate the date and time return undef unless ($iso =~ /^\@(?:(\d{0,8})T?(\d{0,6}))?$/); unless (length($iso) == 16) { my $date = $1 || ''; my $time = $2 || ''; # we need to know how many characters each has my $len_date = length($date); my $len_time = length($time); # get current date & time as defaults my $defdate = strftime("%Y%m%d", localtime); my $deftime = strftime("%H%M%S", localtime); # now we just copy the missing parts before the incomplete date & time $iso = '@' . substr($defdate, 0, 8 - $len_date) . $date # this assumes T22 means 22:00:00 . 'T' . $time . substr($deftime, 0, 6 - $len_time); } if ($iso =~ /^\@(\d{4})(\d{2})(\d{2})T(\d{2})(\d{2})(\d{2})$/) { return timelocal($6,$5,$4,$3,$2 - 1,$1); } return undef; } foreach my $iso () { chomp $iso; my $epoc = iso2epoc($iso) or die "wrong input: $iso"; print "$iso -> $epoc (" . strftime("%Y-%m-%d %X", localtime($epoc)) . ")\n"; } __DATA__ @20050122T000000 @050122T000000 @0122T000000 @22T000000 @T000000 @T0000 @T00 @22T @ #### @20050122T000000 -> 1106348400 (2005-01-22 00:00:00) @050122T000000 -> 1106348400 (2005-01-22 00:00:00) @0122T000000 -> 1106348400 (2005-01-22 00:00:00) @22T000000 -> 1114120800 (2005-04-22 00:00:00) @T000000 -> 1112392800 (2005-04-02 00:00:00) @T0000 -> 1112410800 (2005-04-02 05:00:00) @T00 -> 1112412540 (2005-04-02 05:29:00) @22T -> 1114140596 (2005-04-22 05:29:56) @ -> 1112412596 (2005-04-02 05:29:56)