0

I have a date/time like this: 2015-07-31T13:30:00.000+01:00 And I want to convert it to normal date and time using Perl and Time::Piece->strptime

Here is my code:

sub changeDateFormat {
  my ($date, $fromFormat, $toFormat) = (@_);
  return Time::Piece->strptime($date, $fromFormat)->strftime($toFormat);
}

The call:

print changeDateFormat($that_date, '%Y-%m-%dT%H:%M:%S.%N+%z', '%Y:%m:%d');

I think that .000 are nano seconds and +01.00 stands for time zone. But the given code gives this: Error parsing time at /usr/lib64/perl5/Time/Piece.pm line 470

Any help is appreciated.

chansen
  • 2,446
  • 15
  • 20
Paulius
  • 51
  • 4
  • See [`DateTime::Format::Strptime`](https://metacpan.org/pod/DateTime::Format::Strptime).. It has both `%N` and `%z`.. – Håkon Hægland Jul 10 '15 at 10:47
  • 1
    The format is known as a ISO 8601 calendar date and time of day with a zone designator in extended format. [Time::Moment->from_string](https://metacpan.org/pod/distribution/Time-Moment/lib/Time/Moment.pod#from_string) can be used to parse it. – chansen Jul 10 '15 at 17:42

3 Answers3

1

There's a couple of problems I think.

%N isn't in my strftime manpage. So that might well not work.

And %z - I'm pretty sure +01:00 isn't valid.

  %z     The +hhmm or -hhmm numeric timezone (that is, the hour and
          minute offset from UTC). (SU)

This works though:

my $date = '2015-07-31T13:30:00+0100'; 
my $fromFormat = '%Y-%m-%dT%H:%M:%S%z'; 
print Time::Piece->strptime($date, $fromFormat);

So I'd suggest - unless your milliseconds are important - you could just strip those via a regex, and likewise the timezone. (And it they are important, I don't think Time::Piece does ms resolution anyway)

You can probably use a regular expression to 'correct' your input date if you were so inclined. I'm unsure if fits your use case but:

$date =~ s/\+(\d{2}):(\d{2})$/+$1$2/;
$date =~ s/\.\d{3}+/+/;
Sobrique
  • 52,974
  • 7
  • 60
  • 101
1

You can use strptime in Time::Piece and adding the time zone manually as shown in this answer, or you could try using DateTime::Format::Strptime instead:

use feature qw(say);
use strict;
use warnings;
use DateTime::Format::Strptime;

my $timestamp = '2015-07-31T13:30:00.000+0100';
my $strp = DateTime::Format::Strptime->new(
    pattern   => '%Y-%m-%dT%H:%M:%S.%N%z'
);

my $dt = $strp->parse_datetime( $timestamp );

say $dt->strftime('%Y:%m:%d');

Output:

2015:07:31
Community
  • 1
  • 1
Håkon Hægland
  • 39,012
  • 21
  • 81
  • 174
1
use DateTime; 
use DateTime::Format::ISO8601;

use DateTime::Format::Strptime;

my $string = '2015-07-31T13:30:00.000+01:00';
my $date = DateTime::Format::ISO8601->parse_datetime( $string ); 
die "Error" unless $date;

my $formatter = new DateTime::Format::Strptime(pattern => '%Y-%m-%d %T');
$date->set_formatter($formatter);
print "$date\n";
Chankey Pathak
  • 21,187
  • 12
  • 85
  • 133