2008-11-17 10 views
10

Chciałbym wiedzieć, czy istnieje moduł do analizy danych "sformatowanych w ludzkim" w języku Perl. Mam na myśli rzeczy takie jak "jutro", "wtorek", "następny tydzień", "1 godzina temu".Jak analizować względne daty za pomocą języka Perl?

Moje badania z CPAN sugerują, że nie ma takiego modułu, więc jak byś go zaprojektował? NLP jest o to za daleko.

Odpowiedz

23

robi dokładnie to.

Oto przykładowy program:

#!/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 

co powoduje następujące dane wyjściowe:

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 jest jedną z funkcji oferowanych przez Date::Manip, pierwszy argument jest data/czas w dowolny format wspierany przez moduł, drugi argument opisuje sposób formatowania daty/czasu. Istnieją inne funkcje, które analizują te "ludzkie" daty, bez formatowania, do wykorzystania w obliczeniach delta, itp.

+1

Ach, stare dobre Date :: Manip ... Jak można nie kochać moduł, który próbuje więc trudno mówić cię z użyciem to? –

+0

Dokładnie tego, czego szukałem, ale (jak zwykle) nie wiedziałem, jak sformułować pytanie. Dzięki. – andymurd

+0

Myślę, że DateTime jest tym, co społeczność teraz najbardziej naciska jako kompleksowe rozwiązanie Date & Time. Sprawdź datetime.perl.org i ten artykuł http://www.perl.com/pub/a/2003/03/13/datetime.html – draegtun

-2

Zakładam, że masz kontekst. W jaki sposób NLP może tu pomóc? jak na dzikie domysły, można znaleźć najbliższy termin, który jest dokładną datą (nie w stosunku do dnia dzisiejszego) i użyć dzisiaj/jutro/wczoraj, aby się do tego odnosić.

9

możesz również uznać za interesujące przyjrzeć się rodzinie DateTime::Format, a konkretnie DateTime::Format::Natural. po sparsowaniu daty/czasu w obiekcie DateTime można nim manipulować i oceniać na wiele różnych sposobów.

oto przykładowy program:

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"; 
    } 
} 

wyjściowa:

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

Dzięki za sugestię DateTime. Yay, One True Systems! – Anirvan

2

Osobiście zawsze używany Time::ParseDate do tego. Rozumie praktycznie każdy wypróbowany format.

Bezwzględne formaty daty

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) 

Względne formaty daty:

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" 

Bezwzględne formaty czasu:

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

Względne formaty czasu:

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" 

formaty Strefa czasowa:

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

Specjalne formaty:

[ d]d/Mon/yyyy:hh:mm:ss [[+-]dddd] 
    yy/mm/dd.hh:mm 
Powiązane problemy