시간 처리는 꽤 복잡합니다. 시간에 대한 일반적인 잘못된 가정은 다음과 같습니다.

  1. 하루는 24시간으로 구성된다.
  2. 한 시간은 60분을 포함한다.
  3. 일주일은 7일로 구성된다.
  4. 일 년은 365일로 이루어진다.

예를 들면, 1은 특정 시간 지점에 24시간을 더했을 때 항상 새로운 달력 날짜가 되는 것은 아니라는 것을 나타냅니다.

따라서 시간 처리시 언제나 "time" 패키지를 사용하여 이러한 잘못된 가정을 더 안전하고 정확하게 처리할 수 있습니다.

순간적인 시간을 나타내는 time.Time 사용

순간적인 시간을 다룰 때는 time.Time 및 해당 메서드를 사용하여 시간을 비교하거나 더하거나 빼는 것이 좋습니다.

추천하지 않음:

func isActive(now, start, stop int) bool {
  return start <= now && now < stop
}

권장:

func isActive(now, start, stop time.Time) bool {
  return (start.Before(now) || start.Equal(now)) && now.Before(stop)
}

시간 기간을 나타내는 time.Duration 사용

시간 기간을 다룰 때는 time.Duration을 사용하세요.

추천하지 않음:

func poll(delay int) {
  for {
    // ...
    time.Sleep(time.Duration(delay) * time.Millisecond)
  }
}
poll(10) // 초 또는 밀리초인가요?

권장:

func poll(delay time.Duration) {
  for {
    // ...
    time.Sleep(delay)
  }
}
poll(10*time.Second)

첫 번째 예제로 돌아가서, 순간적인 시간에 24시간을 추가할 때 사용하는 방법은 의도에 따라 다릅니다. 현재 날짜의 다음 달력 날짜(현재 날짜의 다음 날)에 동일한 시간 지점을 원할 경우에는 Time.AddDate를 사용해야 합니다. 그러나 이전 시간보다 정확히 24시간 이후의 특정 순간을 보장하고 싶다면 Time.Add를 사용해야 합니다.

newDay := t.AddDate(0 /* years */, 0 /* months */, 1 /* days */)
maybeNewDay := t.Add(24 * time.Hour)

외부 시스템과 time.Timetime.Duration 사용

가능한 경우 외부 시스템과 상호 작용할 때 time.Durationtime.Time을 사용하십시오. 예를 들어:

이러한 상호 작용에서 time.Duration을 사용할 수 없을 때는 필드 이름에 단위를 포함하여 int 또는 float64를 사용하십시오.

예를 들어, encoding/jsontime.Duration을 지원하지 않으므로 필드 이름에 단위가 포함됩니다.

추천되지 않음:

// {"interval": 2}
type Config struct {
  Interval int `json:"interval"`
}

추천됨:

// {"intervalMillis": 2000}
type Config struct {
  IntervalMillis int `json:"intervalMillis"`
}

이러한 상호 작용에서 time.Time을 사용할 수 없는 경우에는 합의에 따라 string을 사용하고 RFC 3339에 따라 타임스탬프 형식을 지정하십시오. 기본적으로 Time.UnmarshalText는 이 형식을 사용하며 Time.Formattime.RFC3339를 통해 time.Parse에서 사용할 수 있습니다.

실제 문제는 아니지만, "time" 패키지는 윤초 타임스탬프를 구문 분석하지 않습니다 (8728) 및 계산에 윤초를 고려하지 않습니다 (15190). 두 시간을 비교하면 그 사이에 발생한 윤초를 포함하지 않을 것입니다.