Perl
如何克服不同伺服器上的 TZ 差異?
我們在不同的時區有幾台伺服器。我們有一個包含日期的 table.html。我們希望在每個伺服器中都有正確的日期,所以我們認為:
- we should convert the time on server "A" to unix time. - then on server "B" back from unix time to normal time.
**問:**那麼,我們如何在正常日期<->unix 時間之間進行轉換(所以就地編輯 table.html?)
伺服器“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>
伺服器“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>
ps:伺服器沒有“date”命令的“-d”參數!也許perl?
ps2:“X”是刪減數據,可以是任何東西..
ps3:有時第7列沒有任何日期,然後寫“NA”
更新:我嘗試了一個答案:
$ 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 $
我建議始終儲存 GMT 日期,或者如果這確實是帶有時區資訊的不方便日期。留下未指定的日期不是一個好主意。
如果您不喜歡這種數據格式,Perl 是一個很好的工具,可以將本地日期轉換為 GMT 日期並返回。
用正則表達式解析 HTML 通常是個壞主意,但如果輸入格式受到高度限制,也可以。在我的回答中,我假設表格行總是在一行上,就像你的例子一樣。如果不是,您可能應該使用實際的 HTML 解析器 -
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"; }
(警告,未經測試的程式碼!)