1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package time provides functionality for measuring and displaying time.
19 // Time is the struct representing a parsed time value.
21 Year int64 // 2006 is 2006
22 Month, Day int // Jan-2 is 1, 2
23 Hour, Minute, Second int // 15:04:05 is 15, 4, 5.
24 Weekday int // Sunday, Monday, ...
25 ZoneOffset int // seconds east of UTC, e.g. -7*60*60 for -0700
26 Zone string // e.g., "MST"
29 var nonleapyear = []int{31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
30 var leapyear = []int{31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31}
32 func months(year int64) []int {
33 if year%4 == 0 && (year%100 != 0 || year%400 == 0) {
40 secondsPerDay = 24 * 60 * 60
41 daysPer400Years = 365*400 + 97
42 daysPer100Years = 365*100 + 24
43 daysPer4Years = 365*4 + 1
44 days1970To2001 = 31*365 + 8
47 // SecondsToUTC converts sec, in number of seconds since the Unix epoch,
48 // into a parsed Time value in the UTC time zone.
49 func SecondsToUTC(sec int64) *Time {
52 // Split into time and day.
53 day := sec / secondsPerDay
54 sec -= day * secondsPerDay
61 t.Hour = int(sec / 3600)
62 t.Minute = int((sec / 60) % 60)
63 t.Second = int(sec % 60)
65 // Day 0 = January 1, 1970 was a Thursday
66 t.Weekday = int((day + Thursday) % 7)
71 // Change day from 0 = 1970 to 0 = 2001,
72 // to make leap year calculations easier
73 // (2001 begins 4-, 100-, and 400-year cycles ending in a leap year.)
78 // Go back enough 400 year cycles to make day positive.
79 n := -day/daysPer400Years + 1
81 day += daysPer400Years * n
84 // Cut off 400 year cycles.
85 n := day / daysPer400Years
87 day -= daysPer400Years * n
89 // Cut off 100-year cycles
90 n = day / daysPer100Years
91 if n > 3 { // happens on last day of 400th year
95 day -= daysPer100Years * n
97 // Cut off 4-year cycles
98 n = day / daysPer4Years
99 if n > 24 { // happens on last day of 100th year
103 day -= daysPer4Years * n
105 // Cut off non-leap years.
107 if n > 3 { // happens on last day of 4th year
115 // If someone ever needs yearday,
116 // tyearday = day (+1?)
118 months := months(year)
121 for m = 0; m < 12 && yday >= months[m]; m++ {
131 // UTC returns the current time as a parsed Time value in the UTC time zone.
132 func UTC() *Time { return SecondsToUTC(Seconds()) }
134 // SecondsToLocalTime converts sec, in number of seconds since the Unix epoch,
135 // into a parsed Time value in the local time zone.
136 func SecondsToLocalTime(sec int64) *Time {
137 z, offset := lookupTimezone(sec)
138 t := SecondsToUTC(sec + int64(offset))
140 t.ZoneOffset = offset
144 // LocalTime returns the current time as a parsed Time value in the local time zone.
145 func LocalTime() *Time { return SecondsToLocalTime(Seconds()) }
147 // Seconds returns the number of seconds since January 1, 1970 represented by the
148 // parsed Time value.
149 func (t *Time) Seconds() int64 {
150 // First, accumulate days since January 1, 2001.
151 // Using 2001 instead of 1970 makes the leap-year
152 // handling easier (see SecondsToUTC), because
153 // it is at the beginning of the 4-, 100-, and 400-year cycles.
156 // Rewrite year to be >= 2001.
159 n := (2001-year)/400 + 1
161 day -= daysPer400Years * n
164 // Add in days from 400-year cycles.
165 n := (year - 2001) / 400
167 day += daysPer400Years * n
169 // Add in 100-year cycles.
170 n = (year - 2001) / 100
172 day += daysPer100Years * n
174 // Add in 4-year cycles.
175 n = (year - 2001) / 4
177 day += daysPer4Years * n
179 // Add in non-leap years.
183 // Add in days this year.
184 months := months(t.Year)
185 for m := 0; m < t.Month-1; m++ {
186 day += int64(months[m])
188 day += int64(t.Day - 1)
190 // Convert days to seconds since January 1, 2001.
191 sec := day * secondsPerDay
193 // Add in time elapsed today.
194 sec += int64(t.Hour) * 3600
195 sec += int64(t.Minute) * 60
196 sec += int64(t.Second)
198 // Convert from seconds since 2001 to seconds since 1970.
199 sec += days1970To2001 * secondsPerDay
201 // Account for local time zone.
202 sec -= int64(t.ZoneOffset)