How to convert timestamp to epoch?

Discussion in 'Perl Misc' started by void.no.spam.com@gmail.com, Oct 30, 2007.

  1. Guest

    If I get timestamps in the following format:

    22-OCT-07 06.16.44.160000 PM
    22-OCT-07 08.16.02.686000 AM

    What is the easiest way for me to convert it into the number of
    seconds since 1970?
     
    , Oct 30, 2007
    #1
    1. Advertising

  2. TonyV Guest

    On Oct 30, 2:45 pm, ""
    <> wrote:
    > If I get timestamps in the following format:
    >
    > 22-OCT-07 06.16.44.160000 PM
    > 22-OCT-07 08.16.02.686000 AM
    >
    > What is the easiest way for me to convert it into the number of
    > seconds since 1970?


    I would probably make it a function:

    use Time::Local;

    my $ts_to_convert = '22-jun-07 06.16.44.160000 PM';
    print timestamp_to_epoch($ts_to_convert);

    sub timestamp_to_epoch {
    my ($ts) = @_;
    my %month = ('JAN' => 0, 'FEB' => 1, 'MAR' => 2, 'APR' => 3, 'MAY'
    => 4, 'JUN' => 5,
    'JUL' => 6, 'AUG' => 7, 'SEP' => 8, 'OCT' => 9, 'NOV' => 10, 'DEC'
    => 11);
    if ($ts =~ m{^(\d{1,2})-(\w{1,3})-(\d{1,2}) (\d{1,2})\.(\d{1,2})\.
    (\d{1,2})\.\d+ ([AP])M$}i) {
    my ($dd, $mo, $yy, $hh, $mm, $ss, $ap) = ($1, $2, $3, $4, $5, $6,
    $7);
    $yy += 2000; $mo = $month{uc($mo)};
    $hh += 12 if (uc($ap) eq 'P');
    return timelocal($ss, $mm, $hh, $dd, $mo, $yy);
    }
    else { return 0; }
    }


    Check to make sure your return value is non-zero, and you're in
    business.

    You might also want to check out the Date::Manip package, as I
    understand that it was designed to do this type of parsing. I don't
    use it myself, so I'll defer to others' recommendations for it, but
    here it is:
    http://search.cpan.org/dist/Date-Manip/Manip.pod
     
    TonyV, Oct 30, 2007
    #2
    1. Advertising

  3. TonyV Guest

    On Oct 30, 3:15 pm, TonyV <> wrote:
    > On Oct 30, 2:45 pm, ""
    >
    > <> wrote:
    > > If I get timestamps in the following format:

    >
    > > 22-OCT-07 06.16.44.160000 PM
    > > 22-OCT-07 08.16.02.686000 AM

    >
    > > What is the easiest way for me to convert it into the number of
    > > seconds since 1970?

    >
    > I would probably make it a function:


    Gah, here's a more word-wrap-friendly version:

    use Time::Local;

    my $ts_to_convert = '22-jun-07 06.16.44.160000 PM';
    print timestamp_to_epoch($ts_to_convert);

    sub timestamp_to_epoch {
    my ($ts) = @_;
    my %month = (
    'JAN' => 0, 'FEB' => 1, 'MAR' => 2, 'APR' => 3,
    'MAY' => 4, 'JUN' => 5, 'JUL' => 6, 'AUG' => 7,
    'SEP' => 8, 'OCT' => 9, 'NOV' => 10, 'DEC' => 11);
    my $regex = '^(\d{1,2})-(\w{1,3})-(\d{1,2}) ';
    $regex .= '(\d{1,2})\.(\d{1,2})\.(\d{1,2})';
    $regex .= '\.\d+ ([AP])M$';
    if ($ts =~ m{$regex}i) {
    my ($dd, $mo, $yy, $hh, $mm, $ss, $ap) =
    ($1, $2, $3, $4, $5, $6, $7);
    $yy += 2000; $mo = $month{uc($mo)};
    $hh += 12 if (uc($ap) eq 'P');
    return timelocal($ss, $mm, $hh, $dd, $mo, $yy);
    }
    else { return 0; }
    }
     
    TonyV, Oct 30, 2007
    #3
  4. Paul Lalli Guest

    On Oct 30, 2:45 pm, ""
    <> wrote:
    > If I get timestamps in the following format:
    >
    > 22-OCT-07 06.16.44.160000 PM
    > 22-OCT-07 08.16.02.686000 AM
    >
    > What is the easiest way for me to convert it into the number of
    > seconds since 1970?


    If you convert those first two periods to colons, Date::parse can
    handle it just fine:

    #!/usr/bin/perl
    use strict;
    use warnings;
    use Date::parse 'str2time';
    my $date = "22-OCT-07 06.16.44.160000 PM";
    $date =~ s/\./:/ for 1..2;
    my $epoch = str2time($date);
    print "Epoch: $epoch\n";
    __END__

    Paul Lalli
     
    Paul Lalli, Oct 30, 2007
    #4
  5. Guest

    On Oct 30, 3:27 pm, TonyV <> wrote:
    > On Oct 30, 3:15 pm, TonyV <> wrote:
    >
    > > On Oct 30, 2:45 pm, ""

    >
    > > <> wrote:
    > > > If I get timestamps in the following format:

    >
    > > > 22-OCT-07 06.16.44.160000 PM
    > > > 22-OCT-07 08.16.02.686000 AM

    >
    > > > What is the easiest way for me to convert it into the number of
    > > > seconds since 1970?

    >
    > > I would probably make it a function:

    >
    > Gah, here's a more word-wrap-friendly version:
    >
    > use Time::Local;
    >
    > my $ts_to_convert = '22-jun-07 06.16.44.160000 PM';
    > print timestamp_to_epoch($ts_to_convert);
    >
    > sub timestamp_to_epoch {
    > my ($ts) = @_;
    > my %month = (
    > 'JAN' => 0, 'FEB' => 1, 'MAR' => 2, 'APR' => 3,
    > 'MAY' => 4, 'JUN' => 5, 'JUL' => 6, 'AUG' => 7,
    > 'SEP' => 8, 'OCT' => 9, 'NOV' => 10, 'DEC' => 11);
    > my $regex = '^(\d{1,2})-(\w{1,3})-(\d{1,2}) ';
    > $regex .= '(\d{1,2})\.(\d{1,2})\.(\d{1,2})';
    > $regex .= '\.\d+ ([AP])M$';
    > if ($ts =~ m{$regex}i) {
    > my ($dd, $mo, $yy, $hh, $mm, $ss, $ap) =
    > ($1, $2, $3, $4, $5, $6, $7);
    > $yy += 2000; $mo = $month{uc($mo)};
    > $hh += 12 if (uc($ap) eq 'P');
    > return timelocal($ss, $mm, $hh, $dd, $mo, $yy);
    > }
    > else { return 0; }
    >
    >
    >
    > }


    Thank you for writing that up.

    I did have to change one line to get it to work:

    sub timestamp_to_epoch {
    my ($ts) = @_;
    my %month = (
    'JAN' => 0, 'FEB' => 1, 'MAR' => 2, 'APR' => 3,
    'MAY' => 4, 'JUN' => 5, 'JUL' => 6, 'AUG' => 7,
    'SEP' => 8, 'OCT' => 9, 'NOV' => 10, 'DEC' => 11);
    my $regex = '^(\d{1,2})-(\w{1,3})-(\d{1,2}) ';
    $regex .= '(\d{1,2})\.(\d{1,2})\.(\d{1,2})';
    $regex .= '\.\d+ ([AP])M$';
    if ($ts =~ m{$regex}i) {
    my ($dd, $mo, $yy, $hh, $mm, $ss, $ap) =
    ($1, $2, $3, $4, $5, $6, $7);
    $yy += 2000; $mo = $month{uc($mo)};
    $hh += 12 if (uc($ap) eq 'P' && $hh != 12);
    return timelocal($ss, $mm, $hh, $dd, $mo, $yy);
    }
    else { return 0; }
    }
     
    , Oct 30, 2007
    #5
  6. Guest

    On Oct 30, 1:27 pm, TonyV <> wrote:
    >
    > use Time::Local;
    >
    > my $ts_to_convert = '22-jun-07 06.16.44.160000 PM';
    > print timestamp_to_epoch($ts_to_convert);
    >
    > sub timestamp_to_epoch {
    > my ($ts) = @_;
    > my %month = (
    > 'JAN' => 0, 'FEB' => 1, 'MAR' => 2, 'APR' => 3,
    > 'MAY' => 4, 'JUN' => 5, 'JUL' => 6, 'AUG' => 7,
    > 'SEP' => 8, 'OCT' => 9, 'NOV' => 10, 'DEC' => 11);
    > my $regex = '^(\d{1,2})-(\w{1,3})-(\d{1,2}) ';
    > $regex .= '(\d{1,2})\.(\d{1,2})\.(\d{1,2})';
    > $regex .= '\.\d+ ([AP])M$';
    > if ($ts =~ m{$regex}i) {
    > my ($dd, $mo, $yy, $hh, $mm, $ss, $ap) =
    > ($1, $2, $3, $4, $5, $6, $7);
    > $yy += 2000; $mo = $month{uc($mo)};
    > $hh += 12 if (uc($ap) eq 'P');
    > return timelocal($ss, $mm, $hh, $dd, $mo, $yy);
    > }
    > else { return 0; }
    > }



    Ummm... this code has a subtle error in it: it won't correctly
    convert dates with "12" as the hour. To see what I mean, try running
    your code with this line:

    my $ts_to_convert = '22-JUN-07 12.16.44.160000 PM';

    Instead of an epoch time value, you'll see an error message like:

    Hour '24' out of range 0..23

    Converting 12-hour AM/PM time to 24-hour time (and vice-versa) is a
    little trickier than many people think. They often forget to check
    the cases where the hour equals 12, thinking that simply adding 12 to
    the hour (if they are in PM) is enough to convert from 12-hour to 24-
    hour time (like in the code you gave).

    But "12:00 am" needs to be converted to "00:00" and "12:00 pm"
    needs to be converted to "12:00", and just adding 12 to the hour value
    won't correctly convert either.
     
    , Oct 30, 2007
    #6
  7. Guest

    Oops, actually this is the working version:

    sub timestamp_to_epoch {
    my ($ts) = @_;
    my %month = (
    'JAN' => 0, 'FEB' => 1, 'MAR' => 2, 'APR' => 3,
    'MAY' => 4, 'JUN' => 5, 'JUL' => 6, 'AUG' => 7,
    'SEP' => 8, 'OCT' => 9, 'NOV' => 10, 'DEC' => 11);
    my $regex = '^(\d{1,2})-(\w{1,3})-(\d{1,2}) ';
    $regex .= '(\d{1,2})\.(\d{1,2})\.(\d{1,2})';
    $regex .= '\.\d+ ([AP])M$';
    if ($ts =~ m{$regex}i) {
    my ($dd, $mo, $yy, $hh, $mm, $ss, $ap) =
    ($1, $2, $3, $4, $5, $6, $7);
    $yy += 2000; $mo = $month{uc($mo)};
    if (uc($ap) eq 'P' && $hh != 12) {
    $hh += 12;
    }
    elsif (uc($ap) eq 'A' && $hh == 12) {
    $hh -= 12;
    }
    return timelocal($ss, $mm, $hh, $dd, $mo, $yy);
    }
    else { return 0; }
    }
     
    , Oct 30, 2007
    #7
  8. TonyV Guest

    On Oct 30, 5:42 pm, ""
    <> wrote:
    > Oops, actually this is the working version:


    Great catch, I usually deal exclusively with 24-hour time, which is
    why I probably introduced that bug in. I wish we could get rid of
    that pesky AM/PM format entirely, even from our everyday, normal
    lives. :p
     
    TonyV, Oct 30, 2007
    #8
  9. Guest

    On Oct 30, 11:47 am, Paul Lalli <> wrote:
    > $date =~ s/\./:/ for 1..2;


    That's a nifty little idiom that I would not have thought of (I would
    have probably constructed some ugly regexp). I'm gonna write that
    down on my Perl cheat-sheet!

    --
    The best way to get a good answer is to ask a good question.
    David Filmer (http://DavidFilmer.com)
     
    , Oct 31, 2007
    #9
  10. Guest

    On Oct 30, 1:47 pm, Paul Lalli <> wrote:
    >
    > #!/usr/bin/perl
    > use strict;
    > use warnings;
    > use Date::parse 'str2time';
    > my $date = "22-OCT-07 06.16.44.160000 PM";
    > $date =~ s/\./:/ for 1..2;
    > my $epoch = str2time($date);
    > print "Epoch: $epoch\n";
    > __END__



    The Date::parse module looks great, but I can't seem to find it in
    my ActiveState distribution of Perl, nor am I successful in installing
    it with the command "ppm install Date-Parse".

    Is there any one out there who is running ActiveState Perl and has
    it, or am I the only one who's missing the Date::parse module? In
    case anyone wonders, my "perl -v" output is:

    This is perl, v5.8.8 built for MSWin32-x86-multi-thread
    (with 33 registered patches, see perl -V for more detail)

    Copyright 1987-2006, Larry Wall

    Binary build 819 [267479] provided by ActiveState http://www.ActiveState.com
    Built Aug 29 2006 12:42:41

    Thanks.
     
    , Oct 31, 2007
    #10
  11. Guest

    On Oct 31, 12:10 pm, "" <>
    wrote:
    >
    > The Date::parse module looks great, but I can't seem to find it in
    > my ActiveState distribution of Perl, nor am I successful in installing
    > it with the command "ppm install Date-Parse".



    Update: I was able to install the Date::parse module for
    ActiveState Perl with the "cpan -i Date::parse" command. It required
    the "nmake.exe" executable (and possibly others as well) to be in my
    %PATH%, though.
     
    , Oct 31, 2007
    #11
  12. Ben Morrow Guest

    Quoth "" <>:
    > On Oct 30, 1:47 pm, Paul Lalli <> wrote:
    > >
    > > #!/usr/bin/perl
    > > use strict;
    > > use warnings;
    > > use Date::parse 'str2time';
    > > my $date = "22-OCT-07 06.16.44.160000 PM";
    > > $date =~ s/\./:/ for 1..2;
    > > my $epoch = str2time($date);
    > > print "Epoch: $epoch\n";
    > > __END__

    >
    >
    > The Date::parse module looks great, but I can't seem to find it in
    > my ActiveState distribution of Perl, nor am I successful in installing
    > it with the command "ppm install Date-Parse".


    Rather confusingly, ppm installs 'distributions' rather than 'modules',
    and unlike CPAN.pm won't cross-reference them for you. If you look
    Date::parse up on search.cpan.org you will see it is in the TimeDate
    distribution, so you should be able to get it with

    ppm install TimeDate

    Ben
     
    Ben Morrow, Nov 1, 2007
    #12
  13. Guest

    On Nov 1, 7:09 am, Ben Morrow <> wrote:
    >
    > Rather confusingly, ppm installs 'distributions' rather than 'modules',
    > and unlike CPAN.pm won't cross-reference them for you. If you look
    > Date::parse up on search.cpan.org you will see it is in the TimeDate
    > distribution, so you should be able to get it with
    >
    > ppm install TimeDate



    Thank-you for sharing that, Ben. I never knew that, and now I know
    what to do in case I have trouble with it in the future.

    (Oh, the "ppm install TimeDate" command you gave me worked
    perfectly.)

    Thanks again.

    -- Jean-Luc Romano
     
    , Nov 1, 2007
    #13
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Stefan Antonelli

    convert from date string to epoch

    Stefan Antonelli, Dec 15, 2006, in forum: Python
    Replies:
    2
    Views:
    443
    Paul Watson
    Dec 16, 2006
  2. Stefan Antonelli

    Re: convert from date string to epoch

    Stefan Antonelli, Dec 18, 2006, in forum: Python
    Replies:
    1
    Views:
    713
    John Machin
    Dec 18, 2006
  3. Alexander
    Replies:
    0
    Views:
    261
    Alexander
    Jul 20, 2010
  4. Rami Chowdhury

    Re: convert time to UTC seconds since epoch

    Rami Chowdhury, Jul 20, 2010, in forum: Python
    Replies:
    5
    Views:
    1,100
    Steve Allen
    Jul 21, 2010
  5. Ian Kelly
    Replies:
    0
    Views:
    462
    Ian Kelly
    Jul 21, 2010
Loading...

Share This Page