Como faço para converter uma data / hora de tempo de época (tempo de unix / segundos desde 1970) em Perl?

StackOverflow https://stackoverflow.com/questions/95492

Pergunta

Dada uma data / hora como uma matriz de (ano, mês, dia, hora, minuto, segundo), como você convertê-lo em tempo de época, ou seja, o número de segundos desde 1970-01-01 00:00 : 00 GMT

Bônus pergunta:? Se lhe for dada a data / hora como uma seqüência, como você primeiro analisá-lo para o (y, m, d, h, m, s) array

Foi útil?

Solução 2

Esta é a maneira mais simples de obter uma hora Unix:

use Time::Local;
timelocal($second,$minute,$hour,$day,$month-1,$year);

Observe a ordem inversa dos argumentos e que janeiro é mês 0. Para muitas mais opções, veja o DateTime módulo do CPAN.

Como para análise, consulte a Data :: módulo Parse do CPAN. Se você realmente precisa para começar a fantasia com a data de análise, a Date :: Manip pode ser útil, embora a sua própria documentação avisa longe dele, uma vez que carrega muita bagagem (ela sabe coisas como feriados comuns de negócios, por exemplo) e outras soluções são muito mais rápidos.

Se acontecer de você saber algo sobre o formato da data / vezes você vai ser analisar, em seguida, uma expressão regular pode ser suficiente, mas você é provavelmente melhor fora de usar um módulo CPAN apropriado. Por exemplo, se você sabe as datas será sempre em ordem YMDHMS, usar o CPAN módulo DateTime: :. Format :: ISO8601


Para a minha própria referência, se nada mais, abaixo é um uso I função para uma aplicação onde eu sei as datas será sempre em ordem YMDHMS com todo ou parte do "HMS" parte opcional. Ele aceita qualquer tipo de delimitadores (por exemplo, "2009-02-15" ou "2009.02.15"). Ele retorna o tempo unix correspondente (segundos desde 1970-01-01 00:00:00 GMT) ou -1 se não pudesse analisá-lo (o que significa que é melhor ter certeza de que você precisará nunca mais legitimamente para analisar a data 1969- 12-31 23:59:59). É também presume anos de dois dígitos XX até "69" referem-se a "20XX", de outro modo "19XX" (por exemplo, "50-02-15" significa 2050-02-15 mas "75-02-15" significa 1975- 02-15).

use Time::Local;

sub parsedate { 
  my($s) = @_;
  my($year, $month, $day, $hour, $minute, $second);

  if($s =~ m{^\s*(\d{1,4})\W*0*(\d{1,2})\W*0*(\d{1,2})\W*0*
                 (\d{0,2})\W*0*(\d{0,2})\W*0*(\d{0,2})}x) {
    $year = $1;  $month = $2;   $day = $3;
    $hour = $4;  $minute = $5;  $second = $6;
    $hour |= 0;  $minute |= 0;  $second |= 0;  # defaults.
    $year = ($year<100 ? ($year<70 ? 2000+$year : 1900+$year) : $year);
    return timelocal($second,$minute,$hour,$day,$month-1,$year);  
  }
  return -1;
}

Outras dicas

Se você estiver usando o DateTime módulo, você pode chamar o época () método em um objeto DateTime, já que é o que você pensa como o tempo unix

Usando DateTimes lhe permite converter facilmente de época, aos objetos de data.

Alternativly, localtime e gmtime irá converter uma época em uma matriz contendo mês dia e ano, e timelocal e timegm do Time :: módulo local fará o oposto, conversão de um conjunto de elementos de tempo (segundos, minutos, ..., dias, meses etc.) em uma época.

Para analisar uma data, olhada Date :: Parse no CPAN.

$ENV{TZ}="GMT";
POSIX::tzset();
$time = POSIX::mktime($s,$m,$h,$d,$mo-1,$y-1900);

Eu sei que isto é uma questão de idade, mas pensei que eu iria oferecer uma outra resposta.

Time::Piece é o núcleo a partir de Perl 5.9.5

Isto permite a análise de tempo em formatos arbitrários através do método strptime.

por exemplo:.

my $t = Time::Piece->strptime("Sunday 3rd Nov, 1943",
                              "%A %drd %b, %Y");

A parte útil é -. Porque é um objeto sobrecarregado, você pode usá-lo para comparações numéricas

por exemplo.

if ( $t < time() ) { #do something }

Ou se você acessá-lo em um contexto string:

print $t,"\n"; 

Você recebe:

Wed Nov  3 00:00:00 1943

Há um monte de métodos de acesso que permitem a alguns variados de outras transformações baseadas em tempo útil. https://metacpan.org/pod/Time::Piece

Get Date :: Manip do CPAN , então:

use Date::Manip;
$string = '18-Sep-2008 20:09'; # or a wide range of other date formats
$unix_time = UnixDate( ParseDate($string), "%s" );

edit:

Date :: Manip é grande e lento, mas muito flexível na análise, e é pura perl. Usá-lo se você estiver com pressa quando você está escrevendo código, e você sabe que não vai estar em uma pressa quando você está executando-o.

por exemplo. Use-o para analisar opções de linha de comando uma vez no start-up, mas não usá-lo analisar grandes quantidades de dados em um servidor web ocupado.

Consulte os comentários autores .

(graças ao autor do primeiro comentário abaixo)

O meu analisador de data e hora favorita é DateTime :: Format :: ISO8601 uma vez que você tem que trabalhar, você terá um objeto DateTime, facilmente convertível para segundos marcaram época com época ()

Existem muitos módulos Data de manipulação no CPAN. Meu favorito é DateTime e você pode usar o strptime módulos para analisar as datas em formatos arbitrários. Há também muitos módulos de DateTime :: Format no CPAN para lidar com formatos de data especializados, mas strptime é o mais genérico.

Para referência, um revestimento que pode ser aplicado em, por exemplo, os scripts !#/bin/sh.

EPOCH="`perl -e 'use Time::Local; print timelocal('${SEC}','${MIN}','${HOUR}','${DAY}','${MONTH}','${YEAR}'),\"\n\";'`"

Apenas lembre-se de evitar valores octais!

Possivelmente um dos melhores exemplos de 'Há mais de uma maneira de fazê-lo", com ou sem a ajuda do CPAN.

Se você tem controle sobre o que se passou como uma 'data / hora', eu sugiro ir a DateTime rota , usando uma data específica :: subclasse Tempo :: Format, ou usando DateTime :: Format :: strptime se não houver um suporte o formato da data maluco (veja o datetime FAQ para mais detalhes). Em geral, Data :: O tempo é o caminho a percorrer se você quiser fazer alguma coisa séria com o resultado:. Poucas aulas sobre CPAN são tão anal-retentiva e obsessivamente precisa

Se você está esperando coisas de forma livre estranho, jogá-lo em Date :: Parse 's método str2time (), which'll obter um valor época segundos desde-que você pode então ter o seu caminho perverso com, sem a sobrecarga de Date :: Manip .

Um filtro de conversão de todas as datas em vários formatos ISO-relacionado (e que usaria qualquer outra coisa depois de ler os escritos do Poderoso Kuhn) na entrada padrão para segundos-desde-the-época vez na saída padrão pode servir para ilustrar as duas partes:?

martind@whitewater:~$ cat `which isoToEpoch`
#!/usr/bin/perl -w
use strict;
use Time::Piece;
# sudo apt-get install libtime-piece-perl
while (<>) {
  # date --iso=s:
  # 2007-02-15T18:25:42-0800
  # Other matched formats:
  # 2007-02-15 13:50:29 (UTC-0800)
  # 2007-02-15 13:50:29 (UTC-08:00)
  s/(\d{4}-\d{2}-\d{2}([T ])\d{2}:\d{2}:\d{2})(?:\.\d+)? ?(?:\(UTC)?([+\-]\d{2})?:?00\)?/Time::Piece->strptime ($1, "%Y-%m-%d$2%H:%M:%S")->epoch - (defined ($3) ? $3 * 3600 : 0)/eg;
  print;
}
martind@whitewater:~$ 

Se você está apenas à procura de um utilitário de linha de comando (ou seja, não é algo que será chamado de outras funções), experimentar este script. Assume-se a existência de data GNU (presente em praticamente qualquer sistema Linux):

#! /usr/bin/perl -w

use strict;

$_ = (join ' ', @ARGV);
$_ ||= <STDIN>;

chomp;

if (/^[\d.]+$/) {
    print scalar localtime $_;
    print "\n";
}
else {
    exec "date -d '$_' +%s";
}

Eis como funciona:

$ Time now
1221763842

$ Time yesterday
1221677444

$ Time 1221677444
Wed Sep 17 11:50:44 2008

$ Time '12:30pm jan 4 1987'
536790600

$ Time '9am 8 weeks ago'
1216915200
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top