将小时字段递增 5(UTC 到 EST 格式)



我有一个包含数千条记录的文件。每行应具有一个或多个 UTC 格式的日期时间字段。

我需要将日期和时间字段转换为 EST 格式:在小时字段中添加 +5,如果它大于 24,日期也应该更改。

例如:

输入:

123456|2016-03-10T14:30:25.000|abcd|efdgh|1245|2016-03-10T23:30:25.000
654321|2016-03-10T20:30:25.000|abcd|efdgh|1245|2016-03-11T04:30:25.000

输出应为:

123456|2016-03-10T19:30:25.000|abcd|efdgh|1245|2016-03-10T14:30:25.000
654321|2016-03-11T01:30:25.000|abcd|efdgh|1245|2016-03-10T19:30:25.000

这是我尝试过的:

# cat f
123456|2016-03-10T14:30:25.000|abcd|efdgh|1245|2016-03-10T23:30:25.000 654321|2016-03-10T20:30:25.000|abcd|efdgh|1245|2016-03-11T04:30:25.000
# awk 'BEGIN {FS = "T";; OFS="T" } $2+=4,$3+=5' f
123456|2016-03-10T18T28 654321|2016-03-10T24T9

我认为你的计算是错误的。您可以通过减去 5 小时而不是添加 5 小时从 UTC 转换为 EST(假设"EST"是指美国东部标准时间)。

这是我的做法。

#!/usr/bin/perl
use strict;
use warnings;
use DateTime::Format::Strptime;
my $fmt = '%Y-%m-%dT%H:%M:%S';
my $dp = DateTime::Format::Strptime->new(
  pattern   => $fmt,
  time_zone => 'UTC',
);
while (<DATA>) {
  s/(d{4}-dd-ddTdd:dd:dd)/change_time($1)/eg;
  print;
}
sub change_time {
  my $time = shift;
  my $dt = $dp->parse_datetime($time);
  $dt->set_time_zone("EST");
  return $dt;
}
__DATA__
123456|2016-03-10T14:30:25.000|abcd|efdgh|1245|2016-03-10T23:30:25.000
654321|2016-03-10T20:30:25.000|abcd|efdgh|1245|2016-03-11T04:30:25.000

运行此程序的输出为:

123456|2016-03-10T09:30:25.000|abcd|efdgh|1245|2016-03-10T18:30:25.000
654321|2016-03-10T15:30:25.000|abcd|efdgh|1245|2016-03-10T23:30:25.000

使用 GNU awk 用于时间函数:

$ cat tst.awk
BEGIN { FS=OFS="|" }
{ $2=upd($2); $6=upd($6); print }
function upd(dt,        a) {
    split(dt,a,/[.]/)
    gsub(/[-T:]/," ",a[1])
    return strftime("%Y-%m-%dT%H:%M:%S",mktime(a[1])+5*60*60) "." a[2]
}
$ awk -f tst.awk file
123456|2016-03-10T19:30:25.000|abcd|efdgh|1245|2016-03-11T04:30:25.000
654321|2016-03-11T01:30:25.000|abcd|efdgh|1245|2016-03-11T09:30:25.000

生命太短,无法手动计算日期和时间。因此,请使用包含时间处理模块的语言。根据你选择的标签,我会选择Perl和DateTime模块。

因此,提取日期字段,然后创建一个 DateTime 对象来执行计算:

use DateTime;
my $date = '2016-03-10T23:30:25.000'
if ($date =~ /(dddd)-(dd)-(dd)T(dd):(dd):(dd)/) {
    my $dt = DateTime->new(year => $1, month => $2, day => $3,
                           hour => $4, minute => $5, second => $6,
                           time_zone => 'UTC');
    $dt->set_time_zone("EST");
    $date = $dt->ymd . "T" . $dt->hms;
} else {
    die "invalid date";
}

这将处理所有角落情况,而不仅仅是用 5 小时抵消。

是的,我知道日期时间不是最快的解决方案。但除非另有证明,否则我认为它应该表现得足够好。

最新更新