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

View as plain text