perl datetime format
¿Cómo puedo analizar las fechas relativas con Perl? (4)
Me encantaría saber si hay un módulo para analizar las fechas "con formato humano" en Perl. Quiero decir cosas como "mañana", "martes", "la próxima semana", "1 hora atrás".
Mi investigación con CPAN sugiere que no hay tal módulo, entonces, ¿cómo harías para crear uno? NLP está muy por encima de esto.
Supongo que tienes contexto. ¿Cómo podría ayudar NLP aquí? como adivinanza, podría encontrar la fecha más cercana que sea una fecha exacta (no relativa a hoy) y usar hoy / mañana / ayer para relacionarse con eso.
También puede encontrar interesante mirar la familia DateTime::Format
, específicamente DateTime :: Format :: Natural . una vez que haya analizado su fecha / hora en un objeto DateTime, puede manipularla y evaluarla de muchas maneras diferentes.
aquí hay un programa de muestra:
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";
}
}
salida:
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
Personalmente, siempre he usado Time :: ParseDate para esto. Entiende casi todos los formatos que he probado.
Formatos de fecha absolutos
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)
Formatos de fecha relativos:
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"
Formatos de tiempo absolutos:
hh:mm:ss[.ddd]
hh:mm
hh:mm[AP]M
hh[AP]M
hhmmss[[AP]M]
"noon"
"midnight"
Formatos de tiempo relativos:
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"
Formatos de zona horaria:
[+-]dddd
GMT[+-]d+
[+-]dddd (TZN)
TZN
Formatos especiales:
[ d]d/Mon/yyyy:hh:mm:ss [[+-]dddd]
yy/mm/dd.hh:mm
Date :: Manip hace exactamente esto.
Aquí hay un programa de ejemplo:
#!/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
Lo que resulta en el siguiente resultado:
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 es una de las funciones proporcionadas por Date::Manip
, el primer argumento es una fecha / hora en cualquier formato compatible con el módulo, el segundo argumento describe cómo formatear la fecha / hora. Hay otras funciones que simplemente analizan estas fechas "humanas", sin formatearlas, para usarlas en cálculos delta, etc.