我有一个包含数千条记录的文件。每行应具有一个或多个 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 小时抵消。
是的,我知道日期时间不是最快的解决方案。但除非另有证明,否则我认为它应该表现得足够好。