Como superar a diferença do TZ em diferentes servidores?

3

Temos alguns servidores em diferentes fusos horários. Nós temos um table.html que contém datas. Queremos ter datas corretas em cada servidor, por isso pensamos que:

- we should convert the time on server "A" to unix time. 
- then on server "B" back from unix time to normal time. 

P: Então, como podemos converter entre as datas normais < - > tempo do unix (então editar o table.html no local?)

servidor "A":

cat table.html
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>2014-05-23-12.23.00.000000</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>2014-05-26-17.00.00.000000</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>NA</td></tr>

servidor "B":

cat table.html
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>1400840580</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>1401116400</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>NA</td></tr>

p .: os servidores não possuem o parâmetro "-d" do comando "date"! talvez perl?
p.s.2: o "X" é um dado censurado, poderia ser qualquer coisa ..
p.3: às vezes não há nenhuma data na sétima coluna, então "NA" é escrito por

UPDATE: tentei uma resposta:

$ cat a.txt 
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>2014-05-23-12.23.00.000000</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>2014-05-26-17.00.00.000000</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>NA</td></tr>
$ 
$ cat b.txt 
#!/usr/bin/env perl
use warnings;
use POSIX;
# Pass the option -i to import from unix time to local time.
# Without the option, export from local time to unix time.
$import = 0;
if (@ARGV && $ARGV[1] eq "-i") {$import = 1}
while (<STDIN>) {
    @F = split m!(<td>.*</td>)!;
    # Field 13 contains a potential date.
    if ($import && $F[13] =~ m!(<td>)([0-9]+)(\.[0-9]*</td>)!) {
    # Import unix time to local time
    ($s,$n,$h,$d,$m,$y,@_tail) = localtime($2);
    $F[13] = sprintf "$1%04d-%02d-%02d-$02d.%02d.%02d$3", $y, $m, $d, $h, $n, $s;
    }
    if (!$import && $F[13] =~ m!(<td>)([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)\.([0-9]+)\.([0-9]+)(\.[0-9]*</td>)!) {
    # Export local time to unix time
    $t = POSIX.mktime($7, $6, $5, $4, $3, $2);
    $F[13] = "$1$t$8";
    }
    $_ = "@F";
}
$ 
$ 
$ perl b.txt a.txt 
Use of uninitialized value $ARGV[1] in string eq at b.txt line 7.

Use of uninitialized value $F[13] in pattern match (m//) at b.txt line 16, <STDIN> line 1.

Use of uninitialized value $F[13] in pattern match (m//) at b.txt line 16, <STDIN> line 2.

Use of uninitialized value $F[13] in pattern match (m//) at b.txt line 16, <STDIN> line 3.
^C
$ 
    
por evachristine 15.04.2014 / 09:45

2 respostas

0

Recomendo sempre armazenar datas GMT ou, se isso for realmente inconveniente, datas com informações de fuso horário. Deixar datas não especificadas não é uma boa ideia.

Se você está preso a esse formato de dados, o Perl é uma boa ferramenta para transformar as datas locais em datas GMT e vice-versa.

Analisar HTML com expressões regulares é uma má ideia em geral , mas tudo bem se o formato de entrada for altamente restrito. Na minha resposta, assumirei que as linhas da tabela estão sempre em uma única linha, como em seu exemplo. Se não estiverem, você provavelmente deve usar um analisador de HTML real - HTML::Parser .

#!/usr/bin/env perl
use warnings;
use POSIX;
# Pass the option -i to import from unix time to local time.
# Without the option, export from local time to unix time.
$import = 0;
if (@ARGV && $ARGV[0] eq "-i") {$import = 1}
while (<STDIN>) {
    @F = split m!(<td>.*</td>)!;
    # Field 13 contains a potential date.
    if ($import && @F >= 13 && $F[13] =~ m!(<td>)([0-9]+)(\.[0-9]*</td>)!) {
        # Import unix time to local time
        ($s,$n,$h,$d,$m,$y,@_tail) = localtime($2);
        $F[13] = sprintf "$1%04d-%02d-%02d-$02d.%02d.%02d$3", $y, $m, $d, $h, $n, $s;
    }
    if (!$import && @F >= 13 && $F[13] =~ m!(<td>)([0-9]+)-([0-9]+)-([0-9]+)-([0-9]+)\.([0-9]+)\.([0-9]+)(\.[0-9]*</td>)!) {
        # Export local time to unix time
        $t = POSIX.mktime($7, $6, $5, $4, $3, $2);
        $F[13] = "$1$t$8";
    }
    $_ = "@F";
}

(Atenção, código não testado!)

    
por 16.04.2014 / 03:03
0

Uma solução perl :

$ perl -MTime::Local -nle 'push @day,$1 if /.*\<td\>(.*)\<\/td\>/;
END {
    for (@day) {
        if (/^\d/) {                                     
            ($y,$m,$d,$h,$mi,$s,@tail) = split("-|\.",$_);
            print timelocal($s,$mi,$h,$d,$m-1,$y);
        }
    }
}' file
1400822580
1401098400

Para alterar o arquivo no local:

$ perl -MTime::Local -i.bak -nle '$date = $1 if /.*\<td\>(.*)\<\/td\>/;
if ($date =~ /^\d/) {
    ($y,$m,$d,$h,$mi,$s,@tail) = split("-|\.",$date);
    $t = timelocal($s,$mi,$h,$d,$m-1,$y);         
    $_ =~ s/$date/$t/e;
}' file
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>1400822580</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>1401098400</td></tr>
<tr><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>X</td><td>NA</td></tr>

Para converter de unixtime para localtime:

$ perl -i -nle '$unixtime = $1 if /.*\<td\>(.*)\<\/td\>/;
    if ($unixtime =~ /\d/) {
        ($s,$mi,$h,$d,$m,$y,@tail) = localtime($unixtime);
        $date = sprintf "%04d-%02d-%02d-%02d.%02d.%04d", $y+1900, $m+1, $d, $h, $mi, $s;
        $_ =~ s/$unixtime/$date/e;
    }
' file
    
por 16.04.2014 / 09:49

Tags