sayth
sayth

Reputation: 7048

Perl using Date::Parse module unable to print <STDIN> date in different format

I want to accept a user date on the command line in format

dd/mm/yyyy

then print the date out to the user in

yyyy/mm/dd

I am trying to use the Date::Parse module to parse into a date to be reprinted.

The Date:Parse docs show that I should be able to get $day, $month and $year from user input.

use Date::Parse;

$time = str2time($date);

($ss,$mm,$hh,$day,$month,$year,$zone) = strptime($date);

This is my current code:

use strict;
use Date::Parse;

print "Enter a date in dd/mm/yyy format: ";
my $user_date = <STDIN>;
my @date      = strptime($user_date);

# ( $day, $month, $year ) = strptime($user_date);
# my $user_day = ( ($day) = strptime($user_date) );
print "%Y/%m/%d", @date;

However the print fails and it appears from output that entered 10 of 10 is 9 in output.

Output

Enter a date in dd/mm/yyy format: 16/10/1952
%Y/%m/%d1952916s

What should I do?

Upvotes: 1

Views: 108

Answers (1)

Dave Cross
Dave Cross

Reputation: 69314

The documentation for Date::Parse isn't clear, but it looks like you get the values back in the format that localtime() would expect. The year, for example, seems to be the year minus 1900. This means that the month number will be 0 to 11 rather than 1 to 12.

Date::Parse hasn't been updated for over five years. I'd suggest that it should best be avoided these days. There are much better options to choose from. These include Time::Piece that has been included as a standard part of the Perl distribution since version 5.10.0. You can use its strptime() (string parse time) method to parse your string and its strftime() (string format time) method to format the date object as you like.

#!/usr/bin/perl

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

use Time::Piece;

print "Enter a date in dd/mm/yyy format: ";
chomp(my $user_date = <STDIN>);

my $tp = Time::Piece->strptime($user_date, '%d/%m/%Y');

say $tp->strftime('%Y/%m/%d');

Update:

Also, it's really not clear what this line is supposed to do:

print "%Y/%m/%d", @date;

I think you were thinking of using the strftime() method from POSIX.pm.

print strftime "%Y/%m/%d", @date;

But with use warnings this generates warnings because of all the undefined values in @data (that's a rather bizarre design decision in that module and, in my opinion, another reason to avoid it). You can fix that by replacing:

my @date      = strptime($user_date);

With:

my @date      = map { $_ // 0 } strptime($user_date);

Upvotes: 6

Related Questions