我需要将偏移时间添加到日期时间值。
获取前一个日期(例如
2023-10-19 00:00:00.000000
)previous_date=`TZ=TZ+24 date '+%Y-%m-%d 00:00:00.000000'`
计算时区偏移量(以小时为单位)并获取其绝对值(例如东部夏令时的 4 小时)
offset_hours=$(date '+%:z' | sed 's/[-+]\(.*\)/\1/' | awk -F: '{print int($1 * 3600 + $2 * 60 + $3) / 3600}')
添加偏移小时数并获取调整后的开始日期(例如 2023-10-19 04:00:00.000000000)
startdateandtime=$(TZ="UTC" date -d "$previous_date $offset_hours hours" '+%Y-%m-%d %H:%M:%S.%N')
前 2 个命令在 AIX 上工作,但在 Linux 上工作的第三个命令在 AIX 上失败。需要帮助来实现这一点并使第三个命令在 AIX 上运行。
谢谢
答案1
听起来您想将时间戳从一个时区转换为另一个时区。
添加固定偏移量并不是正确的方法,因为偏移量会在一年中因 DST 而在许多时区发生变化,并且还会随着政府的突发奇想而变化,政府可能决定停止 DST,或与 DST 保持一致(或被并入)另一个国家...
例如,在美国纽约,添加/删除 4 小时以转换为 UTC 或从 UTC 转换的时间可能在 2023 年 10 月 19 日有效,但在 2023 年 12 月就不再有效,并且在 2030 年 10 月也可能不再有效。
在解析 的输出的方法中date +%:z
,您从时区数据库获取偏移量,但您获取的是当前时间,而不是您尝试转换的时间戳的偏移量,这也是无效的。
从 UTC 时间转换为本地时间
使用 GNU date
,你会这样做:
$ export TZ=America/New_York
$ date -d '2023-10-19 00:00:00.000000 +0000' '+%F %T.%6N'
2023-10-18 20:00:00.000000
可移植的是,您可以使用perl
:
perl -MPOSIX -MTime::Piece -le '
$format = "%Y-%m-%d %H:%M:%S";
for (@ARGV) {
s{[^.]*}{
$t = Time::Piece->strptime($&, $format);
strftime($format, localtime $t->epoch)
}e;
print;
}' '2023-10-19 00:00:00.000000'
在 AIX 上,您应该能够使用 ksh93 的printf
内置命令:
printf '%(%F %T.%6N)T\n' '2023-10-19 00:00:00.000000 +0000'
或者使用 zsh(如果可用):
zmodload zsh/datetime
datetime='2023-10-19 00:00:00.000000'
format='%Y-%m-%d %H:%M:%S'
TZ=UTC0 strftime -rs epoch $format ${datetime%.*} &&
strftime -s t $format $epoch &&
print -r -- $t${(M)datetime%.*}
从本地时间 1 转换为 UTC 时间
和zsh
:
zmodload zsh/datetime
datetime='2023-10-19 00:00:00.000000'
format='%Y-%m-%d %H:%M:%S'
strftime -rs epoch $format ${datetime%.*} &&
TZ=UTC0 strftime -s t $format $epoch &&
print -r -- $t${(M)datetime%.*}
使用 ksh93:
datetime='2023-10-19 00:00:00.000000'
format='%Y-%m-%d %H:%M:%S.%6N'
t=${ printf '%(%s)T' "$datetime"; } &&
TZ=UTC0 printf "%($format)T\n" "#$t"
和perl
:
perl -MPOSIX -le '
$format = "%Y-%m-%d %H:%M:%S";
for (@ARGV) {
if (/^(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)(.*)/) {
print strftime($format, gmtime(mktime($6,$5,$4,$3,$2-1,$1-1900))) . $7;
}
}' '2023-10-19 00:00:00.000000'
使用 GNU date
:
t=$(date -d '2023-10-19 00:00:00.000000' +%s.%N) &&
TZ=UTC0 date -d "@$t" '+%F %T.%6N'
在America/New_York
时区中,他们给出2023-10-19 04:00:00.000000
.
任意时区之间
上述方法可以轻松地适应任意时区之间的转换。您只需TZ
对解析输入日期的命令( ksh93 中的strftime -r
,date -d
, first printf
)和格式化输出日期的命令(strftime
, date
, secondary printf
)进行适当的设置。
使用perl
,您可以TZ
在解析和格式化之前设置环境变量:
perl -MPOSIX -le '
$format = "%Y-%m-%d %H:%M:%S";
for (@ARGV) {
if (/^(\d+)-(\d+)-(\d+) (\d+):(\d+):(\d+)(.*)/) {
$ENV{TZ} = "America/New_York";
my $t = mktime($6,$5,$4,$3,$2-1,$1-1900);
$ENV{TZ} = "Asia/Kolkata";
print strftime($format, localtime($t)) . $7;
}
}' '2023-10-19 00:00:00.000000'
1 尽管本地时间格式不明确,因为它缺少 DST 信息,因此无法可靠地完成转换。例如,2023-11-05 01:23:00.000000
在America/New_York
时区中会发生两次(2023-11-05 05:23:00.000000 UTC 和 2023-11-05 06:23:00.000000 UTC)。