Linux date 命令自动为每个日期时间增加 10 小时

Linux date command adds 10 hours to every datetime automatically

如果我输入 date +"%Y/%m/%d %H:%M" -d "20200819T1234",预期输出是 2020/08/19 12:34,而我实际得到 2020/08/19 02:34,也就是说,少了整整 10 个小时。有人可以向我解释为什么会这样吗? 目前我在命令末尾使用 + 10 hours 进行管理,但我认为这不正常。服务器上设置的时区是-03所以我很困惑。
Ubuntu 16 和 Debian 10

都会发生这种情况

您的格式与时间字符串不匹配:试试

date +"%Y/%m/%d %H:%M" -d "2020/08/19 12:34"

2020/08/1912:34

用于解析日期的 GNU 代码 (parse_datetime2) 中嵌入了这个 table,它提供了您得到错误时间的原因(为简洁起见进行了修剪):

/* Military time zone table.

    Note 'T' is a special case, as it is used as the separator in ISO
          8601 date and time of day representation. */

static table const military_table[] =
{
    { "A", tZONE, -HOUR ( 1) },
    { "B", tZONE, -HOUR ( 2) },
    { "C", tZONE, -HOUR ( 3) },
              :  :  :
    { "Y", tZONE,  HOUR (12) },
    { "Z", tZONE,  HOUR ( 0) },
    { NULL, 0, 0 }
};

而且,实际上,如果您 运行 date 在调试模式下,您可以看到发生了什么(为简洁起见,对输出进行了修整):

pax> for i in {A..I} {K..Z} ; do
...>     date -d $i --debug 2>&1 | awk -vZ=$i '/parsed zone/{print "  "Z":"}'
...> done
  A:UTC-01
  B:UTC-02
    :  :
  T:UTC+07
    :  :
  Z:UTC+00

大多数字母应用基于 military timezones 的时区偏移,因此通常 用于分隔 ISO 格式的日期和时间的 T 是此处的处理方式不同,指定 UTC+7,解释了 ten-hour 与服务器 UTC-3.

之间的区别

底线是您需要使用接受table 到date 的输入格式。这就像(在本例中)根据以下记录将 T 替换为 space 一样简单:

pax:~> ### First, the problematic one.
pax:~> date +"%Y/%m/%d %H:%M" -d "20200819T1234" --debug
date: parsed number part: (Y-M-D) 2020-08-19
date: parsed zone part: UTC+07
date: parsed number part: 12:34:00
date: input timezone: parsed date/time string (+07)
date: using specified time as starting value: '12:34:00'
date: starting date/time: '(Y-M-D) 2020-08-19 12:34:00 TZ=+07'
date: '(Y-M-D) 2020-08-19 12:34:00 TZ=+07' = 1597815240 epoch-seconds
date: timezone: system default
date: final: 1597815240.000000000 (epoch-seconds)
date: final: (Y-M-D) 2020-08-19 05:34:00 (UTC)
date: final: (Y-M-D) 2020-08-19 13:34:00 (UTC+08)
2020/08/19 13:34

pax:~> ### Then, the correct one.
pax:~> date +"%Y/%m/%d %H:%M" -d "20200819 1234" --debug
date: parsed number part: (Y-M-D) 2020-08-19
date: parsed number part: 12:34:00
date: input timezone: system default
date: using specified time as starting value: '12:34:00'
date: starting date/time: '(Y-M-D) 2020-08-19 12:34:00'
date: '(Y-M-D) 2020-08-19 12:34:00' = 1597811640 epoch-seconds
date: timezone: system default
date: final: 1597811640.000000000 (epoch-seconds)
date: final: (Y-M-D) 2020-08-19 04:34:00 (UTC)
date: final: (Y-M-D) 2020-08-19 12:34:00 (UTC+08)
2020/08/19 12:34