将小时添加到日期和时间

将小时添加到日期和时间

我需要将偏移时间添加到日期时间值。

  1. 获取前一个日期(例如2023-10-19 00:00:00.000000

    previous_date=`TZ=TZ+24 date '+%Y-%m-%d 00:00:00.000000'`
    
  2. 计算时区偏移量(以小时为单位)并获取其绝对值(例如东部夏令时的 4 小时)

    offset_hours=$(date '+%:z' | sed 's/[-+]\(.*\)/\1/' | awk -F: '{print int($1 * 3600 + $2 * 60 + $3) / 3600}')
    
  3. 添加偏移小时数并获取调整后的开始日期(例如 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.000000America/New_York时区中会发生两次(2023-11-05 05:23:00.000000 UTC 和 2023-11-05 06:23:00.000000 UTC)。

相关内容