go 时间:欧洲/都柏林时区中,IST解析错误

mccptt67  于 4个月前  发布在  Go
关注(0)|答案(8)|浏览(72)

你正在使用的Go版本是什么(go version)?

$ go version
go version go1.13.4 linux/amd64

这个问题在最新版本的发布中是否重现?

你正在使用什么操作系统和处理器架构(go env)?
go env
GOARCH="amd64" GOHOSTARCH="amd64" GOHOSTOS="linux" GOOS="linux" GOPROXY="https://proxy.golang.org,direct" GOSUMDB="sum.golang.org" GCCGO="gccgo" AR="ar" CC="clang" CXX="clang++" CGO_ENABLED="1" GOMOD="" CGO_CFLAGS="-g -O2" CGO_CPPFLAGS="" CGO_CXXFLAGS="-g -O2" CGO_FFLAGS="-g -O2" CGO_LDFLAGS="-g -O2" PKG_CONFIG="pkg-config" GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build876647815=/tmp/go-build -gno-record-gcc-switches"

$ go env

你做了什么?
我编写了一个解析器来解析欧洲/都柏林的3个字母时区时间。我尝试了IST/GMT/UTC/BST的各种变体。除了夏令时关闭时的IST之外,所有这些都可以正常工作。请参阅示例代码: https://play.golang.org/p/3iNUKCLFC2l

你期望看到什么?
IST应该像BST一样或者至少不会被部分解析为不存在的偏移量。
2020-01-12 09:30 IST应该等于2020-01-12 08:30:00 +0000 GMT

你看到了什么?
2020-01-12 09:30 IST被解析为2020-01-12 08:55:21 +0000 GMT

k3fezbri

k3fezbri1#

当我选择夏令时实际生效的时间时,这确实可以正常工作。例如,将月份更改为6月。

qgzx9mmu

qgzx9mmu2#

一位同事向我指出了这个问题。从tzdata2019c, europe, line 529+:

# The following is like GB-Eire and EU, except with standard time in
# summer and negative daylight saving time in winter.  It is for when
# negative SAVE values are used.
# Rule	NAME	FROM	TO	TYPE	IN	ON	AT	SAVE	LETTER/S
Rule	Eire	1971	only	-	Oct	31	 2:00u	-1:00	-
Rule	Eire	1972	1980	-	Mar	Sun>=16	 2:00u	0	-
Rule	Eire	1972	1980	-	Oct	Sun>=23	 2:00u	-1:00	-
Rule	Eire	1981	max	-	Mar	lastSun	 1:00u	0	-
Rule	Eire	1981	1989	-	Oct	Sun>=23	 1:00u	-1:00	-
Rule	Eire	1990	1995	-	Oct	Sun>=22	 1:00u	-1:00	-
Rule	Eire	1996	max	-	Oct	lastSun	 1:00u	-1:00	-

# Zone	NAME		STDOFF	RULES	FORMAT	[UNTIL]
Zone	Europe/Dublin	-0:25:00 -	LMT	1880 Aug  2
			-0:25:21 -	DMT	1916 May 21  2:00s
			-0:25:21 1:00	IST	1916 Oct  1  2:00s
			 0:00	GB-Eire	%s	1921 Dec  6 # independence
			 0:00	GB-Eire	GMT/IST	1940 Feb 25  2:00s
			 0:00	1:00	IST	1946 Oct  6  2:00s
			 0:00	-	GMT	1947 Mar 16  2:00s
			 0:00	1:00	IST	1947 Nov  2  2:00s
			 0:00	-	GMT	1948 Apr 18  2:00s
			 0:00	GB-Eire	GMT/IST	1968 Oct 27
# The next line is for when negative SAVE values are used.
			 1:00	Eire	IST/GMT
# These three lines are for when SAVE values are always nonnegative.
#			 1:00	-	IST	1971 Oct 31  2:00u
#			 0:00	GB-Eire	GMT/IST	1996
#			 0:00	EU	GMT/IST

看起来偏移量来自于曾经存在DMT的时候。

v7pvogib

v7pvogib4#

Go的时间包只是简单地反映了本地系统的时区数据。就我所知,这就是发生在这里的情况,Go中没有错误。需要在tzdata中更改数据。如果您认为Go中有错误,能否更精确地描述它?谢谢。

f4t66c6m

f4t66c6m5#

我不确定Golang解析器是否有问题。这里有一个使用date命令的例子:

$ TZ=Europe/Dublin date -d '2019-01-12 09:30 IST'
date: invalid date ‘2019-01-12 09:30 IST’
$ TZ=Europe/Dublin date -d '2019-06-12 09:30 IST'
Wed 12 Jun 2019 09:30:00 AM IST

当夏令时不是“开启”时,日期命令会“正确”地拒绝IST是一个无效的时区。然而,Golang解析器却将其转换为都柏林平均时间。这是预期的行为吗?我对tzdata规则的快速阅读还不足以理解这是否是预期的行为。

nxagd54h

nxagd54h6#

我也不知道哪个是正确的。目前Go的做法是在位置中查找名称"IST",并检查它是否对给定的日期有效。在这种情况下,它不是,所以Go只是在时区中查找第一个出现的"IST",即具有25:21偏移量的时区。通常,这种算法似乎是用户意图的一个不错的猜测。但在这种情况下,效果并不好。
也许我们应该使用该时区内名称的最后一次出现。

gev0vcfq

gev0vcfq7#

如果你尝试使用过去的时间来使用解析器,那仍然是一个糟糕的想法。它可能需要根据实际时间进行更仔细的解析。这是支持的还是在范围内?

cu6pst1q

cu6pst1q8#

我们目前没有一个API来询问给定时区是否支持某个时间。我们不会因为某个日期的时区看起来无效而拒绝它们,我们只是尽量以最佳方式处理它们。

相关问题