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

I am trying to convert a file date to epoch using a single line of code in Solaris 10, which uses an older version of perl.

I have been able to convert epoch to a date with your assistance:

echo $epoch | perl -MPOSIX -e 'print strftime("%m%d%H%M", gtime <stdin>)'

However, I would like to now reverse this process.

I was thinking about something like the following:

echo "Mar 20 2018 09:00" | perl -MPOSIX -e 'print strptime(<stdin>, "%s")'

But, I receive an error "Undefined subroutine &main::strptime called at -e line 1, <stdin> line 1. I tried substituting <stdin> with $ARGV[0] but still receive a subroutine error.

Replies are listed 'Best First'.
Re: Date to Epoch (updated)
by haukex (Archbishop) on Mar 20, 2018 at 13:56 UTC
    perl -MPOSIX -e 'print strptime(<stdin>, "%s")'

    For some reason, Perl's POSIX does not provide strptime, you'd need to install and use POSIX::strptime.

    But if you have or can install the module Time::Piece (in core since 5.10), you can use its Time::Piece->strptime(STRING, FORMAT), it has a nicer interface.

    Update:

    $ echo "Mar 20 2018 09:00" | perl -wMstrict -MTime::Piece -nle 'print +Time::Piece->strptime($_,"%b %d %Y %H:%M")->epoch' 1521536400

    If you want to use POSIX::strptime, you should also look into mktime, although at that point I'd really recommend using a better module. I usually use DateTime because it supports almost everything you'd need, but for simple tasks Time::Piece is enough.

      That should probably be localtime->strptime(...)->epoch

      Thank you for the reply

      Time::Piece does not work in core 5.10, and I am unable to install any modules

      I did run across the following code though:

      print -e 'print scalar timelocal(2,16,10,20,2,2018)'

      This solution, however would require me to use external variables in some way

      echo "2,16,10,10,20,2,2018" | perl -e 'print scalar timelocal(<stdin>)'

      Does not recognize the data being pushed

        Time::Piece does not work in core 5.10

        I'm not sure what you mean? In my installations of 5.10.0 and 5.10.1 with Time::Piece 1.12 resp. 1.15 the code I showed works fine. If you are having trouble, see How do I post a question effectively?

        I am unable to install any modules

        That's unlikely - see Yes, even you can use CPAN and local::lib.

        If all you're doing is converting a date, perhaps see date, although it can't do quite as much as the Perl modules I've named.

        $ date -d "Mar 20 2018 09:00" +"%s" 1521532800

        Note there is a discrepancy of one hour to the output in my example above, most likely due to different time zone handling. It's always best to include time zone information with date/time strings or objects to avoid ambiguity.

        And, this solution would also require me to process the dates to numbers first

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Date to Epoch
by Anonymous Monk on Mar 20, 2018 at 15:16 UTC

    If you have a file, and need its epoch date, probably easiest is to stat it directly

    $ perl -we 'print +(stat pop)[9]' myfile.txt 1521558861

      Not only is this simpler, it avoids the problem of duplicate times around a DST switch.

Re: Date to Epoch
by thanos1983 (Parson) on Mar 20, 2018 at 16:15 UTC

    Hello Anonymous Monk,

    As the other fellow Anonymous Monk suggested you can use stat to get the file information and then from there you can print the date into human readable form with Date::Manip.

    Sample of code:

    #!/usr/bin/perl use strict; use warnings; use Date::Manip; my $filename = 'test.log'; my $epochSecs = (stat($filename))[9]; print "Date: " . UnixDate( ParseDateString("epoch $epochSecs"), "%Y-%m +-%d %T" ) . "\n";

    The module Date::Manip is compatible with you Perl version, if you can install it will run on Solaris 10. Solaris 10 runs on perl 5.8.4 ref perl 5.8.4 package for solaris 10.

    Hope this helps, BR.

    Seeking for Perl wisdom...on the process of learning...not there...yet!
Re: Date to Epoch
by Anonymous Monk on Mar 20, 2018 at 14:56 UTC

    I have found a way to do this but it is messy:

    perl -MPOSIX -MTime::Local -se 'print scalar timelocal($a, $b, $c, $d, $e, $f)' -- -a=$sec -b=$min -c=$hour -d=$day -e=$month -f=$year

    Is there a more simpler approach as the one proposed earlier?

      The root node shows the date as a single string (without seconds), but now you have what look like individual bash variables $sec, $min, etc. - where did those come from? Perhaps you could provide us with more context (surrounding code, etc.). See also I know what I mean. Why don't you?

        My apology

        Running:

        ls -oglE <file_name> | awk '{print $4":"$5}' | cut -d. -f1

        will provide with me a date format of: 2018-03-15:09:25:15

        I can then parse this data and assign it to individual variables like seconds, minutes, hours, day, month, year

        But I was hoping to find a simple one line solution to take a format of "Mar 15 09:25:29 2018" and get an epoch time

Re: Date to Epoch
by Anonymous Monk on Mar 20, 2018 at 13:53 UTC

    Also, this version of bash does not allow %s

A reply falls below the community's threshold of quality. You may see it by logging in.