Source file src/time/time_test.go

     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.
     4  
     5  package time_test
     6  
     7  import (
     8  	"bytes"
     9  	"encoding/gob"
    10  	"encoding/json"
    11  	"fmt"
    12  	"math"
    13  	"math/big"
    14  	"math/rand"
    15  	"os"
    16  	"runtime"
    17  	"slices"
    18  	"strings"
    19  	"sync"
    20  	"testing"
    21  	"testing/quick"
    22  	. "time"
    23  )
    24  
    25  func TestInternal(t *testing.T) {
    26  	for _, tt := range InternalTests {
    27  		t.Run(tt.Name, func(t *testing.T) { tt.Test(t) })
    28  	}
    29  }
    30  
    31  func TestZeroTime(t *testing.T) {
    32  	var zero Time
    33  	year, month, day := zero.Date()
    34  	hour, min, sec := zero.Clock()
    35  	nsec := zero.Nanosecond()
    36  	yday := zero.YearDay()
    37  	wday := zero.Weekday()
    38  	if year != 1 || month != January || day != 1 || hour != 0 || min != 0 || sec != 0 || nsec != 0 || yday != 1 || wday != Monday {
    39  		t.Errorf("zero time = %v %v %v year %v %02d:%02d:%02d.%09d yday %d want Monday Jan 1 year 1 00:00:00.000000000 yday 1",
    40  			wday, month, day, year, hour, min, sec, nsec, yday)
    41  	}
    42  
    43  }
    44  
    45  // We should be in PST/PDT, but if the time zone files are missing we
    46  // won't be. The purpose of this test is to at least explain why some of
    47  // the subsequent tests fail.
    48  func TestZoneData(t *testing.T) {
    49  	lt := Now()
    50  	// PST is 8 hours west, PDT is 7 hours west. We could use the name but it's not unique.
    51  	if name, off := lt.Zone(); off != -8*60*60 && off != -7*60*60 {
    52  		t.Errorf("Unable to find US Pacific time zone data for testing; time zone is %q offset %d", name, off)
    53  		t.Error("Likely problem: the time zone files have not been installed.")
    54  	}
    55  }
    56  
    57  // parsedTime is the struct representing a parsed time value.
    58  type parsedTime struct {
    59  	Year                 int
    60  	Month                Month
    61  	Day                  int
    62  	Hour, Minute, Second int // 15:04:05 is 15, 4, 5.
    63  	Nanosecond           int // Fractional second.
    64  	Weekday              Weekday
    65  	ZoneOffset           int    // seconds east of UTC, e.g. -7*60*60 for -0700
    66  	Zone                 string // e.g., "MST"
    67  }
    68  
    69  type TimeTest struct {
    70  	seconds int64
    71  	golden  parsedTime
    72  }
    73  
    74  var utctests = []TimeTest{
    75  	{0, parsedTime{1970, January, 1, 0, 0, 0, 0, Thursday, 0, "UTC"}},
    76  	{1221681866, parsedTime{2008, September, 17, 20, 4, 26, 0, Wednesday, 0, "UTC"}},
    77  	{-1221681866, parsedTime{1931, April, 16, 3, 55, 34, 0, Thursday, 0, "UTC"}},
    78  	{-11644473600, parsedTime{1601, January, 1, 0, 0, 0, 0, Monday, 0, "UTC"}},
    79  	{599529660, parsedTime{1988, December, 31, 0, 1, 0, 0, Saturday, 0, "UTC"}},
    80  	{978220860, parsedTime{2000, December, 31, 0, 1, 0, 0, Sunday, 0, "UTC"}},
    81  }
    82  
    83  var nanoutctests = []TimeTest{
    84  	{0, parsedTime{1970, January, 1, 0, 0, 0, 1e8, Thursday, 0, "UTC"}},
    85  	{1221681866, parsedTime{2008, September, 17, 20, 4, 26, 2e8, Wednesday, 0, "UTC"}},
    86  }
    87  
    88  var localtests = []TimeTest{
    89  	{0, parsedTime{1969, December, 31, 16, 0, 0, 0, Wednesday, -8 * 60 * 60, "PST"}},
    90  	{1221681866, parsedTime{2008, September, 17, 13, 4, 26, 0, Wednesday, -7 * 60 * 60, "PDT"}},
    91  	{2159200800, parsedTime{2038, June, 3, 11, 0, 0, 0, Thursday, -7 * 60 * 60, "PDT"}},
    92  	{2152173599, parsedTime{2038, March, 14, 1, 59, 59, 0, Sunday, -8 * 60 * 60, "PST"}},
    93  	{2152173600, parsedTime{2038, March, 14, 3, 0, 0, 0, Sunday, -7 * 60 * 60, "PDT"}},
    94  	{2152173601, parsedTime{2038, March, 14, 3, 0, 1, 0, Sunday, -7 * 60 * 60, "PDT"}},
    95  	{2172733199, parsedTime{2038, November, 7, 1, 59, 59, 0, Sunday, -7 * 60 * 60, "PDT"}},
    96  	{2172733200, parsedTime{2038, November, 7, 1, 0, 0, 0, Sunday, -8 * 60 * 60, "PST"}},
    97  	{2172733201, parsedTime{2038, November, 7, 1, 0, 1, 0, Sunday, -8 * 60 * 60, "PST"}},
    98  }
    99  
   100  var nanolocaltests = []TimeTest{
   101  	{0, parsedTime{1969, December, 31, 16, 0, 0, 1e8, Wednesday, -8 * 60 * 60, "PST"}},
   102  	{1221681866, parsedTime{2008, September, 17, 13, 4, 26, 3e8, Wednesday, -7 * 60 * 60, "PDT"}},
   103  }
   104  
   105  func same(t Time, u *parsedTime) bool {
   106  	// Check aggregates.
   107  	year, month, day := t.Date()
   108  	hour, min, sec := t.Clock()
   109  	name, offset := t.Zone()
   110  	if year != u.Year || month != u.Month || day != u.Day ||
   111  		hour != u.Hour || min != u.Minute || sec != u.Second ||
   112  		name != u.Zone || offset != u.ZoneOffset {
   113  		return false
   114  	}
   115  	// Check individual entries.
   116  	return t.Year() == u.Year &&
   117  		t.Month() == u.Month &&
   118  		t.Day() == u.Day &&
   119  		t.Hour() == u.Hour &&
   120  		t.Minute() == u.Minute &&
   121  		t.Second() == u.Second &&
   122  		t.Nanosecond() == u.Nanosecond &&
   123  		t.Weekday() == u.Weekday
   124  }
   125  
   126  func TestUnixUTC(t *testing.T) {
   127  	for _, test := range utctests {
   128  		sec := test.seconds
   129  		golden := &test.golden
   130  		tm := Unix(sec, 0).UTC()
   131  		newsec := tm.Unix()
   132  		if newsec != sec {
   133  			t.Errorf("Unix(%d, 0).Unix() = %d", sec, newsec)
   134  		}
   135  		if !same(tm, golden) {
   136  			t.Errorf("Unix(%d, 0):  // %#v", sec, tm)
   137  			t.Errorf("  want=%+v", *golden)
   138  			t.Errorf("  have=%v", tm.Format(RFC3339+" MST"))
   139  		}
   140  	}
   141  }
   142  
   143  func TestUnixNanoUTC(t *testing.T) {
   144  	for _, test := range nanoutctests {
   145  		golden := &test.golden
   146  		nsec := test.seconds*1e9 + int64(golden.Nanosecond)
   147  		tm := Unix(0, nsec).UTC()
   148  		newnsec := tm.Unix()*1e9 + int64(tm.Nanosecond())
   149  		if newnsec != nsec {
   150  			t.Errorf("Unix(0, %d).Nanoseconds() = %d", nsec, newnsec)
   151  		}
   152  		if !same(tm, golden) {
   153  			t.Errorf("Unix(0, %d):", nsec)
   154  			t.Errorf("  want=%+v", *golden)
   155  			t.Errorf("  have=%+v", tm.Format(RFC3339+" MST"))
   156  		}
   157  	}
   158  }
   159  
   160  func TestUnix(t *testing.T) {
   161  	for _, test := range localtests {
   162  		sec := test.seconds
   163  		golden := &test.golden
   164  		tm := Unix(sec, 0)
   165  		newsec := tm.Unix()
   166  		if newsec != sec {
   167  			t.Errorf("Unix(%d, 0).Seconds() = %d", sec, newsec)
   168  		}
   169  		if !same(tm, golden) {
   170  			t.Errorf("Unix(%d, 0):", sec)
   171  			t.Errorf("  want=%+v", *golden)
   172  			t.Errorf("  have=%+v", tm.Format(RFC3339+" MST"))
   173  		}
   174  	}
   175  }
   176  
   177  func TestUnixNano(t *testing.T) {
   178  	for _, test := range nanolocaltests {
   179  		golden := &test.golden
   180  		nsec := test.seconds*1e9 + int64(golden.Nanosecond)
   181  		tm := Unix(0, nsec)
   182  		newnsec := tm.Unix()*1e9 + int64(tm.Nanosecond())
   183  		if newnsec != nsec {
   184  			t.Errorf("Unix(0, %d).Seconds() = %d", nsec, newnsec)
   185  		}
   186  		if !same(tm, golden) {
   187  			t.Errorf("Unix(0, %d):", nsec)
   188  			t.Errorf("  want=%+v", *golden)
   189  			t.Errorf("  have=%+v", tm.Format(RFC3339+" MST"))
   190  		}
   191  	}
   192  }
   193  
   194  func TestUnixUTCAndBack(t *testing.T) {
   195  	f := func(sec int64) bool { return Unix(sec, 0).UTC().Unix() == sec }
   196  	f32 := func(sec int32) bool { return f(int64(sec)) }
   197  	cfg := &quick.Config{MaxCount: 10000}
   198  
   199  	// Try a reasonable date first, then the huge ones.
   200  	if err := quick.Check(f32, cfg); err != nil {
   201  		t.Fatal(err)
   202  	}
   203  	if err := quick.Check(f, cfg); err != nil {
   204  		t.Fatal(err)
   205  	}
   206  }
   207  
   208  func TestUnixNanoUTCAndBack(t *testing.T) {
   209  	f := func(nsec int64) bool {
   210  		t := Unix(0, nsec).UTC()
   211  		ns := t.Unix()*1e9 + int64(t.Nanosecond())
   212  		return ns == nsec
   213  	}
   214  	f32 := func(nsec int32) bool { return f(int64(nsec)) }
   215  	cfg := &quick.Config{MaxCount: 10000}
   216  
   217  	// Try a small date first, then the large ones. (The span is only a few hundred years
   218  	// for nanoseconds in an int64.)
   219  	if err := quick.Check(f32, cfg); err != nil {
   220  		t.Fatal(err)
   221  	}
   222  	if err := quick.Check(f, cfg); err != nil {
   223  		t.Fatal(err)
   224  	}
   225  }
   226  
   227  func TestUnixMilli(t *testing.T) {
   228  	f := func(msec int64) bool {
   229  		t := UnixMilli(msec)
   230  		return t.UnixMilli() == msec
   231  	}
   232  	cfg := &quick.Config{MaxCount: 10000}
   233  	if err := quick.Check(f, cfg); err != nil {
   234  		t.Fatal(err)
   235  	}
   236  }
   237  
   238  func TestUnixMicro(t *testing.T) {
   239  	f := func(usec int64) bool {
   240  		t := UnixMicro(usec)
   241  		return t.UnixMicro() == usec
   242  	}
   243  	cfg := &quick.Config{MaxCount: 10000}
   244  	if err := quick.Check(f, cfg); err != nil {
   245  		t.Fatal(err)
   246  	}
   247  }
   248  
   249  // The time routines provide no way to get absolute time
   250  // (seconds since zero), but we need it to compute the right
   251  // answer for bizarre roundings like "to the nearest 3 ns".
   252  // Compute as t - year1 = (t - 1970) + (1970 - 2001) + (2001 - 1).
   253  // t - 1970 is returned by Unix and Nanosecond.
   254  // 1970 - 2001 is -(31*365+8)*86400 = -978307200 seconds.
   255  // 2001 - 1 is 2000*365.2425*86400 = 63113904000 seconds.
   256  const unixToZero = -978307200 + 63113904000
   257  
   258  // abs returns the absolute time stored in t, as seconds and nanoseconds.
   259  func abs(t Time) (sec, nsec int64) {
   260  	unix := t.Unix()
   261  	nano := t.Nanosecond()
   262  	return unix + unixToZero, int64(nano)
   263  }
   264  
   265  // absString returns abs as a decimal string.
   266  func absString(t Time) string {
   267  	sec, nsec := abs(t)
   268  	if sec < 0 {
   269  		sec = -sec
   270  		nsec = -nsec
   271  		if nsec < 0 {
   272  			nsec += 1e9
   273  			sec--
   274  		}
   275  		return fmt.Sprintf("-%d%09d", sec, nsec)
   276  	}
   277  	return fmt.Sprintf("%d%09d", sec, nsec)
   278  }
   279  
   280  var truncateRoundTests = []struct {
   281  	t Time
   282  	d Duration
   283  }{
   284  	{Date(-1, January, 1, 12, 15, 30, 5e8, UTC), 3},
   285  	{Date(-1, January, 1, 12, 15, 31, 5e8, UTC), 3},
   286  	{Date(2012, January, 1, 12, 15, 30, 5e8, UTC), Second},
   287  	{Date(2012, January, 1, 12, 15, 31, 5e8, UTC), Second},
   288  	{Unix(-19012425939, 649146258), 7435029458905025217}, // 5.8*d rounds to 6*d, but .8*d+.8*d < 0 < d
   289  }
   290  
   291  func TestTruncateRound(t *testing.T) {
   292  	var (
   293  		bsec  = new(big.Int)
   294  		bnsec = new(big.Int)
   295  		bd    = new(big.Int)
   296  		bt    = new(big.Int)
   297  		br    = new(big.Int)
   298  		bq    = new(big.Int)
   299  		b1e9  = new(big.Int)
   300  	)
   301  
   302  	b1e9.SetInt64(1e9)
   303  
   304  	testOne := func(ti, tns, di int64) bool {
   305  		t.Helper()
   306  
   307  		t0 := Unix(ti, tns).UTC()
   308  		d := Duration(di)
   309  		if d < 0 {
   310  			d = -d
   311  		}
   312  		if d <= 0 {
   313  			d = 1
   314  		}
   315  
   316  		// Compute bt = absolute nanoseconds.
   317  		sec, nsec := abs(t0)
   318  		bsec.SetInt64(sec)
   319  		bnsec.SetInt64(nsec)
   320  		bt.Mul(bsec, b1e9)
   321  		bt.Add(bt, bnsec)
   322  
   323  		// Compute quotient and remainder mod d.
   324  		bd.SetInt64(int64(d))
   325  		bq.DivMod(bt, bd, br)
   326  
   327  		// To truncate, subtract remainder.
   328  		// br is < d, so it fits in an int64.
   329  		r := br.Int64()
   330  		t1 := t0.Add(-Duration(r))
   331  
   332  		// Check that time.Truncate works.
   333  		if trunc := t0.Truncate(d); trunc != t1 {
   334  			t.Errorf("Time.Truncate(%s, %s) = %s, want %s\n"+
   335  				"%v trunc %v =\n%v want\n%v",
   336  				t0.Format(RFC3339Nano), d, trunc, t1.Format(RFC3339Nano),
   337  				absString(t0), int64(d), absString(trunc), absString(t1))
   338  			return false
   339  		}
   340  
   341  		// To round, add d back if remainder r > d/2 or r == exactly d/2.
   342  		// The commented out code would round half to even instead of up,
   343  		// but that makes it time-zone dependent, which is a bit strange.
   344  		if r > int64(d)/2 || r+r == int64(d) /*&& bq.Bit(0) == 1*/ {
   345  			t1 = t1.Add(d)
   346  		}
   347  
   348  		// Check that time.Round works.
   349  		if rnd := t0.Round(d); rnd != t1 {
   350  			t.Errorf("Time.Round(%s, %s) = %s, want %s\n"+
   351  				"%v round %v =\n%v want\n%v",
   352  				t0.Format(RFC3339Nano), d, rnd, t1.Format(RFC3339Nano),
   353  				absString(t0), int64(d), absString(rnd), absString(t1))
   354  			return false
   355  		}
   356  		return true
   357  	}
   358  
   359  	// manual test cases
   360  	for _, tt := range truncateRoundTests {
   361  		testOne(tt.t.Unix(), int64(tt.t.Nanosecond()), int64(tt.d))
   362  	}
   363  
   364  	// exhaustive near 0
   365  	for i := 0; i < 100; i++ {
   366  		for j := 1; j < 100; j++ {
   367  			testOne(unixToZero, int64(i), int64(j))
   368  			testOne(unixToZero, -int64(i), int64(j))
   369  			if t.Failed() {
   370  				return
   371  			}
   372  		}
   373  	}
   374  
   375  	if t.Failed() {
   376  		return
   377  	}
   378  
   379  	// randomly generated test cases
   380  	cfg := &quick.Config{MaxCount: 100000}
   381  	if testing.Short() {
   382  		cfg.MaxCount = 1000
   383  	}
   384  
   385  	// divisors of Second
   386  	f1 := func(ti int64, tns int32, logdi int32) bool {
   387  		d := Duration(1)
   388  		a, b := uint(logdi%9), (logdi>>16)%9
   389  		d <<= a
   390  		for i := 0; i < int(b); i++ {
   391  			d *= 5
   392  		}
   393  
   394  		// Make room for unix ↔ internal conversion.
   395  		// We don't care about behavior too close to ± 2^63 Unix seconds.
   396  		// It is full of wraparounds but will never happen in a reasonable program.
   397  		// (Or maybe not? See go.dev/issue/20678. In any event, they're not handled today.)
   398  		ti >>= 1
   399  
   400  		return testOne(ti, int64(tns), int64(d))
   401  	}
   402  	quick.Check(f1, cfg)
   403  
   404  	// multiples of Second
   405  	f2 := func(ti int64, tns int32, di int32) bool {
   406  		d := Duration(di) * Second
   407  		if d < 0 {
   408  			d = -d
   409  		}
   410  		ti >>= 1 // see comment in f1
   411  		return testOne(ti, int64(tns), int64(d))
   412  	}
   413  	quick.Check(f2, cfg)
   414  
   415  	// halfway cases
   416  	f3 := func(tns, di int64) bool {
   417  		di &= 0xfffffffe
   418  		if di == 0 {
   419  			di = 2
   420  		}
   421  		tns -= tns % di
   422  		if tns < 0 {
   423  			tns += di / 2
   424  		} else {
   425  			tns -= di / 2
   426  		}
   427  		return testOne(0, tns, di)
   428  	}
   429  	quick.Check(f3, cfg)
   430  
   431  	// full generality
   432  	f4 := func(ti int64, tns int32, di int64) bool {
   433  		ti >>= 1 // see comment in f1
   434  		return testOne(ti, int64(tns), di)
   435  	}
   436  	quick.Check(f4, cfg)
   437  }
   438  
   439  type ISOWeekTest struct {
   440  	year       int // year
   441  	month, day int // month and day
   442  	yex        int // expected year
   443  	wex        int // expected week
   444  }
   445  
   446  var isoWeekTests = []ISOWeekTest{
   447  	{1981, 1, 1, 1981, 1}, {1982, 1, 1, 1981, 53}, {1983, 1, 1, 1982, 52},
   448  	{1984, 1, 1, 1983, 52}, {1985, 1, 1, 1985, 1}, {1986, 1, 1, 1986, 1},
   449  	{1987, 1, 1, 1987, 1}, {1988, 1, 1, 1987, 53}, {1989, 1, 1, 1988, 52},
   450  	{1990, 1, 1, 1990, 1}, {1991, 1, 1, 1991, 1}, {1992, 1, 1, 1992, 1},
   451  	{1993, 1, 1, 1992, 53}, {1994, 1, 1, 1993, 52}, {1995, 1, 2, 1995, 1},
   452  	{1996, 1, 1, 1996, 1}, {1996, 1, 7, 1996, 1}, {1996, 1, 8, 1996, 2},
   453  	{1997, 1, 1, 1997, 1}, {1998, 1, 1, 1998, 1}, {1999, 1, 1, 1998, 53},
   454  	{2000, 1, 1, 1999, 52}, {2001, 1, 1, 2001, 1}, {2002, 1, 1, 2002, 1},
   455  	{2003, 1, 1, 2003, 1}, {2004, 1, 1, 2004, 1}, {2005, 1, 1, 2004, 53},
   456  	{2006, 1, 1, 2005, 52}, {2007, 1, 1, 2007, 1}, {2008, 1, 1, 2008, 1},
   457  	{2009, 1, 1, 2009, 1}, {2010, 1, 1, 2009, 53}, {2010, 1, 1, 2009, 53},
   458  	{2011, 1, 1, 2010, 52}, {2011, 1, 2, 2010, 52}, {2011, 1, 3, 2011, 1},
   459  	{2011, 1, 4, 2011, 1}, {2011, 1, 5, 2011, 1}, {2011, 1, 6, 2011, 1},
   460  	{2011, 1, 7, 2011, 1}, {2011, 1, 8, 2011, 1}, {2011, 1, 9, 2011, 1},
   461  	{2011, 1, 10, 2011, 2}, {2011, 1, 11, 2011, 2}, {2011, 6, 12, 2011, 23},
   462  	{2011, 6, 13, 2011, 24}, {2011, 12, 25, 2011, 51}, {2011, 12, 26, 2011, 52},
   463  	{2011, 12, 27, 2011, 52}, {2011, 12, 28, 2011, 52}, {2011, 12, 29, 2011, 52},
   464  	{2011, 12, 30, 2011, 52}, {2011, 12, 31, 2011, 52}, {1995, 1, 1, 1994, 52},
   465  	{2012, 1, 1, 2011, 52}, {2012, 1, 2, 2012, 1}, {2012, 1, 8, 2012, 1},
   466  	{2012, 1, 9, 2012, 2}, {2012, 12, 23, 2012, 51}, {2012, 12, 24, 2012, 52},
   467  	{2012, 12, 30, 2012, 52}, {2012, 12, 31, 2013, 1}, {2013, 1, 1, 2013, 1},
   468  	{2013, 1, 6, 2013, 1}, {2013, 1, 7, 2013, 2}, {2013, 12, 22, 2013, 51},
   469  	{2013, 12, 23, 2013, 52}, {2013, 12, 29, 2013, 52}, {2013, 12, 30, 2014, 1},
   470  	{2014, 1, 1, 2014, 1}, {2014, 1, 5, 2014, 1}, {2014, 1, 6, 2014, 2},
   471  	{2015, 1, 1, 2015, 1}, {2016, 1, 1, 2015, 53}, {2017, 1, 1, 2016, 52},
   472  	{2018, 1, 1, 2018, 1}, {2019, 1, 1, 2019, 1}, {2020, 1, 1, 2020, 1},
   473  	{2021, 1, 1, 2020, 53}, {2022, 1, 1, 2021, 52}, {2023, 1, 1, 2022, 52},
   474  	{2024, 1, 1, 2024, 1}, {2025, 1, 1, 2025, 1}, {2026, 1, 1, 2026, 1},
   475  	{2027, 1, 1, 2026, 53}, {2028, 1, 1, 2027, 52}, {2029, 1, 1, 2029, 1},
   476  	{2030, 1, 1, 2030, 1}, {2031, 1, 1, 2031, 1}, {2032, 1, 1, 2032, 1},
   477  	{2033, 1, 1, 2032, 53}, {2034, 1, 1, 2033, 52}, {2035, 1, 1, 2035, 1},
   478  	{2036, 1, 1, 2036, 1}, {2037, 1, 1, 2037, 1}, {2038, 1, 1, 2037, 53},
   479  	{2039, 1, 1, 2038, 52}, {2040, 1, 1, 2039, 52},
   480  }
   481  
   482  func TestISOWeek(t *testing.T) {
   483  	// Selected dates and corner cases
   484  	for _, wt := range isoWeekTests {
   485  		dt := Date(wt.year, Month(wt.month), wt.day, 0, 0, 0, 0, UTC)
   486  		y, w := dt.ISOWeek()
   487  		if w != wt.wex || y != wt.yex {
   488  			t.Errorf("got %d/%d; expected %d/%d for %d-%02d-%02d",
   489  				y, w, wt.yex, wt.wex, wt.year, wt.month, wt.day)
   490  		}
   491  	}
   492  
   493  	// The only real invariant: Jan 04 is in week 1
   494  	for year := 1950; year < 2100; year++ {
   495  		if y, w := Date(year, January, 4, 0, 0, 0, 0, UTC).ISOWeek(); y != year || w != 1 {
   496  			t.Errorf("got %d/%d; expected %d/1 for Jan 04", y, w, year)
   497  		}
   498  	}
   499  }
   500  
   501  type YearDayTest struct {
   502  	year, month, day int
   503  	yday             int
   504  }
   505  
   506  // Test YearDay in several different scenarios
   507  // and corner cases
   508  var yearDayTests = []YearDayTest{
   509  	// Non-leap-year tests
   510  	{2007, 1, 1, 1},
   511  	{2007, 1, 15, 15},
   512  	{2007, 2, 1, 32},
   513  	{2007, 2, 15, 46},
   514  	{2007, 3, 1, 60},
   515  	{2007, 3, 15, 74},
   516  	{2007, 4, 1, 91},
   517  	{2007, 12, 31, 365},
   518  
   519  	// Leap-year tests
   520  	{2008, 1, 1, 1},
   521  	{2008, 1, 15, 15},
   522  	{2008, 2, 1, 32},
   523  	{2008, 2, 15, 46},
   524  	{2008, 3, 1, 61},
   525  	{2008, 3, 15, 75},
   526  	{2008, 4, 1, 92},
   527  	{2008, 12, 31, 366},
   528  
   529  	// Looks like leap-year (but isn't) tests
   530  	{1900, 1, 1, 1},
   531  	{1900, 1, 15, 15},
   532  	{1900, 2, 1, 32},
   533  	{1900, 2, 15, 46},
   534  	{1900, 3, 1, 60},
   535  	{1900, 3, 15, 74},
   536  	{1900, 4, 1, 91},
   537  	{1900, 12, 31, 365},
   538  
   539  	// Year one tests (non-leap)
   540  	{1, 1, 1, 1},
   541  	{1, 1, 15, 15},
   542  	{1, 2, 1, 32},
   543  	{1, 2, 15, 46},
   544  	{1, 3, 1, 60},
   545  	{1, 3, 15, 74},
   546  	{1, 4, 1, 91},
   547  	{1, 12, 31, 365},
   548  
   549  	// Year minus one tests (non-leap)
   550  	{-1, 1, 1, 1},
   551  	{-1, 1, 15, 15},
   552  	{-1, 2, 1, 32},
   553  	{-1, 2, 15, 46},
   554  	{-1, 3, 1, 60},
   555  	{-1, 3, 15, 74},
   556  	{-1, 4, 1, 91},
   557  	{-1, 12, 31, 365},
   558  
   559  	// 400 BC tests (leap-year)
   560  	{-400, 1, 1, 1},
   561  	{-400, 1, 15, 15},
   562  	{-400, 2, 1, 32},
   563  	{-400, 2, 15, 46},
   564  	{-400, 3, 1, 61},
   565  	{-400, 3, 15, 75},
   566  	{-400, 4, 1, 92},
   567  	{-400, 12, 31, 366},
   568  
   569  	// Special Cases
   570  
   571  	// Gregorian calendar change (no effect)
   572  	{1582, 10, 4, 277},
   573  	{1582, 10, 15, 288},
   574  }
   575  
   576  // Check to see if YearDay is location sensitive
   577  var yearDayLocations = []*Location{
   578  	FixedZone("UTC-8", -8*60*60),
   579  	FixedZone("UTC-4", -4*60*60),
   580  	UTC,
   581  	FixedZone("UTC+4", 4*60*60),
   582  	FixedZone("UTC+8", 8*60*60),
   583  }
   584  
   585  func TestYearDay(t *testing.T) {
   586  	for i, loc := range yearDayLocations {
   587  		for _, ydt := range yearDayTests {
   588  			dt := Date(ydt.year, Month(ydt.month), ydt.day, 0, 0, 0, 0, loc)
   589  			yday := dt.YearDay()
   590  			if yday != ydt.yday {
   591  				t.Errorf("Date(%d-%02d-%02d in %v).YearDay() = %d, want %d",
   592  					ydt.year, ydt.month, ydt.day, loc, yday, ydt.yday)
   593  				continue
   594  			}
   595  
   596  			if ydt.year < 0 || ydt.year > 9999 {
   597  				continue
   598  			}
   599  			f := fmt.Sprintf("%04d-%02d-%02d %03d %+.2d00",
   600  				ydt.year, ydt.month, ydt.day, ydt.yday, (i-2)*4)
   601  			dt1, err := Parse("2006-01-02 002 -0700", f)
   602  			if err != nil {
   603  				t.Errorf(`Parse("2006-01-02 002 -0700", %q): %v`, f, err)
   604  				continue
   605  			}
   606  			if !dt1.Equal(dt) {
   607  				t.Errorf(`Parse("2006-01-02 002 -0700", %q) = %v, want %v`, f, dt1, dt)
   608  			}
   609  		}
   610  	}
   611  }
   612  
   613  var durationTests = []struct {
   614  	str string
   615  	d   Duration
   616  }{
   617  	{"0s", 0},
   618  	{"1ns", 1 * Nanosecond},
   619  	{"1.1µs", 1100 * Nanosecond},
   620  	{"2.2ms", 2200 * Microsecond},
   621  	{"3.3s", 3300 * Millisecond},
   622  	{"4m5s", 4*Minute + 5*Second},
   623  	{"4m5.001s", 4*Minute + 5001*Millisecond},
   624  	{"5h6m7.001s", 5*Hour + 6*Minute + 7001*Millisecond},
   625  	{"8m0.000000001s", 8*Minute + 1*Nanosecond},
   626  	{"2562047h47m16.854775807s", 1<<63 - 1},
   627  	{"-2562047h47m16.854775808s", -1 << 63},
   628  }
   629  
   630  func TestDurationString(t *testing.T) {
   631  	for _, tt := range durationTests {
   632  		if str := tt.d.String(); str != tt.str {
   633  			t.Errorf("Duration(%d).String() = %s, want %s", int64(tt.d), str, tt.str)
   634  		}
   635  		if tt.d > 0 {
   636  			if str := (-tt.d).String(); str != "-"+tt.str {
   637  				t.Errorf("Duration(%d).String() = %s, want %s", int64(-tt.d), str, "-"+tt.str)
   638  			}
   639  		}
   640  	}
   641  }
   642  
   643  var dateTests = []struct {
   644  	year, month, day, hour, min, sec, nsec int
   645  	z                                      *Location
   646  	unix                                   int64
   647  }{
   648  	{2011, 11, 6, 1, 0, 0, 0, Local, 1320566400},   // 1:00:00 PDT
   649  	{2011, 11, 6, 1, 59, 59, 0, Local, 1320569999}, // 1:59:59 PDT
   650  	{2011, 11, 6, 2, 0, 0, 0, Local, 1320573600},   // 2:00:00 PST
   651  
   652  	{2011, 3, 13, 1, 0, 0, 0, Local, 1300006800},   // 1:00:00 PST
   653  	{2011, 3, 13, 1, 59, 59, 0, Local, 1300010399}, // 1:59:59 PST
   654  	{2011, 3, 13, 3, 0, 0, 0, Local, 1300010400},   // 3:00:00 PDT
   655  	{2011, 3, 13, 2, 30, 0, 0, Local, 1300008600},  // 2:30:00 PDT ≡ 1:30 PST
   656  	{2012, 12, 24, 0, 0, 0, 0, Local, 1356336000},  // Leap year
   657  
   658  	// Many names for Fri Nov 18 7:56:35 PST 2011
   659  	{2011, 11, 18, 7, 56, 35, 0, Local, 1321631795},                 // Nov 18 7:56:35
   660  	{2011, 11, 19, -17, 56, 35, 0, Local, 1321631795},               // Nov 19 -17:56:35
   661  	{2011, 11, 17, 31, 56, 35, 0, Local, 1321631795},                // Nov 17 31:56:35
   662  	{2011, 11, 18, 6, 116, 35, 0, Local, 1321631795},                // Nov 18 6:116:35
   663  	{2011, 10, 49, 7, 56, 35, 0, Local, 1321631795},                 // Oct 49 7:56:35
   664  	{2011, 11, 18, 7, 55, 95, 0, Local, 1321631795},                 // Nov 18 7:55:95
   665  	{2011, 11, 18, 7, 56, 34, 1e9, Local, 1321631795},               // Nov 18 7:56:34 + 10⁹ns
   666  	{2011, 12, -12, 7, 56, 35, 0, Local, 1321631795},                // Dec -21 7:56:35
   667  	{2012, 1, -43, 7, 56, 35, 0, Local, 1321631795},                 // Jan -52 7:56:35 2012
   668  	{2012, int(January - 2), 18, 7, 56, 35, 0, Local, 1321631795},   // (Jan-2) 18 7:56:35 2012
   669  	{2010, int(December + 11), 18, 7, 56, 35, 0, Local, 1321631795}, // (Dec+11) 18 7:56:35 2010
   670  	{1970, 1, 15297, 7, 56, 35, 0, Local, 1321631795},               // large number of days
   671  
   672  	{1970, 1, -25508, 0, 0, 0, 0, Local, -2203948800}, // negative Unix time
   673  }
   674  
   675  func TestDate(t *testing.T) {
   676  	for _, tt := range dateTests {
   677  		time := Date(tt.year, Month(tt.month), tt.day, tt.hour, tt.min, tt.sec, tt.nsec, tt.z)
   678  		want := Unix(tt.unix, 0)
   679  		if !time.Equal(want) {
   680  			t.Errorf("Date(%d, %d, %d, %d, %d, %d, %d, %s) = %v, want %v",
   681  				tt.year, tt.month, tt.day, tt.hour, tt.min, tt.sec, tt.nsec, tt.z,
   682  				time, want)
   683  		}
   684  	}
   685  }
   686  
   687  // Several ways of getting from
   688  // Fri Nov 18 7:56:35 PST 2011
   689  // to
   690  // Thu Mar 19 7:56:35 PST 2016
   691  var addDateTests = []struct {
   692  	years, months, days int
   693  }{
   694  	{4, 4, 1},
   695  	{3, 16, 1},
   696  	{3, 15, 30},
   697  	{5, -6, -18 - 30 - 12},
   698  }
   699  
   700  func TestAddDate(t *testing.T) {
   701  	t0 := Date(2011, 11, 18, 7, 56, 35, 0, UTC)
   702  	t1 := Date(2016, 3, 19, 7, 56, 35, 0, UTC)
   703  	for _, at := range addDateTests {
   704  		time := t0.AddDate(at.years, at.months, at.days)
   705  		if !time.Equal(t1) {
   706  			t.Errorf("AddDate(%d, %d, %d) = %v, want %v",
   707  				at.years, at.months, at.days,
   708  				time, t1)
   709  		}
   710  	}
   711  
   712  	t2 := Date(1899, 12, 31, 0, 0, 0, 0, UTC)
   713  	days := t2.Unix() / (24 * 60 * 60)
   714  	t3 := Unix(0, 0).AddDate(0, 0, int(days))
   715  	if !t2.Equal(t3) {
   716  		t.Errorf("Adddate(0, 0, %d) = %v, want %v", days, t3, t2)
   717  	}
   718  }
   719  
   720  var daysInTests = []struct {
   721  	year, month, di int
   722  }{
   723  	{2011, 1, 31},  // January, first month, 31 days
   724  	{2011, 2, 28},  // February, non-leap year, 28 days
   725  	{2012, 2, 29},  // February, leap year, 29 days
   726  	{2011, 6, 30},  // June, 30 days
   727  	{2011, 12, 31}, // December, last month, 31 days
   728  }
   729  
   730  func TestDaysIn(t *testing.T) {
   731  	// The daysIn function is not exported.
   732  	// Test the daysIn function via the `var DaysIn = daysIn`
   733  	// statement in the internal_test.go file.
   734  	for _, tt := range daysInTests {
   735  		di := DaysIn(Month(tt.month), tt.year)
   736  		if di != tt.di {
   737  			t.Errorf("got %d; expected %d for %d-%02d",
   738  				di, tt.di, tt.year, tt.month)
   739  		}
   740  	}
   741  }
   742  
   743  func TestAddToExactSecond(t *testing.T) {
   744  	// Add an amount to the current time to round it up to the next exact second.
   745  	// This test checks that the nsec field still lies within the range [0, 999999999].
   746  	t1 := Now()
   747  	t2 := t1.Add(Second - Duration(t1.Nanosecond()))
   748  	sec := (t1.Second() + 1) % 60
   749  	if t2.Second() != sec || t2.Nanosecond() != 0 {
   750  		t.Errorf("sec = %d, nsec = %d, want sec = %d, nsec = 0", t2.Second(), t2.Nanosecond(), sec)
   751  	}
   752  }
   753  
   754  func equalTimeAndZone(a, b Time) bool {
   755  	aname, aoffset := a.Zone()
   756  	bname, boffset := b.Zone()
   757  	return a.Equal(b) && aoffset == boffset && aname == bname
   758  }
   759  
   760  var gobTests = []Time{
   761  	Date(0, 1, 2, 3, 4, 5, 6, UTC),
   762  	Date(7, 8, 9, 10, 11, 12, 13, FixedZone("", 0)),
   763  	Unix(81985467080890095, 0x76543210), // Time.sec: 0x0123456789ABCDEF
   764  	{},                                  // nil location
   765  	Date(1, 2, 3, 4, 5, 6, 7, FixedZone("", 32767*60)),
   766  	Date(1, 2, 3, 4, 5, 6, 7, FixedZone("", -32768*60)),
   767  }
   768  
   769  func TestTimeGob(t *testing.T) {
   770  	var b bytes.Buffer
   771  	enc := gob.NewEncoder(&b)
   772  	dec := gob.NewDecoder(&b)
   773  	for _, tt := range gobTests {
   774  		var gobtt Time
   775  		if err := enc.Encode(&tt); err != nil {
   776  			t.Errorf("%v gob Encode error = %q, want nil", tt, err)
   777  		} else if err := dec.Decode(&gobtt); err != nil {
   778  			t.Errorf("%v gob Decode error = %q, want nil", tt, err)
   779  		} else if !equalTimeAndZone(gobtt, tt) {
   780  			t.Errorf("Decoded time = %v, want %v", gobtt, tt)
   781  		}
   782  		b.Reset()
   783  	}
   784  }
   785  
   786  var invalidEncodingTests = []struct {
   787  	bytes []byte
   788  	want  string
   789  }{
   790  	{[]byte{}, "Time.UnmarshalBinary: no data"},
   791  	{[]byte{0, 2, 3}, "Time.UnmarshalBinary: unsupported version"},
   792  	{[]byte{1, 2, 3}, "Time.UnmarshalBinary: invalid length"},
   793  }
   794  
   795  func TestInvalidTimeGob(t *testing.T) {
   796  	for _, tt := range invalidEncodingTests {
   797  		var ignored Time
   798  		err := ignored.GobDecode(tt.bytes)
   799  		if err == nil || err.Error() != tt.want {
   800  			t.Errorf("time.GobDecode(%#v) error = %v, want %v", tt.bytes, err, tt.want)
   801  		}
   802  		err = ignored.UnmarshalBinary(tt.bytes)
   803  		if err == nil || err.Error() != tt.want {
   804  			t.Errorf("time.UnmarshalBinary(%#v) error = %v, want %v", tt.bytes, err, tt.want)
   805  		}
   806  	}
   807  }
   808  
   809  var notEncodableTimes = []struct {
   810  	time Time
   811  	want string
   812  }{
   813  	{Date(0, 1, 2, 3, 4, 5, 6, FixedZone("", -1*60)), "Time.MarshalBinary: unexpected zone offset"},
   814  	{Date(0, 1, 2, 3, 4, 5, 6, FixedZone("", -32769*60)), "Time.MarshalBinary: unexpected zone offset"},
   815  	{Date(0, 1, 2, 3, 4, 5, 6, FixedZone("", 32768*60)), "Time.MarshalBinary: unexpected zone offset"},
   816  }
   817  
   818  func TestNotGobEncodableTime(t *testing.T) {
   819  	for _, tt := range notEncodableTimes {
   820  		_, err := tt.time.GobEncode()
   821  		if err == nil || err.Error() != tt.want {
   822  			t.Errorf("%v GobEncode error = %v, want %v", tt.time, err, tt.want)
   823  		}
   824  		_, err = tt.time.MarshalBinary()
   825  		if err == nil || err.Error() != tt.want {
   826  			t.Errorf("%v MarshalBinary error = %v, want %v", tt.time, err, tt.want)
   827  		}
   828  	}
   829  }
   830  
   831  var jsonTests = []struct {
   832  	time Time
   833  	json string
   834  }{
   835  	{Date(9999, 4, 12, 23, 20, 50, 520*1e6, UTC), `"9999-04-12T23:20:50.52Z"`},
   836  	{Date(1996, 12, 19, 16, 39, 57, 0, Local), `"1996-12-19T16:39:57-08:00"`},
   837  	{Date(0, 1, 1, 0, 0, 0, 1, FixedZone("", 1*60)), `"0000-01-01T00:00:00.000000001+00:01"`},
   838  	{Date(2020, 1, 1, 0, 0, 0, 0, FixedZone("", 23*60*60+59*60)), `"2020-01-01T00:00:00+23:59"`},
   839  }
   840  
   841  func TestTimeJSON(t *testing.T) {
   842  	for _, tt := range jsonTests {
   843  		var jsonTime Time
   844  
   845  		if jsonBytes, err := json.Marshal(tt.time); err != nil {
   846  			t.Errorf("%v json.Marshal error = %v, want nil", tt.time, err)
   847  		} else if string(jsonBytes) != tt.json {
   848  			t.Errorf("%v JSON = %#q, want %#q", tt.time, string(jsonBytes), tt.json)
   849  		} else if err = json.Unmarshal(jsonBytes, &jsonTime); err != nil {
   850  			t.Errorf("%v json.Unmarshal error = %v, want nil", tt.time, err)
   851  		} else if !equalTimeAndZone(jsonTime, tt.time) {
   852  			t.Errorf("Unmarshaled time = %v, want %v", jsonTime, tt.time)
   853  		}
   854  	}
   855  }
   856  
   857  func TestUnmarshalInvalidTimes(t *testing.T) {
   858  	tests := []struct {
   859  		in   string
   860  		want string
   861  	}{
   862  		{`{}`, "Time.UnmarshalJSON: input is not a JSON string"},
   863  		{`[]`, "Time.UnmarshalJSON: input is not a JSON string"},
   864  		{`"2000-01-01T1:12:34Z"`, `<nil>`},
   865  		{`"2000-01-01T00:00:00,000Z"`, `<nil>`},
   866  		{`"2000-01-01T00:00:00+24:00"`, `<nil>`},
   867  		{`"2000-01-01T00:00:00+00:60"`, `<nil>`},
   868  		{`"2000-01-01T00:00:00+123:45"`, `parsing time "2000-01-01T00:00:00+123:45" as "2006-01-02T15:04:05Z07:00": cannot parse "+123:45" as "Z07:00"`},
   869  	}
   870  
   871  	for _, tt := range tests {
   872  		var ts Time
   873  
   874  		want := tt.want
   875  		err := json.Unmarshal([]byte(tt.in), &ts)
   876  		if fmt.Sprint(err) != want {
   877  			t.Errorf("Time.UnmarshalJSON(%s) = %v, want %v", tt.in, err, want)
   878  		}
   879  
   880  		if strings.HasPrefix(tt.in, `"`) && strings.HasSuffix(tt.in, `"`) {
   881  			err = ts.UnmarshalText([]byte(strings.Trim(tt.in, `"`)))
   882  			if fmt.Sprint(err) != want {
   883  				t.Errorf("Time.UnmarshalText(%s) = %v, want %v", tt.in, err, want)
   884  			}
   885  		}
   886  	}
   887  }
   888  
   889  func TestMarshalInvalidTimes(t *testing.T) {
   890  	tests := []struct {
   891  		time Time
   892  		want string
   893  	}{
   894  		{Date(10000, 1, 1, 0, 0, 0, 0, UTC), "Time.MarshalJSON: year outside of range [0,9999]"},
   895  		{Date(-998, 1, 1, 0, 0, 0, 0, UTC).Add(-Second), "Time.MarshalJSON: year outside of range [0,9999]"},
   896  		{Date(0, 1, 1, 0, 0, 0, 0, UTC).Add(-Nanosecond), "Time.MarshalJSON: year outside of range [0,9999]"},
   897  		{Date(2020, 1, 1, 0, 0, 0, 0, FixedZone("", 24*60*60)), "Time.MarshalJSON: timezone hour outside of range [0,23]"},
   898  		{Date(2020, 1, 1, 0, 0, 0, 0, FixedZone("", 123*60*60)), "Time.MarshalJSON: timezone hour outside of range [0,23]"},
   899  	}
   900  
   901  	for _, tt := range tests {
   902  		want := tt.want
   903  		b, err := tt.time.MarshalJSON()
   904  		switch {
   905  		case b != nil:
   906  			t.Errorf("(%v).MarshalText() = %q, want nil", tt.time, b)
   907  		case err == nil || err.Error() != want:
   908  			t.Errorf("(%v).MarshalJSON() error = %v, want %v", tt.time, err, want)
   909  		}
   910  
   911  		want = strings.ReplaceAll(tt.want, "JSON", "Text")
   912  		b, err = tt.time.MarshalText()
   913  		switch {
   914  		case b != nil:
   915  			t.Errorf("(%v).MarshalText() = %q, want nil", tt.time, b)
   916  		case err == nil || err.Error() != want:
   917  			t.Errorf("(%v).MarshalText() error = %v, want %v", tt.time, err, want)
   918  		}
   919  
   920  		buf := make([]byte, 0, 64)
   921  		want = strings.ReplaceAll(tt.want, "MarshalJSON", "AppendText")
   922  		b, err = tt.time.AppendText(buf)
   923  		switch {
   924  		case b != nil:
   925  			t.Errorf("(%v).AppendText() = %q, want nil", tt.time, b)
   926  		case err == nil || err.Error() != want:
   927  			t.Errorf("(%v).AppendText() error = %v, want %v", tt.time, err, want)
   928  		}
   929  	}
   930  }
   931  
   932  var parseDurationTests = []struct {
   933  	in   string
   934  	want Duration
   935  }{
   936  	// simple
   937  	{"0", 0},
   938  	{"5s", 5 * Second},
   939  	{"30s", 30 * Second},
   940  	{"1478s", 1478 * Second},
   941  	// sign
   942  	{"-5s", -5 * Second},
   943  	{"+5s", 5 * Second},
   944  	{"-0", 0},
   945  	{"+0", 0},
   946  	// decimal
   947  	{"5.0s", 5 * Second},
   948  	{"5.6s", 5*Second + 600*Millisecond},
   949  	{"5.s", 5 * Second},
   950  	{".5s", 500 * Millisecond},
   951  	{"1.0s", 1 * Second},
   952  	{"1.00s", 1 * Second},
   953  	{"1.004s", 1*Second + 4*Millisecond},
   954  	{"1.0040s", 1*Second + 4*Millisecond},
   955  	{"100.00100s", 100*Second + 1*Millisecond},
   956  	// different units
   957  	{"10ns", 10 * Nanosecond},
   958  	{"11us", 11 * Microsecond},
   959  	{"12µs", 12 * Microsecond}, // U+00B5
   960  	{"12μs", 12 * Microsecond}, // U+03BC
   961  	{"13ms", 13 * Millisecond},
   962  	{"14s", 14 * Second},
   963  	{"15m", 15 * Minute},
   964  	{"16h", 16 * Hour},
   965  	// composite durations
   966  	{"3h30m", 3*Hour + 30*Minute},
   967  	{"10.5s4m", 4*Minute + 10*Second + 500*Millisecond},
   968  	{"-2m3.4s", -(2*Minute + 3*Second + 400*Millisecond)},
   969  	{"1h2m3s4ms5us6ns", 1*Hour + 2*Minute + 3*Second + 4*Millisecond + 5*Microsecond + 6*Nanosecond},
   970  	{"39h9m14.425s", 39*Hour + 9*Minute + 14*Second + 425*Millisecond},
   971  	// large value
   972  	{"52763797000ns", 52763797000 * Nanosecond},
   973  	// more than 9 digits after decimal point, see https://golang.org/issue/6617
   974  	{"0.3333333333333333333h", 20 * Minute},
   975  	// 9007199254740993 = 1<<53+1 cannot be stored precisely in a float64
   976  	{"9007199254740993ns", (1<<53 + 1) * Nanosecond},
   977  	// largest duration that can be represented by int64 in nanoseconds
   978  	{"9223372036854775807ns", (1<<63 - 1) * Nanosecond},
   979  	{"9223372036854775.807us", (1<<63 - 1) * Nanosecond},
   980  	{"9223372036s854ms775us807ns", (1<<63 - 1) * Nanosecond},
   981  	{"-9223372036854775808ns", -1 << 63 * Nanosecond},
   982  	{"-9223372036854775.808us", -1 << 63 * Nanosecond},
   983  	{"-9223372036s854ms775us808ns", -1 << 63 * Nanosecond},
   984  	// largest negative value
   985  	{"-9223372036854775808ns", -1 << 63 * Nanosecond},
   986  	// largest negative round trip value, see https://golang.org/issue/48629
   987  	{"-2562047h47m16.854775808s", -1 << 63 * Nanosecond},
   988  	// huge string; issue 15011.
   989  	{"0.100000000000000000000h", 6 * Minute},
   990  	// This value tests the first overflow check in leadingFraction.
   991  	{"0.830103483285477580700h", 49*Minute + 48*Second + 372539827*Nanosecond},
   992  }
   993  
   994  func TestParseDuration(t *testing.T) {
   995  	for _, tc := range parseDurationTests {
   996  		d, err := ParseDuration(tc.in)
   997  		if err != nil || d != tc.want {
   998  			t.Errorf("ParseDuration(%q) = %v, %v, want %v, nil", tc.in, d, err, tc.want)
   999  		}
  1000  	}
  1001  }
  1002  
  1003  var parseDurationErrorTests = []struct {
  1004  	in     string
  1005  	expect string
  1006  }{
  1007  	// invalid
  1008  	{"", `""`},
  1009  	{"3", `"3"`},
  1010  	{"-", `"-"`},
  1011  	{"s", `"s"`},
  1012  	{".", `"."`},
  1013  	{"-.", `"-."`},
  1014  	{".s", `".s"`},
  1015  	{"+.s", `"+.s"`},
  1016  	{"1d", `"1d"`},
  1017  	{"\x85\x85", `"\x85\x85"`},
  1018  	{"\xffff", `"\xffff"`},
  1019  	{"hello \xffff world", `"hello \xffff world"`},
  1020  	{"\uFFFD", `"\xef\xbf\xbd"`},                                             // utf8.RuneError
  1021  	{"\uFFFD hello \uFFFD world", `"\xef\xbf\xbd hello \xef\xbf\xbd world"`}, // utf8.RuneError
  1022  	// overflow
  1023  	{"9223372036854775810ns", `"9223372036854775810ns"`},
  1024  	{"9223372036854775808ns", `"9223372036854775808ns"`},
  1025  	{"-9223372036854775809ns", `"-9223372036854775809ns"`},
  1026  	{"9223372036854776us", `"9223372036854776us"`},
  1027  	{"3000000h", `"3000000h"`},
  1028  	{"9223372036854775.808us", `"9223372036854775.808us"`},
  1029  	{"9223372036854ms775us808ns", `"9223372036854ms775us808ns"`},
  1030  }
  1031  
  1032  func TestParseDurationErrors(t *testing.T) {
  1033  	for _, tc := range parseDurationErrorTests {
  1034  		_, err := ParseDuration(tc.in)
  1035  		if err == nil {
  1036  			t.Errorf("ParseDuration(%q) = _, nil, want _, non-nil", tc.in)
  1037  		} else if !strings.Contains(err.Error(), tc.expect) {
  1038  			t.Errorf("ParseDuration(%q) = _, %q, error does not contain %q", tc.in, err, tc.expect)
  1039  		}
  1040  	}
  1041  }
  1042  
  1043  func TestParseDurationRoundTrip(t *testing.T) {
  1044  	// https://golang.org/issue/48629
  1045  	max0 := Duration(math.MaxInt64)
  1046  	max1, err := ParseDuration(max0.String())
  1047  	if err != nil || max0 != max1 {
  1048  		t.Errorf("round-trip failed: %d => %q => %d, %v", max0, max0.String(), max1, err)
  1049  	}
  1050  
  1051  	min0 := Duration(math.MinInt64)
  1052  	min1, err := ParseDuration(min0.String())
  1053  	if err != nil || min0 != min1 {
  1054  		t.Errorf("round-trip failed: %d => %q => %d, %v", min0, min0.String(), min1, err)
  1055  	}
  1056  
  1057  	for i := 0; i < 100; i++ {
  1058  		// Resolutions finer than milliseconds will result in
  1059  		// imprecise round-trips.
  1060  		d0 := Duration(rand.Int31()) * Millisecond
  1061  		s := d0.String()
  1062  		d1, err := ParseDuration(s)
  1063  		if err != nil || d0 != d1 {
  1064  			t.Errorf("round-trip failed: %d => %q => %d, %v", d0, s, d1, err)
  1065  		}
  1066  	}
  1067  }
  1068  
  1069  // golang.org/issue/4622
  1070  func TestLocationRace(t *testing.T) {
  1071  	ResetLocalOnceForTest() // reset the Once to trigger the race
  1072  
  1073  	c := make(chan string, 1)
  1074  	go func() {
  1075  		c <- Now().String()
  1076  	}()
  1077  	_ = Now().String()
  1078  	<-c
  1079  	Sleep(100 * Millisecond)
  1080  
  1081  	// Back to Los Angeles for subsequent tests:
  1082  	ForceUSPacificForTesting()
  1083  }
  1084  
  1085  var (
  1086  	t Time
  1087  	u int64
  1088  )
  1089  
  1090  var mallocTest = []struct {
  1091  	count int
  1092  	desc  string
  1093  	fn    func()
  1094  }{
  1095  	{0, `time.Now()`, func() { t = Now() }},
  1096  	{0, `time.Now().UnixNano()`, func() { u = Now().UnixNano() }},
  1097  	{0, `time.Now().UnixMilli()`, func() { u = Now().UnixMilli() }},
  1098  	{0, `time.Now().UnixMicro()`, func() { u = Now().UnixMicro() }},
  1099  }
  1100  
  1101  func TestCountMallocs(t *testing.T) {
  1102  	if testing.Short() {
  1103  		t.Skip("skipping malloc count in short mode")
  1104  	}
  1105  	if runtime.GOMAXPROCS(0) > 1 {
  1106  		t.Skip("skipping; GOMAXPROCS>1")
  1107  	}
  1108  	for _, mt := range mallocTest {
  1109  		allocs := int(testing.AllocsPerRun(100, mt.fn))
  1110  		if allocs > mt.count {
  1111  			t.Errorf("%s: %d allocs, want %d", mt.desc, allocs, mt.count)
  1112  		}
  1113  	}
  1114  }
  1115  
  1116  func TestLoadFixed(t *testing.T) {
  1117  	// Issue 4064: handle locations without any zone transitions.
  1118  	loc, err := LoadLocation("Etc/GMT+1")
  1119  	if err != nil {
  1120  		t.Fatal(err)
  1121  	}
  1122  
  1123  	// The tzdata name Etc/GMT+1 uses "east is negative",
  1124  	// but Go and most other systems use "east is positive".
  1125  	// So GMT+1 corresponds to -3600 in the Go zone, not +3600.
  1126  	name, offset := Now().In(loc).Zone()
  1127  	// The zone abbreviation is "-01" since tzdata-2016g, and "GMT+1"
  1128  	// on earlier versions; we accept both. (Issue 17276.)
  1129  	wantName := []string{"GMT+1", "-01"}
  1130  	// The zone abbreviation may be "+01" on OpenBSD. (Issue 69840.)
  1131  	if runtime.GOOS == "openbsd" {
  1132  		wantName = append(wantName, "+01")
  1133  	}
  1134  	if !slices.Contains(wantName, name) || offset != -1*60*60 {
  1135  		t.Errorf("Now().In(loc).Zone() = %q, %d, want %q (one of), %d",
  1136  			name, offset, wantName, -1*60*60)
  1137  	}
  1138  }
  1139  
  1140  const (
  1141  	minDuration Duration = -1 << 63
  1142  	maxDuration Duration = 1<<63 - 1
  1143  )
  1144  
  1145  var subTests = []struct {
  1146  	t Time
  1147  	u Time
  1148  	d Duration
  1149  }{
  1150  	{Time{}, Time{}, Duration(0)},
  1151  	{Date(2009, 11, 23, 0, 0, 0, 1, UTC), Date(2009, 11, 23, 0, 0, 0, 0, UTC), Duration(1)},
  1152  	{Date(2009, 11, 23, 0, 0, 0, 0, UTC), Date(2009, 11, 24, 0, 0, 0, 0, UTC), -24 * Hour},
  1153  	{Date(2009, 11, 24, 0, 0, 0, 0, UTC), Date(2009, 11, 23, 0, 0, 0, 0, UTC), 24 * Hour},
  1154  	{Date(-2009, 11, 24, 0, 0, 0, 0, UTC), Date(-2009, 11, 23, 0, 0, 0, 0, UTC), 24 * Hour},
  1155  	{Time{}, Date(2109, 11, 23, 0, 0, 0, 0, UTC), minDuration},
  1156  	{Date(2109, 11, 23, 0, 0, 0, 0, UTC), Time{}, maxDuration},
  1157  	{Time{}, Date(-2109, 11, 23, 0, 0, 0, 0, UTC), maxDuration},
  1158  	{Date(-2109, 11, 23, 0, 0, 0, 0, UTC), Time{}, minDuration},
  1159  	{Date(2290, 1, 1, 0, 0, 0, 0, UTC), Date(2000, 1, 1, 0, 0, 0, 0, UTC), 290*365*24*Hour + 71*24*Hour},
  1160  	{Date(2300, 1, 1, 0, 0, 0, 0, UTC), Date(2000, 1, 1, 0, 0, 0, 0, UTC), maxDuration},
  1161  	{Date(2000, 1, 1, 0, 0, 0, 0, UTC), Date(2290, 1, 1, 0, 0, 0, 0, UTC), -290*365*24*Hour - 71*24*Hour},
  1162  	{Date(2000, 1, 1, 0, 0, 0, 0, UTC), Date(2300, 1, 1, 0, 0, 0, 0, UTC), minDuration},
  1163  	{Date(2311, 11, 26, 02, 16, 47, 63535996, UTC), Date(2019, 8, 16, 2, 29, 30, 268436582, UTC), 9223372036795099414},
  1164  	{MinMonoTime, MaxMonoTime, minDuration},
  1165  	{MaxMonoTime, MinMonoTime, maxDuration},
  1166  }
  1167  
  1168  func TestSub(t *testing.T) {
  1169  	for i, st := range subTests {
  1170  		got := st.t.Sub(st.u)
  1171  		if got != st.d {
  1172  			t.Errorf("#%d: Sub(%v, %v): got %v; want %v", i, st.t, st.u, got, st.d)
  1173  		}
  1174  	}
  1175  }
  1176  
  1177  var nsDurationTests = []struct {
  1178  	d    Duration
  1179  	want int64
  1180  }{
  1181  	{Duration(-1000), -1000},
  1182  	{Duration(-1), -1},
  1183  	{Duration(1), 1},
  1184  	{Duration(1000), 1000},
  1185  }
  1186  
  1187  func TestDurationNanoseconds(t *testing.T) {
  1188  	for _, tt := range nsDurationTests {
  1189  		if got := tt.d.Nanoseconds(); got != tt.want {
  1190  			t.Errorf("Duration(%s).Nanoseconds() = %d; want: %d", tt.d, got, tt.want)
  1191  		}
  1192  	}
  1193  }
  1194  
  1195  var usDurationTests = []struct {
  1196  	d    Duration
  1197  	want int64
  1198  }{
  1199  	{Duration(-1000), -1},
  1200  	{Duration(1000), 1},
  1201  }
  1202  
  1203  func TestDurationMicroseconds(t *testing.T) {
  1204  	for _, tt := range usDurationTests {
  1205  		if got := tt.d.Microseconds(); got != tt.want {
  1206  			t.Errorf("Duration(%s).Microseconds() = %d; want: %d", tt.d, got, tt.want)
  1207  		}
  1208  	}
  1209  }
  1210  
  1211  var msDurationTests = []struct {
  1212  	d    Duration
  1213  	want int64
  1214  }{
  1215  	{Duration(-1000000), -1},
  1216  	{Duration(1000000), 1},
  1217  }
  1218  
  1219  func TestDurationMilliseconds(t *testing.T) {
  1220  	for _, tt := range msDurationTests {
  1221  		if got := tt.d.Milliseconds(); got != tt.want {
  1222  			t.Errorf("Duration(%s).Milliseconds() = %d; want: %d", tt.d, got, tt.want)
  1223  		}
  1224  	}
  1225  }
  1226  
  1227  var secDurationTests = []struct {
  1228  	d    Duration
  1229  	want float64
  1230  }{
  1231  	{Duration(300000000), 0.3},
  1232  }
  1233  
  1234  func TestDurationSeconds(t *testing.T) {
  1235  	for _, tt := range secDurationTests {
  1236  		if got := tt.d.Seconds(); got != tt.want {
  1237  			t.Errorf("Duration(%s).Seconds() = %g; want: %g", tt.d, got, tt.want)
  1238  		}
  1239  	}
  1240  }
  1241  
  1242  var minDurationTests = []struct {
  1243  	d    Duration
  1244  	want float64
  1245  }{
  1246  	{Duration(-60000000000), -1},
  1247  	{Duration(-1), -1 / 60e9},
  1248  	{Duration(1), 1 / 60e9},
  1249  	{Duration(60000000000), 1},
  1250  	{Duration(3000), 5e-8},
  1251  }
  1252  
  1253  func TestDurationMinutes(t *testing.T) {
  1254  	for _, tt := range minDurationTests {
  1255  		if got := tt.d.Minutes(); got != tt.want {
  1256  			t.Errorf("Duration(%s).Minutes() = %g; want: %g", tt.d, got, tt.want)
  1257  		}
  1258  	}
  1259  }
  1260  
  1261  var hourDurationTests = []struct {
  1262  	d    Duration
  1263  	want float64
  1264  }{
  1265  	{Duration(-3600000000000), -1},
  1266  	{Duration(-1), -1 / 3600e9},
  1267  	{Duration(1), 1 / 3600e9},
  1268  	{Duration(3600000000000), 1},
  1269  	{Duration(36), 1e-11},
  1270  }
  1271  
  1272  func TestDurationHours(t *testing.T) {
  1273  	for _, tt := range hourDurationTests {
  1274  		if got := tt.d.Hours(); got != tt.want {
  1275  			t.Errorf("Duration(%s).Hours() = %g; want: %g", tt.d, got, tt.want)
  1276  		}
  1277  	}
  1278  }
  1279  
  1280  var durationTruncateTests = []struct {
  1281  	d    Duration
  1282  	m    Duration
  1283  	want Duration
  1284  }{
  1285  	{0, Second, 0},
  1286  	{Minute, -7 * Second, Minute},
  1287  	{Minute, 0, Minute},
  1288  	{Minute, 1, Minute},
  1289  	{Minute + 10*Second, 10 * Second, Minute + 10*Second},
  1290  	{2*Minute + 10*Second, Minute, 2 * Minute},
  1291  	{10*Minute + 10*Second, 3 * Minute, 9 * Minute},
  1292  	{Minute + 10*Second, Minute + 10*Second + 1, 0},
  1293  	{Minute + 10*Second, Hour, 0},
  1294  	{-Minute, Second, -Minute},
  1295  	{-10 * Minute, 3 * Minute, -9 * Minute},
  1296  	{-10 * Minute, Hour, 0},
  1297  }
  1298  
  1299  func TestDurationTruncate(t *testing.T) {
  1300  	for _, tt := range durationTruncateTests {
  1301  		if got := tt.d.Truncate(tt.m); got != tt.want {
  1302  			t.Errorf("Duration(%s).Truncate(%s) = %s; want: %s", tt.d, tt.m, got, tt.want)
  1303  		}
  1304  	}
  1305  }
  1306  
  1307  var durationRoundTests = []struct {
  1308  	d    Duration
  1309  	m    Duration
  1310  	want Duration
  1311  }{
  1312  	{0, Second, 0},
  1313  	{Minute, -11 * Second, Minute},
  1314  	{Minute, 0, Minute},
  1315  	{Minute, 1, Minute},
  1316  	{2 * Minute, Minute, 2 * Minute},
  1317  	{2*Minute + 10*Second, Minute, 2 * Minute},
  1318  	{2*Minute + 30*Second, Minute, 3 * Minute},
  1319  	{2*Minute + 50*Second, Minute, 3 * Minute},
  1320  	{-Minute, 1, -Minute},
  1321  	{-2 * Minute, Minute, -2 * Minute},
  1322  	{-2*Minute - 10*Second, Minute, -2 * Minute},
  1323  	{-2*Minute - 30*Second, Minute, -3 * Minute},
  1324  	{-2*Minute - 50*Second, Minute, -3 * Minute},
  1325  	{8e18, 3e18, 9e18},
  1326  	{9e18, 5e18, 1<<63 - 1},
  1327  	{-8e18, 3e18, -9e18},
  1328  	{-9e18, 5e18, -1 << 63},
  1329  	{3<<61 - 1, 3 << 61, 3 << 61},
  1330  }
  1331  
  1332  func TestDurationRound(t *testing.T) {
  1333  	for _, tt := range durationRoundTests {
  1334  		if got := tt.d.Round(tt.m); got != tt.want {
  1335  			t.Errorf("Duration(%s).Round(%s) = %s; want: %s", tt.d, tt.m, got, tt.want)
  1336  		}
  1337  	}
  1338  }
  1339  
  1340  var durationAbsTests = []struct {
  1341  	d    Duration
  1342  	want Duration
  1343  }{
  1344  	{0, 0},
  1345  	{1, 1},
  1346  	{-1, 1},
  1347  	{1 * Minute, 1 * Minute},
  1348  	{-1 * Minute, 1 * Minute},
  1349  	{minDuration, maxDuration},
  1350  	{minDuration + 1, maxDuration},
  1351  	{minDuration + 2, maxDuration - 1},
  1352  	{maxDuration, maxDuration},
  1353  	{maxDuration - 1, maxDuration - 1},
  1354  }
  1355  
  1356  func TestDurationAbs(t *testing.T) {
  1357  	for _, tt := range durationAbsTests {
  1358  		if got := tt.d.Abs(); got != tt.want {
  1359  			t.Errorf("Duration(%s).Abs() = %s; want: %s", tt.d, got, tt.want)
  1360  		}
  1361  	}
  1362  }
  1363  
  1364  var defaultLocTests = []struct {
  1365  	name string
  1366  	f    func(t1, t2 Time) bool
  1367  }{
  1368  	{"After", func(t1, t2 Time) bool { return t1.After(t2) == t2.After(t1) }},
  1369  	{"Before", func(t1, t2 Time) bool { return t1.Before(t2) == t2.Before(t1) }},
  1370  	{"Equal", func(t1, t2 Time) bool { return t1.Equal(t2) == t2.Equal(t1) }},
  1371  	{"Compare", func(t1, t2 Time) bool { return t1.Compare(t2) == t2.Compare(t1) }},
  1372  
  1373  	{"IsZero", func(t1, t2 Time) bool { return t1.IsZero() == t2.IsZero() }},
  1374  	{"Date", func(t1, t2 Time) bool {
  1375  		a1, b1, c1 := t1.Date()
  1376  		a2, b2, c2 := t2.Date()
  1377  		return a1 == a2 && b1 == b2 && c1 == c2
  1378  	}},
  1379  	{"Year", func(t1, t2 Time) bool { return t1.Year() == t2.Year() }},
  1380  	{"Month", func(t1, t2 Time) bool { return t1.Month() == t2.Month() }},
  1381  	{"Day", func(t1, t2 Time) bool { return t1.Day() == t2.Day() }},
  1382  	{"Weekday", func(t1, t2 Time) bool { return t1.Weekday() == t2.Weekday() }},
  1383  	{"ISOWeek", func(t1, t2 Time) bool {
  1384  		a1, b1 := t1.ISOWeek()
  1385  		a2, b2 := t2.ISOWeek()
  1386  		return a1 == a2 && b1 == b2
  1387  	}},
  1388  	{"Clock", func(t1, t2 Time) bool {
  1389  		a1, b1, c1 := t1.Clock()
  1390  		a2, b2, c2 := t2.Clock()
  1391  		return a1 == a2 && b1 == b2 && c1 == c2
  1392  	}},
  1393  	{"Hour", func(t1, t2 Time) bool { return t1.Hour() == t2.Hour() }},
  1394  	{"Minute", func(t1, t2 Time) bool { return t1.Minute() == t2.Minute() }},
  1395  	{"Second", func(t1, t2 Time) bool { return t1.Second() == t2.Second() }},
  1396  	{"Nanosecond", func(t1, t2 Time) bool { return t1.Hour() == t2.Hour() }},
  1397  	{"YearDay", func(t1, t2 Time) bool { return t1.YearDay() == t2.YearDay() }},
  1398  
  1399  	// Using Equal since Add don't modify loc using "==" will cause a fail
  1400  	{"Add", func(t1, t2 Time) bool { return t1.Add(Hour).Equal(t2.Add(Hour)) }},
  1401  	{"Sub", func(t1, t2 Time) bool { return t1.Sub(t2) == t2.Sub(t1) }},
  1402  
  1403  	// Original cause for this test case bug 15852
  1404  	{"AddDate", func(t1, t2 Time) bool { return t1.AddDate(1991, 9, 3) == t2.AddDate(1991, 9, 3) }},
  1405  
  1406  	{"UTC", func(t1, t2 Time) bool { return t1.UTC() == t2.UTC() }},
  1407  	{"Local", func(t1, t2 Time) bool { return t1.Local() == t2.Local() }},
  1408  	{"In", func(t1, t2 Time) bool { return t1.In(UTC) == t2.In(UTC) }},
  1409  
  1410  	{"Local", func(t1, t2 Time) bool { return t1.Local() == t2.Local() }},
  1411  	{"Zone", func(t1, t2 Time) bool {
  1412  		a1, b1 := t1.Zone()
  1413  		a2, b2 := t2.Zone()
  1414  		return a1 == a2 && b1 == b2
  1415  	}},
  1416  
  1417  	{"Unix", func(t1, t2 Time) bool { return t1.Unix() == t2.Unix() }},
  1418  	{"UnixNano", func(t1, t2 Time) bool { return t1.UnixNano() == t2.UnixNano() }},
  1419  	{"UnixMilli", func(t1, t2 Time) bool { return t1.UnixMilli() == t2.UnixMilli() }},
  1420  	{"UnixMicro", func(t1, t2 Time) bool { return t1.UnixMicro() == t2.UnixMicro() }},
  1421  
  1422  	{"AppendBinary", func(t1, t2 Time) bool {
  1423  		buf1 := make([]byte, 4, 32)
  1424  		buf2 := make([]byte, 4, 32)
  1425  		a1, b1 := t1.AppendBinary(buf1)
  1426  		a2, b2 := t2.AppendBinary(buf2)
  1427  		return bytes.Equal(a1[4:], a2[4:]) && b1 == b2
  1428  	}},
  1429  	{"MarshalBinary", func(t1, t2 Time) bool {
  1430  		a1, b1 := t1.MarshalBinary()
  1431  		a2, b2 := t2.MarshalBinary()
  1432  		return bytes.Equal(a1, a2) && b1 == b2
  1433  	}},
  1434  	{"GobEncode", func(t1, t2 Time) bool {
  1435  		a1, b1 := t1.GobEncode()
  1436  		a2, b2 := t2.GobEncode()
  1437  		return bytes.Equal(a1, a2) && b1 == b2
  1438  	}},
  1439  	{"MarshalJSON", func(t1, t2 Time) bool {
  1440  		a1, b1 := t1.MarshalJSON()
  1441  		a2, b2 := t2.MarshalJSON()
  1442  		return bytes.Equal(a1, a2) && b1 == b2
  1443  	}},
  1444  	{"AppendText", func(t1, t2 Time) bool {
  1445  		maxCap := len(RFC3339Nano) + 4
  1446  		buf1 := make([]byte, 4, maxCap)
  1447  		buf2 := make([]byte, 4, maxCap)
  1448  		a1, b1 := t1.AppendText(buf1)
  1449  		a2, b2 := t2.AppendText(buf2)
  1450  		return bytes.Equal(a1[4:], a2[4:]) && b1 == b2
  1451  	}},
  1452  	{"MarshalText", func(t1, t2 Time) bool {
  1453  		a1, b1 := t1.MarshalText()
  1454  		a2, b2 := t2.MarshalText()
  1455  		return bytes.Equal(a1, a2) && b1 == b2
  1456  	}},
  1457  
  1458  	{"Truncate", func(t1, t2 Time) bool { return t1.Truncate(Hour).Equal(t2.Truncate(Hour)) }},
  1459  	{"Round", func(t1, t2 Time) bool { return t1.Round(Hour).Equal(t2.Round(Hour)) }},
  1460  
  1461  	{"== Time{}", func(t1, t2 Time) bool { return (t1 == Time{}) == (t2 == Time{}) }},
  1462  }
  1463  
  1464  func TestDefaultLoc(t *testing.T) {
  1465  	// Verify that all of Time's methods behave identically if loc is set to
  1466  	// nil or UTC.
  1467  	for _, tt := range defaultLocTests {
  1468  		t1 := Time{}
  1469  		t2 := Time{}.UTC()
  1470  		if !tt.f(t1, t2) {
  1471  			t.Errorf("Time{} and Time{}.UTC() behave differently for %s", tt.name)
  1472  		}
  1473  	}
  1474  }
  1475  
  1476  func BenchmarkNow(b *testing.B) {
  1477  	for i := 0; i < b.N; i++ {
  1478  		t = Now()
  1479  	}
  1480  }
  1481  
  1482  func BenchmarkNowUnixNano(b *testing.B) {
  1483  	for i := 0; i < b.N; i++ {
  1484  		u = Now().UnixNano()
  1485  	}
  1486  }
  1487  
  1488  func BenchmarkNowUnixMilli(b *testing.B) {
  1489  	for i := 0; i < b.N; i++ {
  1490  		u = Now().UnixMilli()
  1491  	}
  1492  }
  1493  
  1494  func BenchmarkNowUnixMicro(b *testing.B) {
  1495  	for i := 0; i < b.N; i++ {
  1496  		u = Now().UnixMicro()
  1497  	}
  1498  }
  1499  
  1500  func BenchmarkFormat(b *testing.B) {
  1501  	t := Unix(1265346057, 0)
  1502  	for i := 0; i < b.N; i++ {
  1503  		t.Format("Mon Jan  2 15:04:05 2006")
  1504  	}
  1505  }
  1506  
  1507  func BenchmarkFormatRFC3339(b *testing.B) {
  1508  	t := Unix(1265346057, 0)
  1509  	for i := 0; i < b.N; i++ {
  1510  		t.Format("2006-01-02T15:04:05Z07:00")
  1511  	}
  1512  }
  1513  
  1514  func BenchmarkFormatRFC3339Nano(b *testing.B) {
  1515  	t := Unix(1265346057, 0)
  1516  	for i := 0; i < b.N; i++ {
  1517  		t.Format("2006-01-02T15:04:05.999999999Z07:00")
  1518  	}
  1519  }
  1520  
  1521  func BenchmarkFormatNow(b *testing.B) {
  1522  	// Like BenchmarkFormat, but easier, because the time zone
  1523  	// lookup cache is optimized for the present.
  1524  	t := Now()
  1525  	for i := 0; i < b.N; i++ {
  1526  		t.Format("Mon Jan  2 15:04:05 2006")
  1527  	}
  1528  }
  1529  
  1530  func BenchmarkMarshalJSON(b *testing.B) {
  1531  	t := Now()
  1532  	for i := 0; i < b.N; i++ {
  1533  		t.MarshalJSON()
  1534  	}
  1535  }
  1536  
  1537  func BenchmarkMarshalText(b *testing.B) {
  1538  	t := Now()
  1539  	for i := 0; i < b.N; i++ {
  1540  		t.MarshalText()
  1541  	}
  1542  }
  1543  
  1544  func BenchmarkMarshalBinary(b *testing.B) {
  1545  	t := Now()
  1546  	for i := 0; i < b.N; i++ {
  1547  		t.MarshalBinary()
  1548  	}
  1549  }
  1550  
  1551  func BenchmarkParse(b *testing.B) {
  1552  	for i := 0; i < b.N; i++ {
  1553  		Parse(ANSIC, "Mon Jan  2 15:04:05 2006")
  1554  	}
  1555  }
  1556  
  1557  const testdataRFC3339UTC = "2020-08-22T11:27:43.123456789Z"
  1558  
  1559  func BenchmarkParseRFC3339UTC(b *testing.B) {
  1560  	for i := 0; i < b.N; i++ {
  1561  		Parse(RFC3339, testdataRFC3339UTC)
  1562  	}
  1563  }
  1564  
  1565  var testdataRFC3339UTCBytes = []byte(testdataRFC3339UTC)
  1566  
  1567  func BenchmarkParseRFC3339UTCBytes(b *testing.B) {
  1568  	for i := 0; i < b.N; i++ {
  1569  		Parse(RFC3339, string(testdataRFC3339UTCBytes))
  1570  	}
  1571  }
  1572  
  1573  const testdataRFC3339TZ = "2020-08-22T11:27:43.123456789-02:00"
  1574  
  1575  func BenchmarkParseRFC3339TZ(b *testing.B) {
  1576  	for i := 0; i < b.N; i++ {
  1577  		Parse(RFC3339, testdataRFC3339TZ)
  1578  	}
  1579  }
  1580  
  1581  var testdataRFC3339TZBytes = []byte(testdataRFC3339TZ)
  1582  
  1583  func BenchmarkParseRFC3339TZBytes(b *testing.B) {
  1584  	for i := 0; i < b.N; i++ {
  1585  		Parse(RFC3339, string(testdataRFC3339TZBytes))
  1586  	}
  1587  }
  1588  
  1589  func BenchmarkParseDuration(b *testing.B) {
  1590  	for i := 0; i < b.N; i++ {
  1591  		ParseDuration("9007199254.740993ms")
  1592  		ParseDuration("9007199254740993ns")
  1593  	}
  1594  }
  1595  
  1596  func BenchmarkHour(b *testing.B) {
  1597  	t := Now()
  1598  	for i := 0; i < b.N; i++ {
  1599  		_ = t.Hour()
  1600  	}
  1601  }
  1602  
  1603  func BenchmarkSecond(b *testing.B) {
  1604  	t := Now()
  1605  	for i := 0; i < b.N; i++ {
  1606  		_ = t.Second()
  1607  	}
  1608  }
  1609  
  1610  func BenchmarkDate(b *testing.B) {
  1611  	t := Now()
  1612  	for i := 0; i < b.N; i++ {
  1613  		_, _, _ = t.Date()
  1614  	}
  1615  }
  1616  
  1617  func BenchmarkYear(b *testing.B) {
  1618  	t := Now()
  1619  	for i := 0; i < b.N; i++ {
  1620  		_ = t.Year()
  1621  	}
  1622  }
  1623  
  1624  func BenchmarkYearDay(b *testing.B) {
  1625  	t := Now()
  1626  	for i := 0; i < b.N; i++ {
  1627  		_ = t.YearDay()
  1628  	}
  1629  }
  1630  
  1631  func BenchmarkMonth(b *testing.B) {
  1632  	t := Now()
  1633  	for i := 0; i < b.N; i++ {
  1634  		_ = t.Month()
  1635  	}
  1636  }
  1637  
  1638  func BenchmarkDay(b *testing.B) {
  1639  	t := Now()
  1640  	for i := 0; i < b.N; i++ {
  1641  		_ = t.Day()
  1642  	}
  1643  }
  1644  
  1645  func BenchmarkISOWeek(b *testing.B) {
  1646  	t := Now()
  1647  	for i := 0; i < b.N; i++ {
  1648  		_, _ = t.ISOWeek()
  1649  	}
  1650  }
  1651  
  1652  func BenchmarkGoString(b *testing.B) {
  1653  	t := Now()
  1654  	for i := 0; i < b.N; i++ {
  1655  		_ = t.GoString()
  1656  	}
  1657  }
  1658  
  1659  func BenchmarkDateFunc(b *testing.B) {
  1660  	var t Time
  1661  	for range b.N {
  1662  		t = Date(2020, 8, 22, 11, 27, 43, 123456789, UTC)
  1663  	}
  1664  	_ = t
  1665  }
  1666  
  1667  func BenchmarkUnmarshalText(b *testing.B) {
  1668  	var t Time
  1669  	in := []byte("2020-08-22T11:27:43.123456789-02:00")
  1670  	for i := 0; i < b.N; i++ {
  1671  		t.UnmarshalText(in)
  1672  	}
  1673  }
  1674  
  1675  func TestMarshalBinaryZeroTime(t *testing.T) {
  1676  	t0 := Time{}
  1677  	enc, err := t0.MarshalBinary()
  1678  	if err != nil {
  1679  		t.Fatal(err)
  1680  	}
  1681  	t1 := Now() // not zero
  1682  	if err := t1.UnmarshalBinary(enc); err != nil {
  1683  		t.Fatal(err)
  1684  	}
  1685  	if t1 != t0 {
  1686  		t.Errorf("t0=%#v\nt1=%#v\nwant identical structures", t0, t1)
  1687  	}
  1688  }
  1689  
  1690  func TestMarshalBinaryVersion2(t *testing.T) {
  1691  	t0, err := Parse(RFC3339, "1880-01-01T00:00:00Z")
  1692  	if err != nil {
  1693  		t.Errorf("Failed to parse time, error = %v", err)
  1694  	}
  1695  	loc, err := LoadLocation("US/Eastern")
  1696  	if err != nil {
  1697  		t.Errorf("Failed to load location, error = %v", err)
  1698  	}
  1699  	t1 := t0.In(loc)
  1700  	b, err := t1.MarshalBinary()
  1701  	if err != nil {
  1702  		t.Errorf("Failed to Marshal, error = %v", err)
  1703  	}
  1704  
  1705  	t2 := Time{}
  1706  	err = t2.UnmarshalBinary(b)
  1707  	if err != nil {
  1708  		t.Errorf("Failed to Unmarshal, error = %v", err)
  1709  	}
  1710  
  1711  	if !(t0.Equal(t1) && t1.Equal(t2)) {
  1712  		if !t0.Equal(t1) {
  1713  			t.Errorf("The result t1: %+v after Marshal is not matched original t0: %+v", t1, t0)
  1714  		}
  1715  		if !t1.Equal(t2) {
  1716  			t.Errorf("The result t2: %+v after Unmarshal is not matched original t1: %+v", t2, t1)
  1717  		}
  1718  	}
  1719  }
  1720  
  1721  func TestUnmarshalTextAllocations(t *testing.T) {
  1722  	in := []byte(testdataRFC3339UTC) // short enough to be stack allocated
  1723  	if allocs := testing.AllocsPerRun(100, func() {
  1724  		var t Time
  1725  		t.UnmarshalText(in)
  1726  	}); allocs != 0 {
  1727  		t.Errorf("got %v allocs, want 0 allocs", allocs)
  1728  	}
  1729  }
  1730  
  1731  // Issue 17720: Zero value of time.Month fails to print
  1732  func TestZeroMonthString(t *testing.T) {
  1733  	if got, want := Month(0).String(), "%!Month(0)"; got != want {
  1734  		t.Errorf("zero month = %q; want %q", got, want)
  1735  	}
  1736  }
  1737  
  1738  // Issue 24692: Out of range weekday panics
  1739  func TestWeekdayString(t *testing.T) {
  1740  	if got, want := Tuesday.String(), "Tuesday"; got != want {
  1741  		t.Errorf("Tuesday weekday = %q; want %q", got, want)
  1742  	}
  1743  	if got, want := Weekday(14).String(), "%!Weekday(14)"; got != want {
  1744  		t.Errorf("14th weekday = %q; want %q", got, want)
  1745  	}
  1746  }
  1747  
  1748  func TestReadFileLimit(t *testing.T) {
  1749  	const zero = "/dev/zero"
  1750  	if _, err := os.Stat(zero); err != nil {
  1751  		t.Skip("skipping test without a /dev/zero")
  1752  	}
  1753  	_, err := ReadFile(zero)
  1754  	if err == nil || !strings.Contains(err.Error(), "is too large") {
  1755  		t.Errorf("readFile(%q) error = %v; want error containing 'is too large'", zero, err)
  1756  	}
  1757  }
  1758  
  1759  // Issue 25686: hard crash on concurrent timer access.
  1760  // Issue 37400: panic with "racy use of timers"
  1761  // This test deliberately invokes a race condition.
  1762  // We are testing that we don't crash with "fatal error: panic holding locks",
  1763  // and that we also don't panic.
  1764  func TestConcurrentTimerReset(t *testing.T) {
  1765  	const goroutines = 8
  1766  	const tries = 1000
  1767  	var wg sync.WaitGroup
  1768  	wg.Add(goroutines)
  1769  	timer := NewTimer(Hour)
  1770  	for i := 0; i < goroutines; i++ {
  1771  		go func(i int) {
  1772  			defer wg.Done()
  1773  			for j := 0; j < tries; j++ {
  1774  				timer.Reset(Hour + Duration(i*j))
  1775  			}
  1776  		}(i)
  1777  	}
  1778  	wg.Wait()
  1779  }
  1780  
  1781  // Issue 37400: panic with "racy use of timers".
  1782  func TestConcurrentTimerResetStop(t *testing.T) {
  1783  	const goroutines = 8
  1784  	const tries = 1000
  1785  	var wg sync.WaitGroup
  1786  	wg.Add(goroutines * 2)
  1787  	timer := NewTimer(Hour)
  1788  	for i := 0; i < goroutines; i++ {
  1789  		go func(i int) {
  1790  			defer wg.Done()
  1791  			for j := 0; j < tries; j++ {
  1792  				timer.Reset(Hour + Duration(i*j))
  1793  			}
  1794  		}(i)
  1795  		go func(i int) {
  1796  			defer wg.Done()
  1797  			timer.Stop()
  1798  		}(i)
  1799  	}
  1800  	wg.Wait()
  1801  }
  1802  
  1803  func TestTimeIsDST(t *testing.T) {
  1804  	undo := DisablePlatformSources()
  1805  	defer undo()
  1806  
  1807  	tzWithDST, err := LoadLocation("Australia/Sydney")
  1808  	if err != nil {
  1809  		t.Fatalf("could not load tz 'Australia/Sydney': %v", err)
  1810  	}
  1811  	tzWithoutDST, err := LoadLocation("Australia/Brisbane")
  1812  	if err != nil {
  1813  		t.Fatalf("could not load tz 'Australia/Brisbane': %v", err)
  1814  	}
  1815  	tzFixed := FixedZone("FIXED_TIME", 12345)
  1816  
  1817  	tests := [...]struct {
  1818  		time Time
  1819  		want bool
  1820  	}{
  1821  		0: {Date(2009, 1, 1, 12, 0, 0, 0, UTC), false},
  1822  		1: {Date(2009, 6, 1, 12, 0, 0, 0, UTC), false},
  1823  		2: {Date(2009, 1, 1, 12, 0, 0, 0, tzWithDST), true},
  1824  		3: {Date(2009, 6, 1, 12, 0, 0, 0, tzWithDST), false},
  1825  		4: {Date(2009, 1, 1, 12, 0, 0, 0, tzWithoutDST), false},
  1826  		5: {Date(2009, 6, 1, 12, 0, 0, 0, tzWithoutDST), false},
  1827  		6: {Date(2009, 1, 1, 12, 0, 0, 0, tzFixed), false},
  1828  		7: {Date(2009, 6, 1, 12, 0, 0, 0, tzFixed), false},
  1829  	}
  1830  
  1831  	for i, tt := range tests {
  1832  		got := tt.time.IsDST()
  1833  		if got != tt.want {
  1834  			t.Errorf("#%d:: (%#v).IsDST()=%t, want %t", i, tt.time.Format(RFC3339), got, tt.want)
  1835  		}
  1836  	}
  1837  }
  1838  
  1839  func TestTimeAddSecOverflow(t *testing.T) {
  1840  	// Test it with positive delta.
  1841  	var maxInt64 int64 = 1<<63 - 1
  1842  	timeExt := maxInt64 - UnixToInternal - 50
  1843  	notMonoTime := Unix(timeExt, 0)
  1844  	for i := int64(0); i < 100; i++ {
  1845  		sec := notMonoTime.Unix()
  1846  		notMonoTime = notMonoTime.Add(Duration(i * 1e9))
  1847  		if newSec := notMonoTime.Unix(); newSec != sec+i && newSec+UnixToInternal != maxInt64 {
  1848  			t.Fatalf("time ext: %d overflows with positive delta, overflow threshold: %d", newSec, maxInt64)
  1849  		}
  1850  	}
  1851  
  1852  	// Test it with negative delta.
  1853  	maxInt64 = -maxInt64
  1854  	notMonoTime = NotMonoNegativeTime
  1855  	for i := int64(0); i > -100; i-- {
  1856  		sec := notMonoTime.Unix()
  1857  		notMonoTime = notMonoTime.Add(Duration(i * 1e9))
  1858  		if newSec := notMonoTime.Unix(); newSec != sec+i && newSec+UnixToInternal != maxInt64 {
  1859  			t.Fatalf("time ext: %d overflows with positive delta, overflow threshold: %d", newSec, maxInt64)
  1860  		}
  1861  	}
  1862  }
  1863  
  1864  // Issue 49284: time: ParseInLocation incorrectly because of Daylight Saving Time
  1865  func TestTimeWithZoneTransition(t *testing.T) {
  1866  	undo := DisablePlatformSources()
  1867  	defer undo()
  1868  
  1869  	loc, err := LoadLocation("Asia/Shanghai")
  1870  	if err != nil {
  1871  		t.Fatal(err)
  1872  	}
  1873  
  1874  	tests := [...]struct {
  1875  		give Time
  1876  		want Time
  1877  	}{
  1878  		// 14 Apr 1991 - Daylight Saving Time Started
  1879  		// When time of "Asia/Shanghai" was about to reach
  1880  		// Sunday, 14 April 1991, 02:00:00 clocks were turned forward 1 hour to
  1881  		// Sunday, 14 April 1991, 03:00:00 local daylight time instead.
  1882  		// The UTC time was 13 April 1991, 18:00:00
  1883  		0: {Date(1991, April, 13, 17, 50, 0, 0, loc), Date(1991, April, 13, 9, 50, 0, 0, UTC)},
  1884  		1: {Date(1991, April, 13, 18, 0, 0, 0, loc), Date(1991, April, 13, 10, 0, 0, 0, UTC)},
  1885  		2: {Date(1991, April, 14, 1, 50, 0, 0, loc), Date(1991, April, 13, 17, 50, 0, 0, UTC)},
  1886  		3: {Date(1991, April, 14, 3, 0, 0, 0, loc), Date(1991, April, 13, 18, 0, 0, 0, UTC)},
  1887  
  1888  		// 15 Sep 1991 - Daylight Saving Time Ended
  1889  		// When local daylight time of "Asia/Shanghai" was about to reach
  1890  		// Sunday, 15 September 1991, 02:00:00 clocks were turned backward 1 hour to
  1891  		// Sunday, 15 September 1991, 01:00:00 local standard time instead.
  1892  		// The UTC time was 14 September 1991, 17:00:00
  1893  		4: {Date(1991, September, 14, 16, 50, 0, 0, loc), Date(1991, September, 14, 7, 50, 0, 0, UTC)},
  1894  		5: {Date(1991, September, 14, 17, 0, 0, 0, loc), Date(1991, September, 14, 8, 0, 0, 0, UTC)},
  1895  		6: {Date(1991, September, 15, 0, 50, 0, 0, loc), Date(1991, September, 14, 15, 50, 0, 0, UTC)},
  1896  		7: {Date(1991, September, 15, 2, 00, 0, 0, loc), Date(1991, September, 14, 18, 00, 0, 0, UTC)},
  1897  	}
  1898  
  1899  	for i, tt := range tests {
  1900  		if !tt.give.Equal(tt.want) {
  1901  			t.Errorf("#%d:: %#v is not equal to %#v", i, tt.give.Format(RFC3339), tt.want.Format(RFC3339))
  1902  		}
  1903  	}
  1904  }
  1905  
  1906  func TestZoneBounds(t *testing.T) {
  1907  	undo := DisablePlatformSources()
  1908  	defer undo()
  1909  	loc, err := LoadLocation("Asia/Shanghai")
  1910  	if err != nil {
  1911  		t.Fatal(err)
  1912  	}
  1913  
  1914  	// The ZoneBounds of a UTC location would just return two zero Time.
  1915  	for _, test := range utctests {
  1916  		sec := test.seconds
  1917  		golden := &test.golden
  1918  		tm := Unix(sec, 0).UTC()
  1919  		start, end := tm.ZoneBounds()
  1920  		if !(start.IsZero() && end.IsZero()) {
  1921  			t.Errorf("ZoneBounds of %+v expects two zero Time, got:\n  start=%v\n  end=%v", *golden, start, end)
  1922  		}
  1923  	}
  1924  
  1925  	// If the zone begins at the beginning of time, start will be returned as a zero Time.
  1926  	// Use math.MinInt32 to avoid overflow of int arguments on 32-bit systems.
  1927  	beginTime := Date(math.MinInt32, January, 1, 0, 0, 0, 0, loc)
  1928  	start, end := beginTime.ZoneBounds()
  1929  	if !start.IsZero() || end.IsZero() {
  1930  		t.Errorf("ZoneBounds of %v expects start is zero Time, got:\n  start=%v\n  end=%v", beginTime, start, end)
  1931  	}
  1932  
  1933  	// If the zone goes on forever, end will be returned as a zero Time.
  1934  	// Use math.MaxInt32 to avoid overflow of int arguments on 32-bit systems.
  1935  	foreverTime := Date(math.MaxInt32, January, 1, 0, 0, 0, 0, loc)
  1936  	start, end = foreverTime.ZoneBounds()
  1937  	if start.IsZero() || !end.IsZero() {
  1938  		t.Errorf("ZoneBounds of %v expects end is zero Time, got:\n  start=%v\n  end=%v", foreverTime, start, end)
  1939  	}
  1940  
  1941  	// Check some real-world cases to make sure we're getting the right bounds.
  1942  	boundOne := Date(1990, September, 16, 1, 0, 0, 0, loc)
  1943  	boundTwo := Date(1991, April, 14, 3, 0, 0, 0, loc)
  1944  	boundThree := Date(1991, September, 15, 1, 0, 0, 0, loc)
  1945  	makeLocalTime := func(sec int64) Time { return Unix(sec, 0) }
  1946  	realTests := [...]struct {
  1947  		giveTime  Time
  1948  		wantStart Time
  1949  		wantEnd   Time
  1950  	}{
  1951  		// The ZoneBounds of "Asia/Shanghai" Daylight Saving Time
  1952  		0: {Date(1991, April, 13, 17, 50, 0, 0, loc), boundOne, boundTwo},
  1953  		1: {Date(1991, April, 13, 18, 0, 0, 0, loc), boundOne, boundTwo},
  1954  		2: {Date(1991, April, 14, 1, 50, 0, 0, loc), boundOne, boundTwo},
  1955  		3: {boundTwo, boundTwo, boundThree},
  1956  		4: {Date(1991, September, 14, 16, 50, 0, 0, loc), boundTwo, boundThree},
  1957  		5: {Date(1991, September, 14, 17, 0, 0, 0, loc), boundTwo, boundThree},
  1958  		6: {Date(1991, September, 15, 0, 50, 0, 0, loc), boundTwo, boundThree},
  1959  
  1960  		// The ZoneBounds of a "Asia/Shanghai" after the last transition (Standard Time)
  1961  		7:  {boundThree, boundThree, Time{}},
  1962  		8:  {Date(1991, December, 15, 1, 50, 0, 0, loc), boundThree, Time{}},
  1963  		9:  {Date(1992, April, 13, 17, 50, 0, 0, loc), boundThree, Time{}},
  1964  		10: {Date(1992, April, 13, 18, 0, 0, 0, loc), boundThree, Time{}},
  1965  		11: {Date(1992, April, 14, 1, 50, 0, 0, loc), boundThree, Time{}},
  1966  		12: {Date(1992, September, 14, 16, 50, 0, 0, loc), boundThree, Time{}},
  1967  		13: {Date(1992, September, 14, 17, 0, 0, 0, loc), boundThree, Time{}},
  1968  		14: {Date(1992, September, 15, 0, 50, 0, 0, loc), boundThree, Time{}},
  1969  
  1970  		// The ZoneBounds of a local time would return two local Time.
  1971  		// Note: We preloaded "America/Los_Angeles" as time.Local for testing
  1972  		15: {makeLocalTime(0), makeLocalTime(-5756400), makeLocalTime(9972000)},
  1973  		16: {makeLocalTime(1221681866), makeLocalTime(1205056800), makeLocalTime(1225616400)},
  1974  		17: {makeLocalTime(2152173599), makeLocalTime(2145916800), makeLocalTime(2152173600)},
  1975  		18: {makeLocalTime(2152173600), makeLocalTime(2152173600), makeLocalTime(2172733200)},
  1976  		19: {makeLocalTime(2152173601), makeLocalTime(2152173600), makeLocalTime(2172733200)},
  1977  		20: {makeLocalTime(2159200800), makeLocalTime(2152173600), makeLocalTime(2172733200)},
  1978  		21: {makeLocalTime(2172733199), makeLocalTime(2152173600), makeLocalTime(2172733200)},
  1979  		22: {makeLocalTime(2172733200), makeLocalTime(2172733200), makeLocalTime(2177452800)},
  1980  	}
  1981  	for i, tt := range realTests {
  1982  		start, end := tt.giveTime.ZoneBounds()
  1983  		if !start.Equal(tt.wantStart) || !end.Equal(tt.wantEnd) {
  1984  			t.Errorf("#%d:: ZoneBounds of %v expects right bounds:\n  got start=%v\n  want start=%v\n  got end=%v\n  want end=%v",
  1985  				i, tt.giveTime, start, tt.wantStart, end, tt.wantEnd)
  1986  		}
  1987  	}
  1988  }
  1989  

View as plain text