我在一个正在运行的带有节点的 docker 容器中,由于某种原因,主机的时区/时间与 docker 容器内的时间永远不会对齐:
root@foobar:~# node -e "console.log(new Date())"
>> Tue May 17 2016 15:12:43 GMT+0200 (CEST)
root@foobar:~# docker exec 9179105c0ff9 node -e "console.log(new Date())"
>> Tue May 17 2016 13:13:01 GMT+0000 (Europe)
root@foobar:~# cat /etc/timezone
>> Europe/Vienna
root@foobar:~# docker exec 9179105c0ff9 cat /etc/timezone
>> Europe/Vienna
所以我已经在 docker-start shell 中执行的脚本如下:
docker run \
...
-v /etc/localtime:/etc/localtime:ro \
-v /etc/timezone:/etc/timezone:ro \
-e "TZ=Europe/Vienna" \
...
...但是,正如您在第一个代码块中看到的那样,时间仍然是错误的!对此有什么想法吗?我错过了什么?
(仅供参考:我正在运行通过 mupx 部署的流星应用程序)
更新:
在主机和容器内运行
date
后,再次出现 2 小时的差异。因此,出于某种原因,docker 容器只是不“应用”我的时区,并且 似乎问题与 JS/node 无关,因为 date
只是一个简单的 unix 系统 cmd ...我在这里缺少什么? !
>> Tue May 17 2016 15:12:43 GMT+0200 (CEST)
和
>> Tue May 17 2016 13:13:01 GMT+0000 (Europe)
时间大致相同(大约有 18 秒的差异,因为您没有同时运行命令)。 仔细一看,现在是下午 3 点 GMT+0200 左右,下午 1 点左右 GMT+0000。 这只是输出格式的不同,但时间是一样的。 如果您对
.getTime()
的值执行 new Date()
,您可能会得到相同的值。
这可能是由于不同 Node.js 版本的默认输出格式存在差异。
我是这样做的: args: ["-v /etc/timezone:/etc/timezone:ro","-v /etc/localtime:/usr/share/zoneinfo/Europe/Prague:ro", '-e TZ=Europe/Prague' ]
需要安装timedatectl
在容器中使用 new Date().toString() 时,我很惊讶地发现同样的问题。它始终返回 GMT+000 的字符串,而不返回服务器时区的字符串。可能有特定于容器的设置来更改时区,但由于我知道我的时区 - 纽约,所以我只使用了 toLocaleString: new Date().toLocaleString("en-US", {timeZone: "America/New_York"})
function adjustTimestampWithTimezone(timestamp) {
let timestampInMillis = new Date(timestamp).getTime();
// Get the timezone offset in minutes and convert it to milliseconds
let timezoneOffsetInMillis = new Date().getTimezoneOffset() * 60 * 1000;
// Calculate the adjusted timestamp with timezone
let adjustedTimestamp = (timestampInMillis - timezoneOffsetInMillis) / 1000;
return parseInt(adjustedTimestamp);
}
使用这个独立于docker环境的功能,可以在整个应用程序中保持一致。