Home > Back-end >  Perl convert datetime with pm to gmtime
Perl convert datetime with pm to gmtime

Time:10-19

I get a database date in a variable an need to convert the date from 12h to 24h format.

For instance, the date Jun 19 2019 11:08pm should be converted to Jun 19 2019 23:08.

Here is my unsuccessful attempt:

#!/usr/bin/perl 
use strict; 
use warnings; 
use feature 'say'; 
use Time::Piece; 

my $date="Jun 19 2019 11:08pm"; 
for (qw[$date]) { 
    my $time = Time::Piece->strptime($_, '%H%p'); 
    say $time->strftime('%H:%M:%S'); 
}

CodePudding user response:

In a comment, you say:

#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use Time::Piece;

my $date="Jun 19 2019 11:08pm";

for (qw[$date]) {
  my $time = Time::Piece->strptime($_, '%H%p');
  say $time->strftime('%H:%M:%S');
 }

"Doesn't work".

Well, "doesn't work" is a really unhelpful bug report. If I run your code, I get a really helpful error.

Error parsing time at /usr/lib64/perl5/Time/Piece.pm line 598

That tells us that the problem is almost certainly that the parsing format you're using ("%H%p") doesn't match your date string ("Jun 19 2019 11:08pm"). Which seems likely, given that "%H" matches an hour on the 24-hour clock and "%p" matches the "am/pm" indicator. And your date string contains a lot more information than that.

The documentation for Time::Piece point you at the strptime man page for more details of the format. And a few minutes looking at that would have led you to a rather more inclusive parsing format. Something like '%b %d %Y %I:%M%p'.

So now your code looks like this:

#!/usr/bin/perl
use strict;
use warnings;
use feature 'say';
use Time::Piece;

my $date="Jun 19 2019 11:08pm";

for (qw[$date]) {
  my $time = Time::Piece->strptime($_, '%b %d %Y %I:%M%p');
  say $time->strftime('%H:%M:%S');
}

But that gives us the same error. It took me a minute or so to work out what the problem is here. It's this line:

for (qw[$date])

I'm not sure what you were trying to do there, but qw[$date] creates a list containing a single element which is the literal string "$date" - not the contents of the variable string, which is (I suspect) what you wanted.

If we simplify this to for ($date) then the parsing works and we get the output "23:08:00". That's still not quite what you say you want for your output, but that's because you're missing some of the necessary output format - instead of just "%H:%M:%S", you need "%b %d %Y %H:%M:%S". Fixing that will give you the output that you need.

Obviously, the for loop is completely unnecessary here. You can just use $date as a parameter to strptime() instead of $_. But I've left the structure of the loop as I suspect your real code will make use of it.

Update: The misunderstandings in your original code are really interesting. I'd love to hear more about the thought processes that led you to this code. Perhaps we can improve the documentation for the module to prevent other people having similar problems.

CodePudding user response:

use strict;
use warnings;
use feature 'say';

use Time::Piece;

my $date="Jun 19 2019 11:08pm";

# strptime %I:%M%p matches 12-hour with am/pm
# strftime %H converts to 24-hour
$date = Time::Piece->strptime($date, '%b %d %Y %I:%M%p')->strftime('%b %d %Y %H:%M');

say $date;

# Jun 19 2019 23:08
  • Related