2012-02-03 16 views
10

En un programa Perl que tiene una variable que contiene la fecha/hora en este formato:diferencia de tiempo en segundos

Feb 3 12:03:20 

necesito para determinar si esa fecha es más de x segundo edad (basado en la hora actual), incluso si esto ocurre durante la medianoche (por ejemplo, Feb 3 23:59:00 con la hora actual = Feb 4 00:00:30).

La información de fecha/hora de perl que he encontrado es alucinante. Cerca de lo que puedo decir Necesito usar Date::Calc, pero no estoy encontrando un delta de segundos. Gracias :)

Respuesta

3

En Perl, siempre hay más de una forma de hacer algo. Aquí está uno que utiliza sólo un módulo que viene de serie con Perl:

#! perl -w 

use strict; 
use Time::Local; 

my $d1 = "Feb 3 12:03:20"; 
my $d2 = "Feb 4 00:00:30"; 

# Your date formats don't include the year, so 
# figure out some kind of default. 
use constant Year => 2012; 


# Convert your date strings to Unix/perl style time in seconds 
# The main problems you have here are: 
# * parsing the date formats 
# * converting the month string to a number from 1 to 11 
sub convert 
{ 
    my $dstring = shift; 

    my %m = ('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 ($dstring =~ /(\S+)\s+(\d+)\s+(\d{2}):(\d{2}):(\d{2})/) 
    { 
     my ($month, $day, $h, $m, $s) = ($1, $2, $3, $4, $5); 
     my $mnumber = $m{$month}; # production code should handle errors here 

     timelocal($s, $m, $h, $day, $mnumber, Year - 1900); 
    } 
    else 
    { 
     die "Format not recognized: ", $dstring, "\n"; 
    } 
} 

my $t1 = convert($d1); 
my $t2 = convert($d2); 

print "Diff (seconds) = ", $t2 - $t1, "\n"; 

Para hacer esto realmente listo para la producción, se necesita un mejor manejo del año (por ejemplo, ¿qué ocurre cuando la fecha de inicio es en diciembre y finales ¿Fecha en enero?) y un mejor manejo de errores (por ejemplo, ¿qué sucede si la abreviatura de 3 caracteres del mes está mal escrita?).

+0

wow ... mucho más complicado de lo que esperaba ... gracias –

+2

@xivix, es innecesariamente complicado para lo que quieres. [la respuesta de vmpstr] (http://stackoverflow.com/a/9134822/132382) es totalmente factible aquí. – pilcrow

+0

Todo depende de la cantidad de módulos que pueda o quiera usar. Vea la respuesta por @vmpstr, usando Date :: Parse. Si la instalación de ese módulo es aceptable, adelante. Es probable que esté haciendo un mejor trabajo manejando diferentes formatos de datos y posibles errores que este breve fragmento de código. – theglauber

9

Parece haber una conveniente Date::Parse. Aquí está el ejemplo:

use Date::Parse; 

print str2time ('Feb 3 12:03:20') . "\n"; 

Y esto es lo que da salida:

$ perl test.pl 
1328288600 

que es: Fri Feb 3 12:03:20 EST 2012

No estoy seguro de cómo decente el análisis es, pero analiza el ejemplo que se acaba bien :)

+0

¿cómo obtendría la fecha actual en el mismo formato para comparar? localtime (tiempo) da un número mucho más largo. –

+0

@xivix: No necesita 'localtime', simplemente use' time': devuelve una marca de tiempo Unix (segundos desde el 1 de enero de 1970 00:00:00 UTC), al igual que 'str2time'. –

+0

Afortunadamente para sus necesidades, perl usa la convención de Unix de medir el tiempo en segundos desde el 1 de enero de 1970, por lo que la salida de str2parse anterior ya está en segundos, y puede hacer los cálculos. – theglauber

2

Suponiendo que desea utilizar Date::Calc, convierta los dos valores a valores de "tiempo" con Date_to_Time y s ubtra los valores para obtener la diferencia en segundos. Pero para hacer esto, debe convertir primero las cadenas a los valores YY MM DD hh mm ss para pasar primero al Date_to_Time.

6

En el espíritu de TMTOWTDI, puede aprovechar el núcleo Time::Piece:

#!/usr/bin/env perl 
use strict; 
use warnings; 
use Time::Piece; 
my $when = "@ARGV" or die "'Mon Day HH:MM:SS' expected\n"; 
my $year = (localtime)[5] + 1900; 
my $t = Time::Piece->strptime($year . q() . $when, "%Y %b %d %H:%M:%S"); 
print "delta seconds = ", time() - $t->strftime("%s"),"\n"; 

$ ./mydelta Feb 3 12:03:20

delta seconds = 14553 

El año en curso se asume y toma de tu tiempo local

+1

No estoy seguro de por qué, pero '$ t-> epoch' funciona mientras' $ t-> strftime ("% s") 'no – Zaid

+0

@Zaid Qué versión de [Tiempo :: Pieza] (https: // metacpan. org/changes/distribution/Time-Piece) ¿estás usando? Parece que 1.20 agregó soporte 'strftime' para'% s'. – JRFerguson

+0

$ t-> epoch parece usar alguna configuración de localización de la que no tengo conocimiento. En mi caso, 'epoch' devuelve el valor de zona horaria EDT, mientras que en realidad estoy en JST (hora de Japón). Sin embargo, 'strftime ("% s ")' devuelve el valor correcto en segundos (JST), que es coherente con 'time()'. – lepe

18
#!/usr/bin/perl 

$Start = time(); 
sleep 3; 
$End = time(); 
$Diff = $End - $Start; 

print "Start ".$Start."\n"; 
print "End ".$End."\n"; 
print "Diff ".$Diff."\n"; 

Esta es una manera simple de encontrar la diferencia de tiempo en segundos.

+0

Esto no responde la pregunta en absoluto, que se trata de comparar los tiempos en dos variables. – RichVel

+0

Cierto, PERO permite ... a.) La persona que hizo la pregunta original para considerar un enfoque diferente, que puede ser más simple que su forma original; b.) Otras personas encuentran esta página a través de una búsqueda web para medir fácilmente los segundos transcurridos. Pertenezco a este último, y me gusta mucho el ejemplo de Sjoerd. Simple, y no tiene dependencias. Justo lo que estaba buscando. – Keve

Cuestiones relacionadas