Original link: https://articles.singee.me/timezone
Usually, the problem of time zone conversion is often involved in localization, and usually the “default” time zone we use is UTC or “local” before we really pay attention to the time zone.
This article takes Go as an example to analyze the time zone usage in Go.
read time zone
In Go, LoadLocation
function is used to read the time zone.
1 |
// LoadLocation returns the Location with the given name. |
Read the comments to know that if the name is empty/UTC, UTC is used, and if it is Local, the local time zone is used (explained later), otherwise, it is read from a specific location.
The so-called read refers to the read tzfile time zone file, you can read this document for more information. To put it simply, a time zone file is a binary file starting with
TZif
, which contains information such as time zone offset, leap second, daylight saving time, etc. Go can read and parse related files.
- If there is a
ZONEINFO
environment variable, use the directory/compressed file pointed to by the variable to read - On Unix systems, use the system standard location
- (mainly used when compiling Go) read from
$GOROOT/lib/time/zoneinfo.zip
- (if
time/tzdata
is imported) read from program embedded data
We are more concerned about 2, which is the storage location of Unix standard time zone files. In Unix systems, time zone files are usually stored in the /usr/share/zoneinfo/
directory (or /usr/share/lib/zoneinfo/ 或/usr/lib/locale/TZ/
depending on the system), for example , the time zone definition file of China ( Asia/Shanghai
) is /usr/share/zoneinfo/Asia/Shanghai
. Therefore, usually the program can obtain the time zone information directly from the system.
Note that in the alpine environment, there is no time zone definition file, so we need to pay special attention to processing
- You can use
import _ "time/tzdata"
in the program to compile the time zone file into the program at compile time, so that you can also find the standard IANA time zone definition when you cannot find the time zone definition in the system - If we don’t need a particularly dynamic time zone, we can avoid using
LoadLocation
but useFixedZone
to provide the time zone name and offset by ourselves, for example, for China UTF+8, you can usetime.FixedZone("Asia/Shanghai", 8*60*60)
local time zone
Usually, the time zone we use “by default” is the so-called “local time zone” before we really consider the time zone issue.
Take time.Now
as an example,
1 |
type Time struct { |
It can be seen that the last field loc *Location
of Time
structure is the time zone, and the time zone used in time.Now
is Local
.
We’ve focused on time zones in this article, but if you’re interested in other factors in this code, feel free to read Do You Really Know Time.Now()? .
Local
here is the local time zone, that is, the time zone of the machine where the program is running.
1 |
// Local represents the system's local time zone. |
Reading the description about Local
in Go shows that Go will respect the time zone specified by TZ
environment variable first. If there is no special specification, use the /etc/localtime file to read the current time zone.
So, how is Local
initialized?
1 |
// localLoc is separate so that initLocal can initialize |
From the logic of this code, it is not difficult to guess that Local
does not actually read the above information when the program starts, but is actually initialized by executing initLocal
function when it is used for the first time. At the same time, this code also implicitly puts forward a requirement for using Location: the get method must be called to obtain the “real Location”.
initLocal
function is defined in zoneinfo_*.go
and has different implementations on different machines, but essentially
The colon is ignored if the TZ content starts
:
:
- If the TZ environment variable is not specified, read
/etc/localtime
(usually a soft link pointing to the real time zone file) - If the specified TZ environment variable is an absolute path, read the file
- Otherwise, read the time zone file according to the LoadLocation process analyzed above
In addition, if the above 3 steps fail, it will fallback to use UTC time
Extra meal: tzdata
tzdata defines the changes of the historical time zone in detail, including daylight saving time, leap second, etc. Therefore, Asia/Shanghai
is more versatile than the simple GMT+8
and can correctly process historical data.
If you are interested, you can use zdump Asia/Shanghai -i
to view the time zone changes in Shanghai and compare it with zdump America/Chicago -i
when using daylight saving time.
This article is transferred from: https://articles.singee.me/timezone
This site is only for collection, and the copyright belongs to the original author.