GrorkGnom has asked for the wisdom of the Perl Monks concerning the following question:

Hello there. I have several scripts that I have written and use at work, but one uses the Time::Piece module and strptime to output a date I pull from a text file. Currently, the code reads:

$date1 = Time::Piece->strptime($date, '%D, %M, %b, %Y') ;

It outputs the date correctly, but adds in a time of 00:00:00 which I do not want it too. It currently prints out like Fri Mar 11 00:00:00 2016. I would like it to print Friday Mar 11, 2016. Is there some secret to using strptime to get this done?

Thanks, GrorkGnom

Replies are listed 'Best First'.
Re: Using Time::Piece Strptime
by Mr. Muskrat (Canon) on Jan 25, 2016 at 22:19 UTC

    It's giving you as much info as you gave it to use.

    '%D' is a shortcut for '%m/%d/%y'. '%M' is the minute as a decimal (0-59). '%b' is abbreviated month name. '%Y' is the year with century as a decimal. See man strptime.

    # derived from your post my $date = '3/11/16, 00, Mar, 2016'; $date1 = Time::Piece->strptime($date, '%D, %M, %b, %Y'); print "'$date' parses to '$date1'\n"; __END__ '3/11/16, 0, Mar, 2016' parses as 'Fri Mar 11 00:00:00 2016'

    Update: Fixed print and added output.

Re: Using Time::Piece Strptime
by stevieb (Canon) on Jan 25, 2016 at 22:24 UTC

    Welcome to the Monastery, GrorkGnom!

    Please show us the code that you're using to output the date. Here's an example that appears to get you what you want. Review the last line... the input is one thing, but it's how you output it that makes the difference:

    use Time::Piece; my $date = "Mon Jan 25 15:19:50 GMT 2016"; my $date1 = Time::Piece->strptime($date, "%a %b %d %H:%M:%S %Z %Y"); # code you're interested in is below here print join ' ', $date1->wdayname, $date1->monname, $date1->mday, $date +1->year;
Re: Using Time::Piece Strptime
by 1nickt (Canon) on Jan 26, 2016 at 01:08 UTC

    "I would like it to print Friday Mar 11, 2016."

    strptime() is for parsing datetime strings.

    strftime() is for formatting datetime strings.

    You can get the output you want by using Time::Piece's strftime() with the appropriate POSIX strftime pattern. Note the chained object methods so you can parse and format in one statement:

    $ perl -MTime::Piece -E' my $date = "3/11/16"; say Time::Piece->strptime($date, "%D")->strftime("%A %b %e, %Y"); '
    Output:
    Friday Mar 11, 2016

    Regarding your existing use of strptime: as Mr. Muskrat points out, the pattern %D is a shortcut for %m/%d/%y.

    At a guess I would say your input looks like 3/11/16 and the date is being parsed by %D -- the rest of the patterns are ignored. You probably thought %D was 'day' and '%M' was month etc.

    Hope this helps!


    Update: moved the lead above the fold
    The way forward always starts with a minimal test.

      Don't assume the input. I think it's more important to show that the return is an object, and that the output can be whatever manipulation one wants :)

      The object will print out a date if it didn't fail, so the input is clearly legit in this case. OP just needs to know how to dump it properly.

        ??

        The code I posted shows how to get the desired output specified in the OP.

        It also addresses the input pattern issue, since I believe it is unlikely that the input data is actually like 3/11/16, 00, Mar, 2016 and that it's more likely the OP made an error with his pattern that his input data masked.

        Update: reply to (unmarked) addition above:

        "The object will print out a date if it didn't fail, so the input is clearly legit in this case. OP just needs to know how to dump it properly."

        Actually I would say it's rather important to get the right parsed datetime, not simply that "the object ... didn't fail." It's not the input that's at issue, it's the pattern used to parse the input.


        The way forward always starts with a minimal test.

      Here's the code piece I am working with:

      my $dfile = 'd1528235.txt'; open my $dfh, '<', $dfile; my $date; while ( <$dfh> ) { chomp; if ( not $date and $date = join '/', /=\((\d\d)(\d\d)(\d\d)/ ) { my $str1 = '$date'; my $date1; $date1 = Time::Piece->strptime($date, '%D, %M, %b, %Y') ; $worksheet->merge_range('A2:G2',$date1,$format7,);

      This is what I have actually gotten to work and it works pretty well except it gives me the default time in the middle displaying out 00:00:00 between the Day and the Year.

        Please post a working code snippet and a sample of the input data file if you want help cleaning up your strptime pattern. (see How do I post a question effectively?)

        You can, in any case, eliminate the undesired time part of your output with:

        my $date_sans_time = $date1->strftime("%A %b %e, %Y");
        as I showed above.


        update: added link
        The way forward always starts with a minimal test.

        Date formats in excel can be tricky. See Excel::Writer::XLSX::Utility

        #!perl use strict; use Excel::Writer::XLSX; use Excel::Writer::XLSX::Utility; use Time::Piece; my $wb = Excel::Writer::XLSX->new( 'dates.xlsx' ); my $ws = $wb->add_worksheet(); my $fmt = $wb->add_format(); $fmt->set_num_format( 'dddd mmm dd, yyyy' ); my $date = '3/15/16, 00, Mar, 2016'; my $t = Time::Piece->strptime($date, '%D, %M, %b, %Y') ; my $xldate = xl_date_list($t->year, $t->mon, $t->mday); $ws->write( 0, 0, $xldate, $fmt ); $wb->close();
        poj
      1nickt,

      To get it into a variable, I used both strptime, then passed that variable into a second one using strftime to format and print the date to a cell in Excel. Looking back, this set of scripts I have is quite complex for what it is doing. Glad I was able to get it to work. My date now shows up in Excel correct as i.e. Friday Jan 27, 2016.

      I found that there are a lot of different variables to strptime using Time::Piece as well as strftime. Just had to figure out how to pass the output of it to where I wanted it.

        I'm very glad you were able to get your script working.

        The way forward always starts with a minimal test.