What is time? Summary of Golang time module errors

Go time module function usage


I recently tested a service code of the company and found that the timestamps in the two containers did not match. I checked the problem all the way, and finally found that it was a time parsing problem in go. Record it here.

1.time.Now()

First of all, this function returns the local time and time with time zone.
See how the source code explains:

// Now returns the current local time.
func Now() Time {
    
    
	sec, nsec, mono := now()
	mono -= startNano
	sec += unixToInternal - minWall
	if uint64(sec)>>33 != 0 {
    
    
		return Time{
    
    uint64(nsec), sec + minWall, Local}
	}
	return Time{
    
    hasMonotonic | uint64(sec)<<nsecShift | uint64(nsec), mono, Local}
}

The return value is the Time structure type, which is the local time. Generally speaking, local time and UTC time are different, so we need to pay attention to the distinction.

// In returns a copy of t representing the same time instant, but
// with the copy's location information set to loc for display
// purposes.
//
// In panics if loc is nil.
func (t Time) In(loc *Location) Time {
    
    
	if loc == nil {
    
    
		panic("time: missing Location in call to Time.In")
	}
	t.setLoc(loc)
	return t
}

The In function can convert the local time to another time zone for display.

package main

import 
("fmt"
"time")

func main() {
    
    
	location, _ := time.LoadLocation("Asia/Shanghai")
	timer1:=time.Now()
	timer2:=time.Now().In(location)
	fmt.Println(timer1.Format("2006-1-2 15:04:05"),timer2.Format("2006-1-2 15:04:05"))
}

The result is

2009-11-10 23:00:00 2009-11-11 07:00:00

Program exited.

Here are a few concepts, UTC time, time zone, and time stamp to facilitate the understanding of the following functions.

The time value needs to contain two parts to be considered complete. One is the time, and the second is the time zone. Time that does not include the time zone is ambiguous, incomplete, and does not include the time zone. It does not know exactly what it means to say 8 o'clock in the morning. It is 8 o'clock in the morning in Beijing and in New York. Eight o'clock in the morning is not a time at all.

This tells us once again that the world is so big. Countless people live at different moments. We can say that we all live in parallel worlds, without mutual awareness of distant places. Some people are ahead of time or lagging behind themselves.

Therefore, the time in the program needs to include a time zone. China is the eighth time zone. Without a time zone, it may be a big pit. I also thought that China has only one time zone at first, so why add the time zone attribute? The results show that it is necessary.

When it comes to time zone, you may understand what it means, but if you say UTC, you may not be familiar. When UTC is in harmony with the world, it is the time we use now.

described as follows:

  • UTC is the time standard we use now, and GMT is the old time measurement standard. UTC calculates time based on atomic clocks, while GMT calculates time based on the rotation and revolution of the earth, that is, the time when the sun passes the Royal Greenwich Observatory in the suburbs of London, England, is 12 noon every day. Since the most accurate atomic clock in the world now has an error of 1 second in 5 billion years (the most accurate atomic clock came out: an error of one second in 5 billion years), it can be said that it is very accurate.
    There are about 20 different laboratories in more than 20 countries in the world. Independent place atomic time. International time is based on the comparison and synthesis of atomic clock data from all over the world, and the final atomic time is called International Atomic Time, or TAI for short.
    The starting point of the TAI is defined as follows: Take the moment of 0:00:00 on January 1, 1958 in Universal Time (UT) as the 0:00:00 on the same day of the same year and the same day as the TAI.

UTC is adjusted based on UT time, relative to the astronomical observation time-Greenwich Mean Time (the source of the error is the unevenness of the earth's revolution and rotation), so that the difference between the two will not exceed 0.9 seconds, which is also the world standard time currently used. It also represents UTC time zone, which is time zone 0. The time in other time zones is added to its time for the time difference, China is UTC+8.

Well, the last is the timestamp. The timestamp is based on a certain moment as the starting point to calculate the number of seconds that have elapsed to the current time. The starting point used in go is January 1, 1970 00:00:00 UTC, and it is normal until now. For billions of seconds. Go calculates the timestamp, which has nothing to do with the time zone and will automatically be converted to the UTC time zone. Because the time stamp is calculated, the time zone must be consistent. Next, talk about the problems encountered by the go time module this time.

2. Time parsing time.parse()

The time module of time contains three parts commonly used: time acquisition, time format conversion, and time stamp generation.
Format conversion includes time format output to string format and string format to time format.
Here we mainly talk about the parse module that converts string format to time format. Divided into two methods, time, parse and time.parseInLocal. The conclusion is, don't use time.parse(), why? I will say below.
Not much to say, just look at the source code.

// In the absence of a time zone indicator, Parse returns a time in UTC.
//
// When parsing a time with a zone offset like -0700, if the offset corresponds
// to a time zone used by the current location (Local), then Parse uses that
// location and zone in the returned time. Otherwise it records the time as
// being in a fabricated location with time fixed at the given zone offset.
//
// When parsing a time with a zone abbreviation like MST, if the zone abbreviation
// has a defined offset in the current location, then that offset is used.
// The zone abbreviation "UTC" is recognized as UTC regardless of location.
// If the zone abbreviation is unknown, Parse records the time as being
// in a fabricated location with the given zone abbreviation and a zero offset.
// This choice means that such a time can be parsed and reformatted with the
// same layout losslessly, but the exact instant used in the representation will
// differ by the actual zone offset. To avoid such problems, prefer time layouts
// that use a numeric zone offset, or use ParseInLocation.
func Parse(layout, value string) (Time, error) {
    
    
	return parse(layout, value, UTC, Local)
}

// ParseInLocation is like Parse but differs in two important ways.
// First, in the absence of time zone information, Parse interprets a time as UTC;
// ParseInLocation interprets the time as in the given location.
// Second, when given a zone offset or abbreviation, Parse tries to match it
// against the Local location; ParseInLocation uses the given location.
func ParseInLocation(layout, value string, loc *Location) (Time, error) {
    
    
	return parse(layout, value, loc, loc)
}

There is a long description of the time parsing function in go. In summary, when using parse, if the string does not have a time zone description, such as directly giving a string such as 2019-9-1 18:32:09, the default is UTC time zone , You can also specify the time zone for parsing, and parseInLocal needs to give the time zone represented by the string time, such as Asia/Shanghai, and parse according to this time zone.

Okay, finally look at the timestamp calculation function.

// Unix returns t as a Unix time, the number of seconds elapsed
// since January 1, 1970 UTC. The result does not depend on the
// location associated with t.
// Unix-like operating systems often record time as a 32-bit
// count of seconds, but since the method here returns a 64-bit
// value it is valid for billions of years into the past or future.
func (t Time) Unix() int64 {
    
    
	return t.unixSec()
}

Pay attention to this sentence, since January 1, 1970 UTC. The result does not depend on the location associated with t. The result returns the time stamp of the converted UTC 0 time zone.

The following is the question of this time.

This time the service is due to this problem. The service sets a time period, such as 7:00-16:00, and then needs to add the date of the day to generate two time stamps to compare the time when the instrument detects the signal , Within the time, pass, otherwise, block it.

If you use time comparison, then under the same date, 7:00 and 8:00 are very good comparisons, and there will be no problem. But currently using the timestamp time.Unix() comparison, then you must ensure that the string is parsed to the correct time zone. Here Unix() says that it does not depend on time zones. It means that at the same time in the world, even if there are different time zones, Unix() will convert the time to UTC0 time zone and then calculate the timestamp.

When parsing time, the parse function used did not add a time zone description, which caused the local time 7:00 to become 7:00 in the UTC0 time zone. But the time used by the instrument is the local time UTC+8, which means that the time of the instrument will always be eight hours less than this time period. It can be said that the instrument time is 8 hours slower, or it can be said that the setting here is 8 hours ahead. , The setting is actually ahead.

The solution is to use location, _ := time.LoadLocation("Asia/Shanghai") to get the correct time zone, and then use parseInLocation to parse the time. The problem is solved.

3. Summary

When writing services, time is used in a wide range. To ensure that there is no problem, time must be brought with time zone to ensure that no unexpected errors occur during parsing and conversion.

Guess you like

Origin blog.csdn.net/hu_hao/article/details/108417345