Skip to content

Commit 59ed4dd

Browse files
cassionerinormandesjr
authored andcommitted
Simplify time package.
1 parent 6d98312 commit 59ed4dd

File tree

4 files changed

+56
-113
lines changed

4 files changed

+56
-113
lines changed

src/time/format.go

+3-2
Original file line numberDiff line numberDiff line change
@@ -557,7 +557,7 @@ func (t Time) String() string {
557557
// code.
558558
func (t Time) GoString() string {
559559
abs := t.abs()
560-
year, month, day := absDate(abs, true)
560+
year, month, day := absDate(abs)
561561
hour, minute, second := absClock(abs)
562562

563563
buf := make([]byte, 0, len("time.Date(9999, time.September, 31, 23, 59, 59, 999999999, time.Local)"))
@@ -671,7 +671,8 @@ func (t Time) appendFormat(b []byte, layout string) []byte {
671671

672672
// Compute year, month, day if needed.
673673
if year < 0 && std&stdNeedDate != 0 {
674-
year, month, day, yday = absDateWithYday(abs, true)
674+
_, month, day = absDate(abs)
675+
year, yday = absYearDay(abs)
675676
yday++
676677
}
677678

src/time/format_rfc3339.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ func (t Time) appendFormatRFC3339(b []byte, nanos bool) []byte {
1919
_, offset, abs := t.locabs()
2020

2121
// Format date.
22-
year, month, day := absDate(abs, true)
22+
year, month, day := absDate(abs)
2323
b = appendInt(b, year, 4)
2424
b = append(b, '-')
2525
b = appendInt(b, int(month), 2)

src/time/time.go

+51-109
Original file line numberDiff line numberDiff line change
@@ -508,25 +508,25 @@ func (t Time) locabs() (name string, offset int, abs uint64) {
508508

509509
// Date returns the year, month, and day in which t occurs.
510510
func (t Time) Date() (year int, month Month, day int) {
511-
year, month, day = t.date(true)
511+
year, month, day = absDate(t.abs())
512512
return
513513
}
514514

515515
// Year returns the year in which t occurs.
516516
func (t Time) Year() int {
517-
year, _, _ := t.date(false)
517+
year, _, _ := t.Date()
518518
return year
519519
}
520520

521521
// Month returns the month of the year specified by t.
522522
func (t Time) Month() Month {
523-
_, month, _ := t.date(true)
523+
_, month, _ := t.Date()
524524
return month
525525
}
526526

527527
// Day returns the day of the month specified by t.
528528
func (t Time) Day() int {
529-
_, _, day := t.date(true)
529+
_, _, day := t.Date()
530530
return day
531531
}
532532

@@ -565,7 +565,7 @@ func (t Time) ISOWeek() (year, week int) {
565565
}
566566
// find the Thursday of the calendar week
567567
abs += uint64(d) * secondsPerDay
568-
year, _, _, yday := absDateWithYday(abs, false)
568+
year, yday := absYearDay(abs)
569569
return year, yday/7 + 1
570570
}
571571

@@ -608,7 +608,8 @@ func (t Time) Nanosecond() int {
608608
// YearDay returns the day of the year specified by t, in the range [1,365] for non-leap years,
609609
// and [1,366] in leap years.
610610
func (t Time) YearDay() int {
611-
return absYearDay(t.abs()) + 1
611+
_, yday := absYearDay(t.abs())
612+
return yday + 1
612613
}
613614

614615
// A Duration represents the elapsed time between two instants
@@ -974,27 +975,25 @@ const (
974975
daysPer400Years = 365*400 + 97
975976
daysPer100Years = 365*100 + 24
976977
daysPer4Years = 365*4 + 1
978+
979+
// Neri-Schneider shift and correction constants. (ns_s is chosen so that
980+
// 1970 is roughly in the middle of the range of their algorithms validity.)
981+
ns_s = uint32(3670)
982+
ns_K = uint32(719468 + 146097*ns_s)
983+
ns_L = int(400 * ns_s)
977984
)
978985

979-
// date computes the year, day of year, and when full=true,
980-
// the month and day in which t occurs.
981-
func (t Time) date(full bool) (year int, month Month, day int) {
982-
return absDate(t.abs(), full)
983-
}
986+
// Computes the year, month and day given the absolute time.
987+
func absDate(abs uint64) (year int, month Month, day int) {
984988

985-
// The algorithm is figure 12 of Neri, Schneider, "Euclidean affine functions
986-
// and their application to calendar algorithms".
987-
// https://onlinelibrary.wiley.com/doi/full/10.1002/spe.3172
988-
func absDate(abs uint64, full bool) (year int, month Month, day int) {
989989
daysAbs := int64(abs / secondsPerDay)
990990
daysUnix := int32(daysAbs - (unixToInternal+internalToAbsolute)/secondsPerDay)
991991

992-
// Shift and correction constants.
993-
s := uint32(3670)
994-
K := uint32(719468 + 146097*s)
995-
L := int(400 * s)
992+
// The algorithm is figure 12 of Neri, Schneider, "Euclidean affine functions
993+
// and their application to calendar algorithms".
994+
// https://onlinelibrary.wiley.com/doi/full/10.1002/spe.3172
996995

997-
N := uint32(daysUnix) + K
996+
N := uint32(daysUnix) + ns_K
998997

999998
// Century
1000999
N_1 := 4*N + 3
@@ -1005,48 +1004,43 @@ func absDate(abs uint64, full bool) (year int, month Month, day int) {
10051004
N_2 := R | 3
10061005
P_2 := 2939745 * uint64(N_2)
10071006
Z := uint32(P_2 / 4294967296)
1008-
N_Y := uint32(P_2%4294967296) / 2939745 / 4
1007+
N_Y := uint32(P_2%4294967296) / 11758980
10091008

10101009
J := 0
10111010
if N_Y >= 306 {
10121011
J = 1
10131012
}
10141013

10151014
Y := 100*C + Z
1016-
year = int(Y) - L + J
1017-
1018-
if !full {
1019-
return
1020-
}
1015+
year = int(Y) - ns_L + J
10211016

10221017
// Month and day
10231018
N_3 := 2141*N_Y + 197913
1024-
M := N_3 / 65536
1025-
D := N_3 % 65536 / 2141
1019+
M := uint16(N_3 / 65536)
1020+
D := uint16(N_3%65536) / 2141
10261021

10271022
month = Month(M)
10281023
if J == 1 {
1029-
month = Month(M - 12)
1024+
month -= 12
10301025
}
1031-
day = int(D + 1)
1026+
day = int(D) + 1
10321027

10331028
return
10341029
}
10351030

1036-
// The algorithm is basicaly figure 12 of Neri, Schneider, "Euclidean affine functions
1037-
// and their application to calendar algorithms", adapted to calculate yday.
1038-
// https://onlinelibrary.wiley.com/doi/full/10.1002/spe.3172
1039-
func absDateWithYday(abs uint64, full bool) (year int, month Month, day int, yday int) {
1040-
daysAbs := int64(abs / secondsPerDay)
1031+
// Computes the year and the year day (in [0, 365]) given the absolute time.
1032+
func absYearDay(abs uint64) (year int, yday int) {
10411033

1034+
daysAbs := int64(abs / secondsPerDay)
10421035
daysUnix := int32(daysAbs - (unixToInternal+internalToAbsolute)/secondsPerDay)
10431036

1044-
// Shift and correction constants.
1045-
s := uint32(3670) // chosen so that 1970 is roughly in the middle of the range
1046-
K := uint32(719468 + 146097*s)
1047-
L := int(400 * s)
1037+
// The algorithm is adapted from figure 12 of Neri, Schneider, "Euclidean affine
1038+
// functions and their application to calendar algorithms".
1039+
// https://onlinelibrary.wiley.com/doi/full/10.1002/spe.3172
10481040

1049-
N := uint32(daysUnix) + K
1041+
// The natural epoch for this algorithm is 0001-Jan-01, i.e, 306 days after
1042+
// 0000-Mar-01
1043+
N := uint32(daysUnix) + ns_K - 306
10501044

10511045
// Century
10521046
N_1 := 4*N + 3
@@ -1055,73 +1049,18 @@ func absDateWithYday(abs uint64, full bool) (year int, month Month, day int, yda
10551049
// Year
10561050
R := N_1 % 146097
10571051
N_2 := R | 3
1052+
10581053
P_2 := 2939745 * uint64(N_2)
10591054
Z := uint32(P_2 / 4294967296)
1060-
N_Y := uint32(P_2%4294967296) / 2939745 / 4
1061-
1062-
isLeapYear := 0
1063-
if Z != 0 {
1064-
if Z%4 == 0 {
1065-
isLeapYear = 1
1066-
}
1067-
} else if C%4 == 0 {
1068-
isLeapYear = 1
1069-
}
1070-
1071-
J := 0
1072-
if N_Y >= 306 {
1073-
J = 1
1074-
}
1075-
1076-
yday = int(N_Y)
1077-
if J == 1 {
1078-
yday = yday - 306
1079-
} else {
1080-
yday = yday + 31 + 28 + isLeapYear
1081-
}
1082-
1055+
N_Y := uint32(P_2%4294967296) / 11758980
10831056
Y := 100*C + Z
1084-
year = int(Y) - L + J
1085-
1086-
if !full {
1087-
return
1088-
}
10891057

1090-
// Month and day
1091-
N_3 := 2141*N_Y + 197913
1092-
M := N_3 / 65536
1093-
D := N_3 % 65536 / 2141
1094-
1095-
month = Month(M)
1096-
if J == 1 {
1097-
month = Month(M - 12)
1098-
}
1099-
day = int(D + 1)
1058+
year = int(Y) - ns_L + 1
1059+
yday = int(N_Y)
11001060

11011061
return
11021062
}
11031063

1104-
func absYearDay(abs uint64) int {
1105-
daysAbs := int64(abs / secondsPerDay)
1106-
daysUnix := int32(daysAbs - (unixToInternal+internalToAbsolute)/secondsPerDay)
1107-
1108-
// Shift and correction constants.
1109-
s := uint32(3670) // chosen so that 1970 is roughly in the middle of the range
1110-
K := uint32(719468 - 306 + 146097*s)
1111-
N := uint32(daysUnix) + K
1112-
1113-
// Century
1114-
N_1 := 4*N + 3
1115-
1116-
// Year
1117-
R := N_1 % 146097
1118-
N_2 := R | 3
1119-
P_2 := 2939745 * uint64(N_2)
1120-
N_Y := uint32(P_2%4294967296) / 2939745 / 4
1121-
1122-
return int(N_Y)
1123-
}
1124-
11251064
// daysBefore[m] counts the number of days in a non-leap year
11261065
// before month m begins. There is an entry for m=12, counting
11271066
// the number of days before January of next year (365).
@@ -1150,16 +1089,15 @@ func daysIn(m Month, year int) int {
11501089

11511090
// daysSinceEpoch takes a year, month and day and returns the number of days from
11521091
// Jan 1 1970 (Unix time) to the given date.
1153-
// The algorithm is figure 13 of Neri, Schneider, "Euclidean affine functions
1154-
// and their application to calendar algorithms".
1155-
// https://onlinelibrary.wiley.com/doi/full/10.1002/spe.3172
1156-
// It gives correct results if the date is in the range [-1,468,000/Mar/01, 1,471,745/Fev/28].
11571092
func daysSinceEpoch(year int, month Month, day int) int32 {
1158-
s := uint32(3670) // chosen so that 1970 is roughly in the middle of the range
1159-
K := uint32(719468 + 146097*s)
1160-
L := int(400 * s)
11611093

1162-
y := uint32(year + L)
1094+
// The algorithm is figure 13 of Neri, Schneider, "Euclidean affine functions
1095+
// and their application to calendar algorithms".
1096+
// https://onlinelibrary.wiley.com/doi/full/10.1002/spe.3172
1097+
// It gives correct results if the date is in the range
1098+
// [-1,468,000/Mar/01, 1,471,745/Fev/28].
1099+
1100+
y := uint32(year + ns_L)
11631101
m := uint32(month)
11641102
if month < 3 {
11651103
y--
@@ -1174,7 +1112,7 @@ func daysSinceEpoch(year int, month Month, day int) int32 {
11741112
m_star := (153*m - 457) / 5
11751113
n := y_star + m_star + d
11761114

1177-
return int32(n - K)
1115+
return int32(n - ns_K)
11781116
}
11791117

11801118
// Provided by package runtime.
@@ -1512,7 +1450,11 @@ func (t Time) IsDST() bool {
15121450
}
15131451

15141452
func isLeap(year int) bool {
1515-
return year%4 == 0 && (year%100 != 0 || year%400 == 0)
1453+
d := 3
1454+
if year%25 == 0 {
1455+
d = 15
1456+
}
1457+
return (year & d) == 0
15161458
}
15171459

15181460
// norm returns nhi, nlo such that

src/time/zoneinfo.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,7 @@ func tzset(s string, lastTxSec, sec int64) (name string, offset int, start, end
332332
}
333333

334334
absTmp := uint64(sec + unixToInternal + internalToAbsolute)
335-
year, _, _, yday := absDateWithYday(absTmp, false)
335+
year, yday := absYearDay(absTmp)
336336

337337
ysec := int64(yday*secondsPerDay) + sec%secondsPerDay
338338

0 commit comments

Comments
 (0)