2008-11-17 9 views
10

Ich würde gerne wissen, ob es ein Modul gibt, um "menschliche formatierte" Daten in Perl zu parsen. Ich meine Dinge wie "morgen", "Dienstag", "nächste Woche", "vor 1 Stunde".Wie kann ich relative Daten mit Perl analysieren?

Meine Forschung mit CPAN deutet darauf hin, dass es kein solches Modul gibt. Wie würden Sie also ein solches Modul erstellen? NLP ist dafür weit übertrieben.

Antwort

23

Date::Manip tut genau dies. Hier

ist ein Beispielprogramm:

#!/usr/bin/perl 

use strict; 
use Date::Manip; 

while (<DATA>) 
{ 
    chomp; 
    print UnixDate($_, "%Y-%m-%d %H:%M:%S"), " ($_)\n"; 
} 

__DATA__ 
today 
yesterday 
tomorrow 
last Tuesday 
next Tuesday 
1 hour ago 
next week 

, die in der folgenden Ausgabe führt:

2008-11-17 15:21:04 (today) 
2008-11-16 15:21:04 (yesterday) 
2008-11-18 15:21:04 (tomorrow) 
2008-11-11 00:00:00 (last Tuesday) 
2008-11-18 00:00:00 (next Tuesday) 
2008-11-17 14:21:04 (1 hour ago) 
2008-11-24 00:00:00 (next week) 

UnixDate ist eine der Funktionen, die von Date::Manip vorgesehen ist, das erste Argument ist ein Datum/Zeit in Jedes Format, das das Modul unterstützt, das zweite Argument beschreibt, wie das Datum/die Uhrzeit formatiert wird. Es gibt andere Funktionen, die diese "menschlichen" Daten einfach analysieren, ohne sie zu formatieren, um sie in Delta-Berechnungen usw. zu verwenden.

+1

Ah, gutes altes Datum :: Manip ... Wie kann man ein Modul nicht lieben, die Sie so hart versucht zu sprechen, aus der Verwendung es? –

+0

Genau das, was ich suchte, aber (wie üblich) wusste ich nicht, wie ich die Frage formulieren sollte. Vielen Dank. – andymurd

+0

Ich denke, DateTime ist das, was die Community als eine umfassende Date & Time-Lösung am meisten vorantreibt. Schauen Sie sich datetime.perl.org und diesen Artikel an http://www.perl.com/pub/a/2003/03/13/datetime.html – draegtun

-2

Ich nehme an, Sie haben Kontext. Wie könnte NLP hier helfen? als wilde Vermutung könnten Sie nur das nächste Datum finden, das ein genaues Datum ist (nicht relativ zu heute) und verwenden Sie heute/morgen/gestern, um sich darauf zu beziehen.

9

Sie können es auch interessant finden, um die DateTime::Format Familie, speziell DateTime::Format::Natural zu betrachten. Sobald Sie Ihr Datum/Ihre Zeit in ein DateTime-Objekt geparst haben, können Sie es auf viele verschiedene Arten bearbeiten und auswerten.

hier ist ein Beispielprogramm:

use strict; 
use warnings; 

use DateTime::Format::Natural; 

my($parser) = DateTime::Format::Natural->new; 

while (<>) { 

    chomp; 
    my($dt) = $parser->parse_datetime($_); 

    if ($parser->success) { 

     print join(' ', $dt->ymd, $dt->hms) . "\n"; 
    } 
    else { 

     print $parser->error . "\n"; 
    } 
} 

Ausgang:

tomorrow 
2008-11-18 21:48:49 
next Tuesday 
2008-11-25 21:48:53 
1 week from now 
2008-11-24 21:48:57 
1 hour ago 
2008-11-17 20:48:59 

TMTOWTDI :)

-Steve

+0

Danke, dass Sie DateTime vorgeschlagen haben. Yay, ein wahres System! – Anirvan

2

Persönlich habe ich immer Time::ParseDate zum Einsatz. Es versteht so ziemlich jedes Format, das ich ausprobiert habe.

Absolute Datumsformate

Dow, dd Mon yy 
    Dow, dd Mon yyyy 
    Dow, dd Mon 
    dd Mon yy 
    dd Mon yyyy 
    Month day{st,nd,rd,th}, year 
    Month day{st,nd,rd,th} 
    Mon dd yyyy 
    yyyy/mm/dd 
    yyyy-mm-dd  (usually the best date specification syntax) 
    yyyy/mm 
    mm/dd/yy 
    mm/dd/yyyy 
    mm/yy 
    yy/mm  (only if year > 12, or > 31 if UK) 
    yy/mm/dd (only if year > 12 and day < 32, or year > 31 if UK) 
    dd/mm/yy (only if UK, or an invalid mm/dd/yy or yy/mm/dd) 
    dd/mm/yyyy (only if UK, or an invalid mm/dd/yyyy) 
    dd/mm  (only if UK, or an invalid mm/dd) 

Relative Datumsformate:

count "days" 
    count "weeks" 
    count "months" 
    count "years" 
    Dow "after next" 
    Dow "before last" 
    Dow      (requires PREFER_PAST or PREFER_FUTURE) 
    "next" Dow 
    "tomorrow" 
    "today" 
    "yesterday" 
    "last" dow 
    "last week" 
    "now" 
    "now" "+" count units 
    "now" "-" count units 
    "+" count units   
    "-" count units 
    count units "ago" 

Absolute Zeitformate:

hh:mm:ss[.ddd] 
    hh:mm 
    hh:mm[AP]M 
    hh[AP]M 
    hhmmss[[AP]M] 
    "noon" 
    "midnight" 

Relative Zeitformate:

count "minutes"   (count can be franctional "1.5" or "1 1/2") 
    count "seconds" 
    count "hours" 
    "+" count units 
    "+" count 
    "-" count units 
    "-" count 
    count units "ago" 

Zeitzone Formate:

[+-]dddd 
    GMT[+-]d+ 
    [+-]dddd (TZN) 
    TZN 

Sonderformate:

[ d]d/Mon/yyyy:hh:mm:ss [[+-]dddd] 
    yy/mm/dd.hh:mm 
Verwandte Themen