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

时间:2016-03-11 05:46:10

标签: linux perl awk sed

我有一个包含数千条记录的文件。每行应包含一个或多个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

3 个答案:

答案 0 :(得分:1)

我认为你的计算错了。您通过减去五小时从UTC转换为EST,而不是通过添加五小时(假设“EST”表示美国东部标准时间)。

我是这样做的。

parentNode.firstChild

运行它的输出是:

#!/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}-\d\d-\d\dT\d\d:\d\d:\d\d)/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

答案 1 :(得分:1)

使用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

答案 2 :(得分:0)

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

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

use DateTime;
my $date = '2016-03-10T23:30:25.000'
if ($date =~ /(\d\d\d\d)-(\d\d)-(\d\d)T(\d\d):(\d\d):(\d\d)/) {
    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小时内抵消。

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