Almost all examples of time resolution in Go take the full time including the date, and the official example is no exception. But few people have used the following code as an example to explain the behavior until the day the user makes a mistake.
Background of the problem
Trying to get the user to enter a readable time as input from the terminal, but I find that I am parsing the input incorrectly.
A very simple piece of code (ignoring the error handling) parses the partial time of an input at the current location.
The hours and minutes are correctly resolved, and the year, month, day, seconds and nanoseconds are also correct defaults. Where is it incorrect? The time zone.
Isn’t it strange that one is CST (China Standard Time, +0800) and the other LMT (Local Mean Time?, +0805). I obviously took the now Location and parse it, but why is the time zone/location different when I parse it? It’s very strange!
Find the answer from the source code
Call stack: Time.String
→ Time.Format
→ Time.AppendFormat
→ Time.locabs
→ Location.lookup
.
This locabs
is the point I want to focus on. Where name
is the name of the time zone and offset
is the offset of the time zone. Here’s the problem: why does it count as “wrong”?
locabs
calls lookup
and here is the source code (with deletions).
|
|
Before interpreting this code, let’s look at the definition of Location
.
|
|
From the comments and the definition, the problem starts to become clear: a Location contains multiple Zones and multiple Transitions. So what is lookup
doing? It’s looking for which time zone of this location to use for the input parameter sec (Unix timestamp).
For me, being a bit geographically and historically illiterate, I didn’t know much about this. So I went and looked up some information (Visipedia - China Time Zones).
China is a vast country and can be divided into five time zones: East 5, East 6, East 7, East 8 and East 9 according to the international standard of time zone division. During the mainland period of the Republic of China, the country’s time zones were divided into Kunlun time zone, Hui-Zang time zone (later renamed Xin-Zang time zone), Long-Shu time zone, Zhongyuan time zone, and Changbai time zone according to international standards. After the founding of the People’s Republic of China in 1949, the whole of mainland China was unified into the eastern eight zones (UTC+8), and Beijing time was adopted as the only standard time in the country.
Simply put, the time zones of the same geographical location are subject to change throughout history (fall of countries, creation of countries, change of regime, etc.). This information is maintained and collated in the Time Zone Information Database.
Going back to the definition of a location, zone
records all the time zones that occur at that location, and tx
records when a time zone changes to another time zone.
It is now clear what lookup
is doing.
Attachment: Zone content of the Location in my example.
CST is the +8 (86060=28800) time zone we are currently using.
Tx I won’t attach, there are as many as 29.
Answers
I made the user’s input contain only hours and minutes, so the default year is 0000, which is converted to a Unix timestamp (a negative number compared to 1970) and the corresponding Zone is indeed LMT by Tx.
So how do we get the input value to parse correctly? Use FixedZone
.
|
|
This Zone constitutes a Location with only one Zone and one Transition.
Let’s modify the sample code again.
The desired answer can now be obtained.