diff options
Diffstat (limited to 'libgo/go/time/time.go')
-rw-r--r-- | libgo/go/time/time.go | 153 |
1 files changed, 53 insertions, 100 deletions
diff --git a/libgo/go/time/time.go b/libgo/go/time/time.go index 5dc9fa6..8ae6230 100644 --- a/libgo/go/time/time.go +++ b/libgo/go/time/time.go @@ -252,7 +252,9 @@ func (t Time) Before(u Time) bool { if t.wall&u.wall&hasMonotonic != 0 { return t.ext < u.ext } - return t.sec() < u.sec() || t.sec() == u.sec() && t.nsec() < u.nsec() + ts := t.sec() + us := u.sec() + return ts < us || ts == us && t.nsec() < u.nsec() } // Equal reports whether t and u represent the same time instant. @@ -285,25 +287,10 @@ const ( December ) -var months = [...]string{ - "January", - "February", - "March", - "April", - "May", - "June", - "July", - "August", - "September", - "October", - "November", - "December", -} - // String returns the English name of the month ("January", "February", ...). func (m Month) String() string { if January <= m && m <= December { - return months[m-1] + return longMonthNames[m-1] } buf := make([]byte, 20) n := fmtInt(buf, uint64(m)) @@ -323,20 +310,10 @@ const ( Saturday ) -var days = [...]string{ - "Sunday", - "Monday", - "Tuesday", - "Wednesday", - "Thursday", - "Friday", - "Saturday", -} - // String returns the English name of the day ("Sunday", "Monday", ...). func (d Weekday) String() string { if Sunday <= d && d <= Saturday { - return days[d] + return longDayNames[d] } buf := make([]byte, 20) n := fmtInt(buf, uint64(d)) @@ -535,58 +512,26 @@ func absWeekday(abs uint64) Weekday { // week 52 or 53 of year n-1, and Dec 29 to Dec 31 might belong to week 1 // of year n+1. func (t Time) ISOWeek() (year, week int) { - year, month, day, yday := t.date(true) - wday := int(t.Weekday()+6) % 7 // weekday but Monday = 0. - const ( - Mon int = iota - Tue - Wed - Thu - Fri - Sat - Sun - ) - - // Calculate week as number of Mondays in year up to - // and including today, plus 1 because the first week is week 0. - // Putting the + 1 inside the numerator as a + 7 keeps the - // numerator from being negative, which would cause it to - // round incorrectly. - week = (yday - wday + 7) / 7 - - // The week number is now correct under the assumption - // that the first Monday of the year is in week 1. - // If Jan 1 is a Tuesday, Wednesday, or Thursday, the first Monday - // is actually in week 2. - jan1wday := (wday - yday + 7*53) % 7 - if Tue <= jan1wday && jan1wday <= Thu { - week++ + // According to the rule that the first calendar week of a calendar year is + // the week including the first Thursday of that year, and that the last one is + // the week immediately preceding the first calendar week of the next calendar year. + // See https://www.iso.org/obp/ui#iso:std:iso:8601:-1:ed-1:v1:en:term:3.1.1.23 for details. + + // weeks start with Monday + // Monday Tuesday Wednesday Thursday Friday Saturday Sunday + // 1 2 3 4 5 6 7 + // +3 +2 +1 0 -1 -2 -3 + // the offset to Thursday + abs := t.abs() + d := Thursday - absWeekday(abs) + // handle Sunday + if d == 4 { + d = -3 } - - // If the week number is still 0, we're in early January but in - // the last week of last year. - if week == 0 { - year-- - week = 52 - // A year has 53 weeks when Jan 1 or Dec 31 is a Thursday, - // meaning Jan 1 of the next year is a Friday - // or it was a leap year and Jan 1 of the next year is a Saturday. - if jan1wday == Fri || (jan1wday == Sat && isLeap(year)) { - week++ - } - } - - // December 29 to 31 are in week 1 of next year if - // they are after the last Thursday of the year and - // December 31 is a Monday, Tuesday, or Wednesday. - if month == December && day >= 29 && wday < Thu { - if dec31wday := (wday + 31 - day) % 7; Mon <= dec31wday && dec31wday <= Wed { - year++ - week = 1 - } - } - - return + // find the Thursday of the calendar week + abs += uint64(d) * secondsPerDay + year, _, _, yday := absDate(abs, false) + return year, yday/7 + 1 } // Clock returns the hour, minute, and second within the day specified by t. @@ -1074,6 +1019,34 @@ func daysIn(m Month, year int) int { return int(daysBefore[m] - daysBefore[m-1]) } +// daysSinceEpoch takes a year and returns the number of days from +// the absolute epoch to the start of that year. +// This is basically (year - zeroYear) * 365, but accounting for leap days. +func daysSinceEpoch(year int) uint64 { + y := uint64(int64(year) - absoluteZeroYear) + + // Add in days from 400-year cycles. + n := y / 400 + y -= 400 * n + d := daysPer400Years * n + + // Add in 100-year cycles. + n = y / 100 + y -= 100 * n + d += daysPer100Years * n + + // Add in 4-year cycles. + n = y / 4 + y -= 4 * n + d += daysPer4Years * n + + // Add in non-leap years. + n = y + d += 365 * n + + return d +} + // Provided by package runtime. func now() (sec int64, nsec int32, mono int64) @@ -1382,28 +1355,8 @@ func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location) T hour, min = norm(hour, min, 60) day, hour = norm(day, hour, 24) - y := uint64(int64(year) - absoluteZeroYear) - // Compute days since the absolute epoch. - - // Add in days from 400-year cycles. - n := y / 400 - y -= 400 * n - d := daysPer400Years * n - - // Add in 100-year cycles. - n = y / 100 - y -= 100 * n - d += daysPer100Years * n - - // Add in 4-year cycles. - n = y / 4 - y -= 4 * n - d += daysPer4Years * n - - // Add in non-leap years. - n = y - d += 365 * n + d := daysSinceEpoch(year) // Add in days before this month. d += uint64(daysBefore[month-1]) |