[Perl] Tijd in ctime formaat omzetten naar UNIX timestamp

Pagina: 1
Acties:

  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22-08 01:56
De topic title geeft de bedoeling al redelijk weer. Ik krijg een tijd in locale-independent ctime-notatie (bv. "Thu Oct 13 04:54:34 1994") binnen en die wil ik graag omzetten naar een UNIX timestamp zodat ik er wat zinnige dingen mee kan gaan doen.

Nu ben ik in principe best in staat om de maand, dag, tijd en jaartal uit die string te halen met een simpele reguliere expressie en met POSIX::mktime daar een timestamp van te construeren, maar het kan er bij mij niet in dat hier geen standaardfunctie voor zou bestaan. Met heel wat creatief manual-zoekwerk kon ik echter geen geschikte functie vinden!

De standaard Perl functies bevatten wel functies om timestamps op te splitsen in componenten (gmtime, localtime), maar niet omgekeerd. De POSIX module voegt wat nuttige functies toe, maar geen daarvan doet iets met een tijd in string vorm.

Uiteraard hebben we nog Time::Local en daar staat ook een functie timegm in, die als een inverse voor gmtime wordt gepresenteerd, maar die kan niet op een enkele string werken (terwijl gmtime in scalaire context wel de tijd als een string in ctime formaat oplevert!).

Mijn vraag is dus: bestaat er een standaardmanier om een datum in cstring formaat om te zetten naar een timestamp? Liefst natuurlijk door van standaardmodules gebruik te maken (anders kan ik net zo goed zelf een procedure van een regel of drie schrijven).

  • phreggle
  • Registratie: Juni 2002
  • Niet online
Niet helemaal het antwoord op je vraag, (ik kon zo snel ook niet iets vinden... :) ). Maar als laatste redmiddel kan je altijd nog zoiets aanroepen vanuit je script:

code:
1
2
3
phreggle@anouk:~$ date -d "Thu Oct 13 04:54:34 1994" +%s
782020474
phreggle@anouk:~$


(Hoewel je dan eigenlijk net zo goed zelf de routine kan schrijven. :) )

[ Voor 15% gewijzigd door phreggle op 17-07-2003 00:38 ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22-08 01:56
phreggle schreef op 17 July 2003 @ 00:36:
Niet helemaal het antwoord op je vraag, (ik kon zo snel ook niet iets vinden... :) ). Maar als laatste redmiddel kan je altijd nog zoiets aanroepen vanuit je script:
code:
1
2
3
phreggle@anouk:~$ date -d "Thu Oct 13 04:54:34 1994" +%s
782020474
phreggle@anouk:~$

(Hoewel je dan eigenlijk net zo goed zelf de routine kan schrijven. :) )
Op zich vind ik dat nog niet zo verkeerd, ware het niet dat ik enkele honderdduizenden regels moet verwerken, en om daar nu elke keer een nieuw proces voor te spawnen gaat me eigenlijk wat te ver. Ik kan echter wel eens kijken naar de implementatie van date, maar ik acht de kans klein dat ik daar iets in tegenkom dat ik ook vanuit Perl kan gebruiken...

edit:
Hmz, onder welk besturingssysteem test jij? Onder FreeBSD kan ik namelijk de datum niet in dat formaat meegeven. Is het Linux ofzo?

[ Voor 10% gewijzigd door Soultaker op 17-07-2003 00:59 ]


  • Soultaker
  • Registratie: September 2000
  • Laatst online: 22-08 01:56
Ter referentie; ik doe het voorlopig maar even zo:
Perl:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# timec.pm

use strict;
use POSIX qw(mktime);

our %months = (
    Jan =>  0, Feb =>  1, Mar =>  2, Apr =>  3, May =>  4, Jun =>  5,
    Jul =>  6, Aug =>  7, Sep =>  8, Oct =>  9, Nov => 10, Dec => 11 );
our $months = join('|', keys %months);

sub timec
{
    my ($date) = @_;                            # get arguments
    return undef unless                         # malformed argument
        my ($wday, $mon, $mday, $hour, $min, $sec, $year) =
        ($date =~ /^\s*
            (Mon|Tue|Wed|Thu|Fri|Sat|Sun)\s+    # day of week
            ($months)\s+                        # month
            (\d{1,2})\s+                        # day of month
            (\d{2}):(\d{2}):(\d{2})\s+          # time of day
            (\d{4})                             # year
        \s*$/x );
    return mktime($sec, $min, $hour, $mday, $months{$mon}, $year - 1900);
}

# EOF


Gebruiksvoorbeeld:
Perl:
1
2
3
4
use timec;
my $timestamp = timec('Thu Oct 13 04:54:34 1994');
exit 1 unless $timestamp;
print $timestamp,"\n", scalar POSIX::localtime($timestamp),"\n";
Maar eigenlijk wil ik nog steeds een standaardfunctie gebruiken! Ik sta dus nog steeds open voor suggesties.

edit:
Is die stomme code formatting bug nou nog niet gefixed?! Als het niet Mozilla maar Internet Explorer zou zijn die de fout in ging, dan zou er allang omheen gewerkt zijn. :(

[ Voor 43% gewijzigd door Soultaker op 17-07-2003 01:53 ]


  • phreggle
  • Registratie: Juni 2002
  • Niet online
Inderdaad werk ik met linux en er zijn wel vaker verschillen geweest tussen de linux en FreeBSD implementatie van date, (zie ook hier).

Overigens heb ik je code ff getest en hij werkt netjes. Ik vond die '$year - 1900' wel eng, maar dat hoort dus zo schijnbaar volgens de uitleg van mktime(), (wist ik niet :D ).