...
Run Format

Source file src/time/format.go

     1	// Copyright 2010 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
     6	
     7	import "errors"
     8	
     9	// These are predefined layouts for use in Time.Format and Time.Parse.
    10	// The reference time used in the layouts is the specific time:
    11	//	Mon Jan 2 15:04:05 MST 2006
    12	// which is Unix time 1136239445. Since MST is GMT-0700,
    13	// the reference time can be thought of as
    14	//	01/02 03:04:05PM '06 -0700
    15	// To define your own format, write down what the reference time would look
    16	// like formatted your way; see the values of constants like ANSIC,
    17	// StampMicro or Kitchen for examples. The model is to demonstrate what the
    18	// reference time looks like so that the Format and Parse methods can apply
    19	// the same transformation to a general time value.
    20	//
    21	// Within the format string, an underscore _ represents a space that may be
    22	// replaced by a digit if the following number (a day) has two digits; for
    23	// compatibility with fixed-width Unix time formats.
    24	//
    25	// A decimal point followed by one or more zeros represents a fractional
    26	// second, printed to the given number of decimal places. A decimal point
    27	// followed by one or more nines represents a fractional second, printed to
    28	// the given number of decimal places, with trailing zeros removed.
    29	// When parsing (only), the input may contain a fractional second
    30	// field immediately after the seconds field, even if the layout does not
    31	// signify its presence. In that case a decimal point followed by a maximal
    32	// series of digits is parsed as a fractional second.
    33	//
    34	// Numeric time zone offsets format as follows:
    35	//	-0700  ±hhmm
    36	//	-07:00 ±hh:mm
    37	//	-07    ±hh
    38	// Replacing the sign in the format with a Z triggers
    39	// the ISO 8601 behavior of printing Z instead of an
    40	// offset for the UTC zone. Thus:
    41	//	Z0700  Z or ±hhmm
    42	//	Z07:00 Z or ±hh:mm
    43	//	Z07    Z or ±hh
    44	//
    45	// The recognized day of week formats are "Mon" and "Monday".
    46	// The recognized month formats are "Jan" and "January".
    47	//
    48	// Text in the format string that is not recognized as part of the reference
    49	// time is echoed verbatim during Format and expected to appear verbatim
    50	// in the input to Parse.
    51	//
    52	// The executable example for time.Format demonstrates the working
    53	// of the layout string in detail and is a good reference.
    54	//
    55	// Note that the RFC822, RFC850, and RFC1123 formats should be applied
    56	// only to local times. Applying them to UTC times will use "UTC" as the
    57	// time zone abbreviation, while strictly speaking those RFCs require the
    58	// use of "GMT" in that case.
    59	// In general RFC1123Z should be used instead of RFC1123 for servers
    60	// that insist on that format, and RFC3339 should be preferred for new protocols.
    61	// RFC822, RFC822Z, RFC1123, and RFC1123Z are useful for formatting;
    62	// when used with time.Parse they do not accept all the time formats
    63	// permitted by the RFCs.
    64	const (
    65		ANSIC       = "Mon Jan _2 15:04:05 2006"
    66		UnixDate    = "Mon Jan _2 15:04:05 MST 2006"
    67		RubyDate    = "Mon Jan 02 15:04:05 -0700 2006"
    68		RFC822      = "02 Jan 06 15:04 MST"
    69		RFC822Z     = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
    70		RFC850      = "Monday, 02-Jan-06 15:04:05 MST"
    71		RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST"
    72		RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
    73		RFC3339     = "2006-01-02T15:04:05Z07:00"
    74		RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
    75		Kitchen     = "3:04PM"
    76		// Handy time stamps.
    77		Stamp      = "Jan _2 15:04:05"
    78		StampMilli = "Jan _2 15:04:05.000"
    79		StampMicro = "Jan _2 15:04:05.000000"
    80		StampNano  = "Jan _2 15:04:05.000000000"
    81	)
    82	
    83	const (
    84		_                        = iota
    85		stdLongMonth             = iota + stdNeedDate  // "January"
    86		stdMonth                                       // "Jan"
    87		stdNumMonth                                    // "1"
    88		stdZeroMonth                                   // "01"
    89		stdLongWeekDay                                 // "Monday"
    90		stdWeekDay                                     // "Mon"
    91		stdDay                                         // "2"
    92		stdUnderDay                                    // "_2"
    93		stdZeroDay                                     // "02"
    94		stdHour                  = iota + stdNeedClock // "15"
    95		stdHour12                                      // "3"
    96		stdZeroHour12                                  // "03"
    97		stdMinute                                      // "4"
    98		stdZeroMinute                                  // "04"
    99		stdSecond                                      // "5"
   100		stdZeroSecond                                  // "05"
   101		stdLongYear              = iota + stdNeedDate  // "2006"
   102		stdYear                                        // "06"
   103		stdPM                    = iota + stdNeedClock // "PM"
   104		stdpm                                          // "pm"
   105		stdTZ                    = iota                // "MST"
   106		stdISO8601TZ                                   // "Z0700"  // prints Z for UTC
   107		stdISO8601SecondsTZ                            // "Z070000"
   108		stdISO8601ShortTZ                              // "Z07"
   109		stdISO8601ColonTZ                              // "Z07:00" // prints Z for UTC
   110		stdISO8601ColonSecondsTZ                       // "Z07:00:00"
   111		stdNumTZ                                       // "-0700"  // always numeric
   112		stdNumSecondsTz                                // "-070000"
   113		stdNumShortTZ                                  // "-07"    // always numeric
   114		stdNumColonTZ                                  // "-07:00" // always numeric
   115		stdNumColonSecondsTZ                           // "-07:00:00"
   116		stdFracSecond0                                 // ".0", ".00", ... , trailing zeros included
   117		stdFracSecond9                                 // ".9", ".99", ..., trailing zeros omitted
   118	
   119		stdNeedDate  = 1 << 8             // need month, day, year
   120		stdNeedClock = 2 << 8             // need hour, minute, second
   121		stdArgShift  = 16                 // extra argument in high bits, above low stdArgShift
   122		stdMask      = 1<<stdArgShift - 1 // mask out argument
   123	)
   124	
   125	// std0x records the std values for "01", "02", ..., "06".
   126	var std0x = [...]int{stdZeroMonth, stdZeroDay, stdZeroHour12, stdZeroMinute, stdZeroSecond, stdYear}
   127	
   128	// startsWithLowerCase reports whether the string has a lower-case letter at the beginning.
   129	// Its purpose is to prevent matching strings like "Month" when looking for "Mon".
   130	func startsWithLowerCase(str string) bool {
   131		if len(str) == 0 {
   132			return false
   133		}
   134		c := str[0]
   135		return 'a' <= c && c <= 'z'
   136	}
   137	
   138	// nextStdChunk finds the first occurrence of a std string in
   139	// layout and returns the text before, the std string, and the text after.
   140	func nextStdChunk(layout string) (prefix string, std int, suffix string) {
   141		for i := 0; i < len(layout); i++ {
   142			switch c := int(layout[i]); c {
   143			case 'J': // January, Jan
   144				if len(layout) >= i+3 && layout[i:i+3] == "Jan" {
   145					if len(layout) >= i+7 && layout[i:i+7] == "January" {
   146						return layout[0:i], stdLongMonth, layout[i+7:]
   147					}
   148					if !startsWithLowerCase(layout[i+3:]) {
   149						return layout[0:i], stdMonth, layout[i+3:]
   150					}
   151				}
   152	
   153			case 'M': // Monday, Mon, MST
   154				if len(layout) >= i+3 {
   155					if layout[i:i+3] == "Mon" {
   156						if len(layout) >= i+6 && layout[i:i+6] == "Monday" {
   157							return layout[0:i], stdLongWeekDay, layout[i+6:]
   158						}
   159						if !startsWithLowerCase(layout[i+3:]) {
   160							return layout[0:i], stdWeekDay, layout[i+3:]
   161						}
   162					}
   163					if layout[i:i+3] == "MST" {
   164						return layout[0:i], stdTZ, layout[i+3:]
   165					}
   166				}
   167	
   168			case '0': // 01, 02, 03, 04, 05, 06
   169				if len(layout) >= i+2 && '1' <= layout[i+1] && layout[i+1] <= '6' {
   170					return layout[0:i], std0x[layout[i+1]-'1'], layout[i+2:]
   171				}
   172	
   173			case '1': // 15, 1
   174				if len(layout) >= i+2 && layout[i+1] == '5' {
   175					return layout[0:i], stdHour, layout[i+2:]
   176				}
   177				return layout[0:i], stdNumMonth, layout[i+1:]
   178	
   179			case '2': // 2006, 2
   180				if len(layout) >= i+4 && layout[i:i+4] == "2006" {
   181					return layout[0:i], stdLongYear, layout[i+4:]
   182				}
   183				return layout[0:i], stdDay, layout[i+1:]
   184	
   185			case '_': // _2, _2006
   186				if len(layout) >= i+2 && layout[i+1] == '2' {
   187					//_2006 is really a literal _, followed by stdLongYear
   188					if len(layout) >= i+5 && layout[i+1:i+5] == "2006" {
   189						return layout[0 : i+1], stdLongYear, layout[i+5:]
   190					}
   191					return layout[0:i], stdUnderDay, layout[i+2:]
   192				}
   193	
   194			case '3':
   195				return layout[0:i], stdHour12, layout[i+1:]
   196	
   197			case '4':
   198				return layout[0:i], stdMinute, layout[i+1:]
   199	
   200			case '5':
   201				return layout[0:i], stdSecond, layout[i+1:]
   202	
   203			case 'P': // PM
   204				if len(layout) >= i+2 && layout[i+1] == 'M' {
   205					return layout[0:i], stdPM, layout[i+2:]
   206				}
   207	
   208			case 'p': // pm
   209				if len(layout) >= i+2 && layout[i+1] == 'm' {
   210					return layout[0:i], stdpm, layout[i+2:]
   211				}
   212	
   213			case '-': // -070000, -07:00:00, -0700, -07:00, -07
   214				if len(layout) >= i+7 && layout[i:i+7] == "-070000" {
   215					return layout[0:i], stdNumSecondsTz, layout[i+7:]
   216				}
   217				if len(layout) >= i+9 && layout[i:i+9] == "-07:00:00" {
   218					return layout[0:i], stdNumColonSecondsTZ, layout[i+9:]
   219				}
   220				if len(layout) >= i+5 && layout[i:i+5] == "-0700" {
   221					return layout[0:i], stdNumTZ, layout[i+5:]
   222				}
   223				if len(layout) >= i+6 && layout[i:i+6] == "-07:00" {
   224					return layout[0:i], stdNumColonTZ, layout[i+6:]
   225				}
   226				if len(layout) >= i+3 && layout[i:i+3] == "-07" {
   227					return layout[0:i], stdNumShortTZ, layout[i+3:]
   228				}
   229	
   230			case 'Z': // Z070000, Z07:00:00, Z0700, Z07:00,
   231				if len(layout) >= i+7 && layout[i:i+7] == "Z070000" {
   232					return layout[0:i], stdISO8601SecondsTZ, layout[i+7:]
   233				}
   234				if len(layout) >= i+9 && layout[i:i+9] == "Z07:00:00" {
   235					return layout[0:i], stdISO8601ColonSecondsTZ, layout[i+9:]
   236				}
   237				if len(layout) >= i+5 && layout[i:i+5] == "Z0700" {
   238					return layout[0:i], stdISO8601TZ, layout[i+5:]
   239				}
   240				if len(layout) >= i+6 && layout[i:i+6] == "Z07:00" {
   241					return layout[0:i], stdISO8601ColonTZ, layout[i+6:]
   242				}
   243				if len(layout) >= i+3 && layout[i:i+3] == "Z07" {
   244					return layout[0:i], stdISO8601ShortTZ, layout[i+3:]
   245				}
   246	
   247			case '.': // .000 or .999 - repeated digits for fractional seconds.
   248				if i+1 < len(layout) && (layout[i+1] == '0' || layout[i+1] == '9') {
   249					ch := layout[i+1]
   250					j := i + 1
   251					for j < len(layout) && layout[j] == ch {
   252						j++
   253					}
   254					// String of digits must end here - only fractional second is all digits.
   255					if !isDigit(layout, j) {
   256						std := stdFracSecond0
   257						if layout[i+1] == '9' {
   258							std = stdFracSecond9
   259						}
   260						std |= (j - (i + 1)) << stdArgShift
   261						return layout[0:i], std, layout[j:]
   262					}
   263				}
   264			}
   265		}
   266		return layout, 0, ""
   267	}
   268	
   269	var longDayNames = []string{
   270		"Sunday",
   271		"Monday",
   272		"Tuesday",
   273		"Wednesday",
   274		"Thursday",
   275		"Friday",
   276		"Saturday",
   277	}
   278	
   279	var shortDayNames = []string{
   280		"Sun",
   281		"Mon",
   282		"Tue",
   283		"Wed",
   284		"Thu",
   285		"Fri",
   286		"Sat",
   287	}
   288	
   289	var shortMonthNames = []string{
   290		"---",
   291		"Jan",
   292		"Feb",
   293		"Mar",
   294		"Apr",
   295		"May",
   296		"Jun",
   297		"Jul",
   298		"Aug",
   299		"Sep",
   300		"Oct",
   301		"Nov",
   302		"Dec",
   303	}
   304	
   305	var longMonthNames = []string{
   306		"---",
   307		"January",
   308		"February",
   309		"March",
   310		"April",
   311		"May",
   312		"June",
   313		"July",
   314		"August",
   315		"September",
   316		"October",
   317		"November",
   318		"December",
   319	}
   320	
   321	// match reports whether s1 and s2 match ignoring case.
   322	// It is assumed s1 and s2 are the same length.
   323	func match(s1, s2 string) bool {
   324		for i := 0; i < len(s1); i++ {
   325			c1 := s1[i]
   326			c2 := s2[i]
   327			if c1 != c2 {
   328				// Switch to lower-case; 'a'-'A' is known to be a single bit.
   329				c1 |= 'a' - 'A'
   330				c2 |= 'a' - 'A'
   331				if c1 != c2 || c1 < 'a' || c1 > 'z' {
   332					return false
   333				}
   334			}
   335		}
   336		return true
   337	}
   338	
   339	func lookup(tab []string, val string) (int, string, error) {
   340		for i, v := range tab {
   341			if len(val) >= len(v) && match(val[0:len(v)], v) {
   342				return i, val[len(v):], nil
   343			}
   344		}
   345		return -1, val, errBad
   346	}
   347	
   348	// appendInt appends the decimal form of x to b and returns the result.
   349	// If the decimal form (excluding sign) is shorter than width, the result is padded with leading 0's.
   350	// Duplicates functionality in strconv, but avoids dependency.
   351	func appendInt(b []byte, x int, width int) []byte {
   352		u := uint(x)
   353		if x < 0 {
   354			b = append(b, '-')
   355			u = uint(-x)
   356		}
   357	
   358		// Assemble decimal in reverse order.
   359		var buf [20]byte
   360		i := len(buf)
   361		for u >= 10 {
   362			i--
   363			q := u / 10
   364			buf[i] = byte('0' + u - q*10)
   365			u = q
   366		}
   367		i--
   368		buf[i] = byte('0' + u)
   369	
   370		// Add 0-padding.
   371		for w := len(buf) - i; w < width; w++ {
   372			b = append(b, '0')
   373		}
   374	
   375		return append(b, buf[i:]...)
   376	}
   377	
   378	// Never printed, just needs to be non-nil for return by atoi.
   379	var atoiError = errors.New("time: invalid number")
   380	
   381	// Duplicates functionality in strconv, but avoids dependency.
   382	func atoi(s string) (x int, err error) {
   383		neg := false
   384		if s != "" && (s[0] == '-' || s[0] == '+') {
   385			neg = s[0] == '-'
   386			s = s[1:]
   387		}
   388		q, rem, err := leadingInt(s)
   389		x = int(q)
   390		if err != nil || rem != "" {
   391			return 0, atoiError
   392		}
   393		if neg {
   394			x = -x
   395		}
   396		return x, nil
   397	}
   398	
   399	// formatNano appends a fractional second, as nanoseconds, to b
   400	// and returns the result.
   401	func formatNano(b []byte, nanosec uint, n int, trim bool) []byte {
   402		u := nanosec
   403		var buf [9]byte
   404		for start := len(buf); start > 0; {
   405			start--
   406			buf[start] = byte(u%10 + '0')
   407			u /= 10
   408		}
   409	
   410		if n > 9 {
   411			n = 9
   412		}
   413		if trim {
   414			for n > 0 && buf[n-1] == '0' {
   415				n--
   416			}
   417			if n == 0 {
   418				return b
   419			}
   420		}
   421		b = append(b, '.')
   422		return append(b, buf[:n]...)
   423	}
   424	
   425	// String returns the time formatted using the format string
   426	//	"2006-01-02 15:04:05.999999999 -0700 MST"
   427	func (t Time) String() string {
   428		return t.Format("2006-01-02 15:04:05.999999999 -0700 MST")
   429	}
   430	
   431	// Format returns a textual representation of the time value formatted
   432	// according to layout, which defines the format by showing how the reference
   433	// time, defined to be
   434	//	Mon Jan 2 15:04:05 -0700 MST 2006
   435	// would be displayed if it were the value; it serves as an example of the
   436	// desired output. The same display rules will then be applied to the time
   437	// value.
   438	//
   439	// A fractional second is represented by adding a period and zeros
   440	// to the end of the seconds section of layout string, as in "15:04:05.000"
   441	// to format a time stamp with millisecond precision.
   442	//
   443	// Predefined layouts ANSIC, UnixDate, RFC3339 and others describe standard
   444	// and convenient representations of the reference time. For more information
   445	// about the formats and the definition of the reference time, see the
   446	// documentation for ANSIC and the other constants defined by this package.
   447	func (t Time) Format(layout string) string {
   448		const bufSize = 64
   449		var b []byte
   450		max := len(layout) + 10
   451		if max < bufSize {
   452			var buf [bufSize]byte
   453			b = buf[:0]
   454		} else {
   455			b = make([]byte, 0, max)
   456		}
   457		b = t.AppendFormat(b, layout)
   458		return string(b)
   459	}
   460	
   461	// AppendFormat is like Format but appends the textual
   462	// representation to b and returns the extended buffer.
   463	func (t Time) AppendFormat(b []byte, layout string) []byte {
   464		var (
   465			name, offset, abs = t.locabs()
   466	
   467			year  int = -1
   468			month Month
   469			day   int
   470			hour  int = -1
   471			min   int
   472			sec   int
   473		)
   474		// Each iteration generates one std value.
   475		for layout != "" {
   476			prefix, std, suffix := nextStdChunk(layout)
   477			if prefix != "" {
   478				b = append(b, prefix...)
   479			}
   480			if std == 0 {
   481				break
   482			}
   483			layout = suffix
   484	
   485			// Compute year, month, day if needed.
   486			if year < 0 && std&stdNeedDate != 0 {
   487				year, month, day, _ = absDate(abs, true)
   488			}
   489	
   490			// Compute hour, minute, second if needed.
   491			if hour < 0 && std&stdNeedClock != 0 {
   492				hour, min, sec = absClock(abs)
   493			}
   494	
   495			switch std & stdMask {
   496			case stdYear:
   497				y := year
   498				if y < 0 {
   499					y = -y
   500				}
   501				b = appendInt(b, y%100, 2)
   502			case stdLongYear:
   503				b = appendInt(b, year, 4)
   504			case stdMonth:
   505				b = append(b, month.String()[:3]...)
   506			case stdLongMonth:
   507				m := month.String()
   508				b = append(b, m...)
   509			case stdNumMonth:
   510				b = appendInt(b, int(month), 0)
   511			case stdZeroMonth:
   512				b = appendInt(b, int(month), 2)
   513			case stdWeekDay:
   514				b = append(b, absWeekday(abs).String()[:3]...)
   515			case stdLongWeekDay:
   516				s := absWeekday(abs).String()
   517				b = append(b, s...)
   518			case stdDay:
   519				b = appendInt(b, day, 0)
   520			case stdUnderDay:
   521				if day < 10 {
   522					b = append(b, ' ')
   523				}
   524				b = appendInt(b, day, 0)
   525			case stdZeroDay:
   526				b = appendInt(b, day, 2)
   527			case stdHour:
   528				b = appendInt(b, hour, 2)
   529			case stdHour12:
   530				// Noon is 12PM, midnight is 12AM.
   531				hr := hour % 12
   532				if hr == 0 {
   533					hr = 12
   534				}
   535				b = appendInt(b, hr, 0)
   536			case stdZeroHour12:
   537				// Noon is 12PM, midnight is 12AM.
   538				hr := hour % 12
   539				if hr == 0 {
   540					hr = 12
   541				}
   542				b = appendInt(b, hr, 2)
   543			case stdMinute:
   544				b = appendInt(b, min, 0)
   545			case stdZeroMinute:
   546				b = appendInt(b, min, 2)
   547			case stdSecond:
   548				b = appendInt(b, sec, 0)
   549			case stdZeroSecond:
   550				b = appendInt(b, sec, 2)
   551			case stdPM:
   552				if hour >= 12 {
   553					b = append(b, "PM"...)
   554				} else {
   555					b = append(b, "AM"...)
   556				}
   557			case stdpm:
   558				if hour >= 12 {
   559					b = append(b, "pm"...)
   560				} else {
   561					b = append(b, "am"...)
   562				}
   563			case stdISO8601TZ, stdISO8601ColonTZ, stdISO8601SecondsTZ, stdISO8601ShortTZ, stdISO8601ColonSecondsTZ, stdNumTZ, stdNumColonTZ, stdNumSecondsTz, stdNumShortTZ, stdNumColonSecondsTZ:
   564				// Ugly special case. We cheat and take the "Z" variants
   565				// to mean "the time zone as formatted for ISO 8601".
   566				if offset == 0 && (std == stdISO8601TZ || std == stdISO8601ColonTZ || std == stdISO8601SecondsTZ || std == stdISO8601ShortTZ || std == stdISO8601ColonSecondsTZ) {
   567					b = append(b, 'Z')
   568					break
   569				}
   570				zone := offset / 60 // convert to minutes
   571				absoffset := offset
   572				if zone < 0 {
   573					b = append(b, '-')
   574					zone = -zone
   575					absoffset = -absoffset
   576				} else {
   577					b = append(b, '+')
   578				}
   579				b = appendInt(b, zone/60, 2)
   580				if std == stdISO8601ColonTZ || std == stdNumColonTZ || std == stdISO8601ColonSecondsTZ || std == stdNumColonSecondsTZ {
   581					b = append(b, ':')
   582				}
   583				if std != stdNumShortTZ && std != stdISO8601ShortTZ {
   584					b = appendInt(b, zone%60, 2)
   585				}
   586	
   587				// append seconds if appropriate
   588				if std == stdISO8601SecondsTZ || std == stdNumSecondsTz || std == stdNumColonSecondsTZ || std == stdISO8601ColonSecondsTZ {
   589					if std == stdNumColonSecondsTZ || std == stdISO8601ColonSecondsTZ {
   590						b = append(b, ':')
   591					}
   592					b = appendInt(b, absoffset%60, 2)
   593				}
   594	
   595			case stdTZ:
   596				if name != "" {
   597					b = append(b, name...)
   598					break
   599				}
   600				// No time zone known for this time, but we must print one.
   601				// Use the -0700 format.
   602				zone := offset / 60 // convert to minutes
   603				if zone < 0 {
   604					b = append(b, '-')
   605					zone = -zone
   606				} else {
   607					b = append(b, '+')
   608				}
   609				b = appendInt(b, zone/60, 2)
   610				b = appendInt(b, zone%60, 2)
   611			case stdFracSecond0, stdFracSecond9:
   612				b = formatNano(b, uint(t.Nanosecond()), std>>stdArgShift, std&stdMask == stdFracSecond9)
   613			}
   614		}
   615		return b
   616	}
   617	
   618	var errBad = errors.New("bad value for field") // placeholder not passed to user
   619	
   620	// ParseError describes a problem parsing a time string.
   621	type ParseError struct {
   622		Layout     string
   623		Value      string
   624		LayoutElem string
   625		ValueElem  string
   626		Message    string
   627	}
   628	
   629	func quote(s string) string {
   630		return "\"" + s + "\""
   631	}
   632	
   633	// Error returns the string representation of a ParseError.
   634	func (e *ParseError) Error() string {
   635		if e.Message == "" {
   636			return "parsing time " +
   637				quote(e.Value) + " as " +
   638				quote(e.Layout) + ": cannot parse " +
   639				quote(e.ValueElem) + " as " +
   640				quote(e.LayoutElem)
   641		}
   642		return "parsing time " +
   643			quote(e.Value) + e.Message
   644	}
   645	
   646	// isDigit reports whether s[i] is in range and is a decimal digit.
   647	func isDigit(s string, i int) bool {
   648		if len(s) <= i {
   649			return false
   650		}
   651		c := s[i]
   652		return '0' <= c && c <= '9'
   653	}
   654	
   655	// getnum parses s[0:1] or s[0:2] (fixed forces the latter)
   656	// as a decimal integer and returns the integer and the
   657	// remainder of the string.
   658	func getnum(s string, fixed bool) (int, string, error) {
   659		if !isDigit(s, 0) {
   660			return 0, s, errBad
   661		}
   662		if !isDigit(s, 1) {
   663			if fixed {
   664				return 0, s, errBad
   665			}
   666			return int(s[0] - '0'), s[1:], nil
   667		}
   668		return int(s[0]-'0')*10 + int(s[1]-'0'), s[2:], nil
   669	}
   670	
   671	func cutspace(s string) string {
   672		for len(s) > 0 && s[0] == ' ' {
   673			s = s[1:]
   674		}
   675		return s
   676	}
   677	
   678	// skip removes the given prefix from value,
   679	// treating runs of space characters as equivalent.
   680	func skip(value, prefix string) (string, error) {
   681		for len(prefix) > 0 {
   682			if prefix[0] == ' ' {
   683				if len(value) > 0 && value[0] != ' ' {
   684					return value, errBad
   685				}
   686				prefix = cutspace(prefix)
   687				value = cutspace(value)
   688				continue
   689			}
   690			if len(value) == 0 || value[0] != prefix[0] {
   691				return value, errBad
   692			}
   693			prefix = prefix[1:]
   694			value = value[1:]
   695		}
   696		return value, nil
   697	}
   698	
   699	// Parse parses a formatted string and returns the time value it represents.
   700	// The layout  defines the format by showing how the reference time,
   701	// defined to be
   702	//	Mon Jan 2 15:04:05 -0700 MST 2006
   703	// would be interpreted if it were the value; it serves as an example of
   704	// the input format. The same interpretation will then be made to the
   705	// input string.
   706	//
   707	// Predefined layouts ANSIC, UnixDate, RFC3339 and others describe standard
   708	// and convenient representations of the reference time. For more information
   709	// about the formats and the definition of the reference time, see the
   710	// documentation for ANSIC and the other constants defined by this package.
   711	// Also, the executable example for time.Format demonstrates the working
   712	// of the layout string in detail and is a good reference.
   713	//
   714	// Elements omitted from the value are assumed to be zero or, when
   715	// zero is impossible, one, so parsing "3:04pm" returns the time
   716	// corresponding to Jan 1, year 0, 15:04:00 UTC (note that because the year is
   717	// 0, this time is before the zero Time).
   718	// Years must be in the range 0000..9999. The day of the week is checked
   719	// for syntax but it is otherwise ignored.
   720	//
   721	// In the absence of a time zone indicator, Parse returns a time in UTC.
   722	//
   723	// When parsing a time with a zone offset like -0700, if the offset corresponds
   724	// to a time zone used by the current location (Local), then Parse uses that
   725	// location and zone in the returned time. Otherwise it records the time as
   726	// being in a fabricated location with time fixed at the given zone offset.
   727	//
   728	// No checking is done that the day of the month is within the month's
   729	// valid dates; any one- or two-digit value is accepted. For example
   730	// February 31 and even February 99 are valid dates, specifying dates
   731	// in March and May. This behavior is consistent with time.Date.
   732	//
   733	// When parsing a time with a zone abbreviation like MST, if the zone abbreviation
   734	// has a defined offset in the current location, then that offset is used.
   735	// The zone abbreviation "UTC" is recognized as UTC regardless of location.
   736	// If the zone abbreviation is unknown, Parse records the time as being
   737	// in a fabricated location with the given zone abbreviation and a zero offset.
   738	// This choice means that such a time can be parsed and reformatted with the
   739	// same layout losslessly, but the exact instant used in the representation will
   740	// differ by the actual zone offset. To avoid such problems, prefer time layouts
   741	// that use a numeric zone offset, or use ParseInLocation.
   742	func Parse(layout, value string) (Time, error) {
   743		return parse(layout, value, UTC, Local)
   744	}
   745	
   746	// ParseInLocation is like Parse but differs in two important ways.
   747	// First, in the absence of time zone information, Parse interprets a time as UTC;
   748	// ParseInLocation interprets the time as in the given location.
   749	// Second, when given a zone offset or abbreviation, Parse tries to match it
   750	// against the Local location; ParseInLocation uses the given location.
   751	func ParseInLocation(layout, value string, loc *Location) (Time, error) {
   752		return parse(layout, value, loc, loc)
   753	}
   754	
   755	func parse(layout, value string, defaultLocation, local *Location) (Time, error) {
   756		alayout, avalue := layout, value
   757		rangeErrString := "" // set if a value is out of range
   758		amSet := false       // do we need to subtract 12 from the hour for midnight?
   759		pmSet := false       // do we need to add 12 to the hour?
   760	
   761		// Time being constructed.
   762		var (
   763			year       int
   764			month      int = 1 // January
   765			day        int = 1
   766			hour       int
   767			min        int
   768			sec        int
   769			nsec       int
   770			z          *Location
   771			zoneOffset int = -1
   772			zoneName   string
   773		)
   774	
   775		// Each iteration processes one std value.
   776		for {
   777			var err error
   778			prefix, std, suffix := nextStdChunk(layout)
   779			stdstr := layout[len(prefix) : len(layout)-len(suffix)]
   780			value, err = skip(value, prefix)
   781			if err != nil {
   782				return Time{}, &ParseError{alayout, avalue, prefix, value, ""}
   783			}
   784			if std == 0 {
   785				if len(value) != 0 {
   786					return Time{}, &ParseError{alayout, avalue, "", value, ": extra text: " + value}
   787				}
   788				break
   789			}
   790			layout = suffix
   791			var p string
   792			switch std & stdMask {
   793			case stdYear:
   794				if len(value) < 2 {
   795					err = errBad
   796					break
   797				}
   798				p, value = value[0:2], value[2:]
   799				year, err = atoi(p)
   800				if year >= 69 { // Unix time starts Dec 31 1969 in some time zones
   801					year += 1900
   802				} else {
   803					year += 2000
   804				}
   805			case stdLongYear:
   806				if len(value) < 4 || !isDigit(value, 0) {
   807					err = errBad
   808					break
   809				}
   810				p, value = value[0:4], value[4:]
   811				year, err = atoi(p)
   812			case stdMonth:
   813				month, value, err = lookup(shortMonthNames, value)
   814			case stdLongMonth:
   815				month, value, err = lookup(longMonthNames, value)
   816			case stdNumMonth, stdZeroMonth:
   817				month, value, err = getnum(value, std == stdZeroMonth)
   818				if month <= 0 || 12 < month {
   819					rangeErrString = "month"
   820				}
   821			case stdWeekDay:
   822				// Ignore weekday except for error checking.
   823				_, value, err = lookup(shortDayNames, value)
   824			case stdLongWeekDay:
   825				_, value, err = lookup(longDayNames, value)
   826			case stdDay, stdUnderDay, stdZeroDay:
   827				if std == stdUnderDay && len(value) > 0 && value[0] == ' ' {
   828					value = value[1:]
   829				}
   830				day, value, err = getnum(value, std == stdZeroDay)
   831				if day < 0 {
   832					// Note that we allow any one- or two-digit day here.
   833					rangeErrString = "day"
   834				}
   835			case stdHour:
   836				hour, value, err = getnum(value, false)
   837				if hour < 0 || 24 <= hour {
   838					rangeErrString = "hour"
   839				}
   840			case stdHour12, stdZeroHour12:
   841				hour, value, err = getnum(value, std == stdZeroHour12)
   842				if hour < 0 || 12 < hour {
   843					rangeErrString = "hour"
   844				}
   845			case stdMinute, stdZeroMinute:
   846				min, value, err = getnum(value, std == stdZeroMinute)
   847				if min < 0 || 60 <= min {
   848					rangeErrString = "minute"
   849				}
   850			case stdSecond, stdZeroSecond:
   851				sec, value, err = getnum(value, std == stdZeroSecond)
   852				if sec < 0 || 60 <= sec {
   853					rangeErrString = "second"
   854					break
   855				}
   856				// Special case: do we have a fractional second but no
   857				// fractional second in the format?
   858				if len(value) >= 2 && value[0] == '.' && isDigit(value, 1) {
   859					_, std, _ = nextStdChunk(layout)
   860					std &= stdMask
   861					if std == stdFracSecond0 || std == stdFracSecond9 {
   862						// Fractional second in the layout; proceed normally
   863						break
   864					}
   865					// No fractional second in the layout but we have one in the input.
   866					n := 2
   867					for ; n < len(value) && isDigit(value, n); n++ {
   868					}
   869					nsec, rangeErrString, err = parseNanoseconds(value, n)
   870					value = value[n:]
   871				}
   872			case stdPM:
   873				if len(value) < 2 {
   874					err = errBad
   875					break
   876				}
   877				p, value = value[0:2], value[2:]
   878				switch p {
   879				case "PM":
   880					pmSet = true
   881				case "AM":
   882					amSet = true
   883				default:
   884					err = errBad
   885				}
   886			case stdpm:
   887				if len(value) < 2 {
   888					err = errBad
   889					break
   890				}
   891				p, value = value[0:2], value[2:]
   892				switch p {
   893				case "pm":
   894					pmSet = true
   895				case "am":
   896					amSet = true
   897				default:
   898					err = errBad
   899				}
   900			case stdISO8601TZ, stdISO8601ColonTZ, stdISO8601SecondsTZ, stdISO8601ShortTZ, stdISO8601ColonSecondsTZ, stdNumTZ, stdNumShortTZ, stdNumColonTZ, stdNumSecondsTz, stdNumColonSecondsTZ:
   901				if (std == stdISO8601TZ || std == stdISO8601ShortTZ || std == stdISO8601ColonTZ) && len(value) >= 1 && value[0] == 'Z' {
   902					value = value[1:]
   903					z = UTC
   904					break
   905				}
   906				var sign, hour, min, seconds string
   907				if std == stdISO8601ColonTZ || std == stdNumColonTZ {
   908					if len(value) < 6 {
   909						err = errBad
   910						break
   911					}
   912					if value[3] != ':' {
   913						err = errBad
   914						break
   915					}
   916					sign, hour, min, seconds, value = value[0:1], value[1:3], value[4:6], "00", value[6:]
   917				} else if std == stdNumShortTZ || std == stdISO8601ShortTZ {
   918					if len(value) < 3 {
   919						err = errBad
   920						break
   921					}
   922					sign, hour, min, seconds, value = value[0:1], value[1:3], "00", "00", value[3:]
   923				} else if std == stdISO8601ColonSecondsTZ || std == stdNumColonSecondsTZ {
   924					if len(value) < 9 {
   925						err = errBad
   926						break
   927					}
   928					if value[3] != ':' || value[6] != ':' {
   929						err = errBad
   930						break
   931					}
   932					sign, hour, min, seconds, value = value[0:1], value[1:3], value[4:6], value[7:9], value[9:]
   933				} else if std == stdISO8601SecondsTZ || std == stdNumSecondsTz {
   934					if len(value) < 7 {
   935						err = errBad
   936						break
   937					}
   938					sign, hour, min, seconds, value = value[0:1], value[1:3], value[3:5], value[5:7], value[7:]
   939				} else {
   940					if len(value) < 5 {
   941						err = errBad
   942						break
   943					}
   944					sign, hour, min, seconds, value = value[0:1], value[1:3], value[3:5], "00", value[5:]
   945				}
   946				var hr, mm, ss int
   947				hr, err = atoi(hour)
   948				if err == nil {
   949					mm, err = atoi(min)
   950				}
   951				if err == nil {
   952					ss, err = atoi(seconds)
   953				}
   954				zoneOffset = (hr*60+mm)*60 + ss // offset is in seconds
   955				switch sign[0] {
   956				case '+':
   957				case '-':
   958					zoneOffset = -zoneOffset
   959				default:
   960					err = errBad
   961				}
   962			case stdTZ:
   963				// Does it look like a time zone?
   964				if len(value) >= 3 && value[0:3] == "UTC" {
   965					z = UTC
   966					value = value[3:]
   967					break
   968				}
   969				n, ok := parseTimeZone(value)
   970				if !ok {
   971					err = errBad
   972					break
   973				}
   974				zoneName, value = value[:n], value[n:]
   975	
   976			case stdFracSecond0:
   977				// stdFracSecond0 requires the exact number of digits as specified in
   978				// the layout.
   979				ndigit := 1 + (std >> stdArgShift)
   980				if len(value) < ndigit {
   981					err = errBad
   982					break
   983				}
   984				nsec, rangeErrString, err = parseNanoseconds(value, ndigit)
   985				value = value[ndigit:]
   986	
   987			case stdFracSecond9:
   988				if len(value) < 2 || value[0] != '.' || value[1] < '0' || '9' < value[1] {
   989					// Fractional second omitted.
   990					break
   991				}
   992				// Take any number of digits, even more than asked for,
   993				// because it is what the stdSecond case would do.
   994				i := 0
   995				for i < 9 && i+1 < len(value) && '0' <= value[i+1] && value[i+1] <= '9' {
   996					i++
   997				}
   998				nsec, rangeErrString, err = parseNanoseconds(value, 1+i)
   999				value = value[1+i:]
  1000			}
  1001			if rangeErrString != "" {
  1002				return Time{}, &ParseError{alayout, avalue, stdstr, value, ": " + rangeErrString + " out of range"}
  1003			}
  1004			if err != nil {
  1005				return Time{}, &ParseError{alayout, avalue, stdstr, value, ""}
  1006			}
  1007		}
  1008		if pmSet && hour < 12 {
  1009			hour += 12
  1010		} else if amSet && hour == 12 {
  1011			hour = 0
  1012		}
  1013	
  1014		// Validate the day of the month.
  1015		if day < 1 || day > daysIn(Month(month), year) {
  1016			return Time{}, &ParseError{alayout, avalue, "", value, ": day out of range"}
  1017		}
  1018	
  1019		if z != nil {
  1020			return Date(year, Month(month), day, hour, min, sec, nsec, z), nil
  1021		}
  1022	
  1023		if zoneOffset != -1 {
  1024			t := Date(year, Month(month), day, hour, min, sec, nsec, UTC)
  1025			t.sec -= int64(zoneOffset)
  1026	
  1027			// Look for local zone with the given offset.
  1028			// If that zone was in effect at the given time, use it.
  1029			name, offset, _, _, _ := local.lookup(t.sec + internalToUnix)
  1030			if offset == zoneOffset && (zoneName == "" || name == zoneName) {
  1031				t.setLoc(local)
  1032				return t, nil
  1033			}
  1034	
  1035			// Otherwise create fake zone to record offset.
  1036			t.setLoc(FixedZone(zoneName, zoneOffset))
  1037			return t, nil
  1038		}
  1039	
  1040		if zoneName != "" {
  1041			t := Date(year, Month(month), day, hour, min, sec, nsec, UTC)
  1042			// Look for local zone with the given offset.
  1043			// If that zone was in effect at the given time, use it.
  1044			offset, _, ok := local.lookupName(zoneName, t.sec+internalToUnix)
  1045			if ok {
  1046				t.sec -= int64(offset)
  1047				t.setLoc(local)
  1048				return t, nil
  1049			}
  1050	
  1051			// Otherwise, create fake zone with unknown offset.
  1052			if len(zoneName) > 3 && zoneName[:3] == "GMT" {
  1053				offset, _ = atoi(zoneName[3:]) // Guaranteed OK by parseGMT.
  1054				offset *= 3600
  1055			}
  1056			t.setLoc(FixedZone(zoneName, offset))
  1057			return t, nil
  1058		}
  1059	
  1060		// Otherwise, fall back to default.
  1061		return Date(year, Month(month), day, hour, min, sec, nsec, defaultLocation), nil
  1062	}
  1063	
  1064	// parseTimeZone parses a time zone string and returns its length. Time zones
  1065	// are human-generated and unpredictable. We can't do precise error checking.
  1066	// On the other hand, for a correct parse there must be a time zone at the
  1067	// beginning of the string, so it's almost always true that there's one
  1068	// there. We look at the beginning of the string for a run of upper-case letters.
  1069	// If there are more than 5, it's an error.
  1070	// If there are 4 or 5 and the last is a T, it's a time zone.
  1071	// If there are 3, it's a time zone.
  1072	// Otherwise, other than special cases, it's not a time zone.
  1073	// GMT is special because it can have an hour offset.
  1074	func parseTimeZone(value string) (length int, ok bool) {
  1075		if len(value) < 3 {
  1076			return 0, false
  1077		}
  1078		// Special case 1: ChST and MeST are the only zones with a lower-case letter.
  1079		if len(value) >= 4 && (value[:4] == "ChST" || value[:4] == "MeST") {
  1080			return 4, true
  1081		}
  1082		// Special case 2: GMT may have an hour offset; treat it specially.
  1083		if value[:3] == "GMT" {
  1084			length = parseGMT(value)
  1085			return length, true
  1086		}
  1087		// How many upper-case letters are there? Need at least three, at most five.
  1088		var nUpper int
  1089		for nUpper = 0; nUpper < 6; nUpper++ {
  1090			if nUpper >= len(value) {
  1091				break
  1092			}
  1093			if c := value[nUpper]; c < 'A' || 'Z' < c {
  1094				break
  1095			}
  1096		}
  1097		switch nUpper {
  1098		case 0, 1, 2, 6:
  1099			return 0, false
  1100		case 5: // Must end in T to match.
  1101			if value[4] == 'T' {
  1102				return 5, true
  1103			}
  1104		case 4:
  1105			// Must end in T, except one special case.
  1106			if value[3] == 'T' || value[:4] == "WITA" {
  1107				return 4, true
  1108			}
  1109		case 3:
  1110			return 3, true
  1111		}
  1112		return 0, false
  1113	}
  1114	
  1115	// parseGMT parses a GMT time zone. The input string is known to start "GMT".
  1116	// The function checks whether that is followed by a sign and a number in the
  1117	// range -14 through 12 excluding zero.
  1118	func parseGMT(value string) int {
  1119		value = value[3:]
  1120		if len(value) == 0 {
  1121			return 3
  1122		}
  1123		sign := value[0]
  1124		if sign != '-' && sign != '+' {
  1125			return 3
  1126		}
  1127		x, rem, err := leadingInt(value[1:])
  1128		if err != nil {
  1129			return 3
  1130		}
  1131		if sign == '-' {
  1132			x = -x
  1133		}
  1134		if x == 0 || x < -14 || 12 < x {
  1135			return 3
  1136		}
  1137		return 3 + len(value) - len(rem)
  1138	}
  1139	
  1140	func parseNanoseconds(value string, nbytes int) (ns int, rangeErrString string, err error) {
  1141		if value[0] != '.' {
  1142			err = errBad
  1143			return
  1144		}
  1145		if ns, err = atoi(value[1:nbytes]); err != nil {
  1146			return
  1147		}
  1148		if ns < 0 || 1e9 <= ns {
  1149			rangeErrString = "fractional second"
  1150			return
  1151		}
  1152		// We need nanoseconds, which means scaling by the number
  1153		// of missing digits in the format, maximum length 10. If it's
  1154		// longer than 10, we won't scale.
  1155		scaleDigits := 10 - nbytes
  1156		for i := 0; i < scaleDigits; i++ {
  1157			ns *= 10
  1158		}
  1159		return
  1160	}
  1161	
  1162	var errLeadingInt = errors.New("time: bad [0-9]*") // never printed
  1163	
  1164	// leadingInt consumes the leading [0-9]* from s.
  1165	func leadingInt(s string) (x int64, rem string, err error) {
  1166		i := 0
  1167		for ; i < len(s); i++ {
  1168			c := s[i]
  1169			if c < '0' || c > '9' {
  1170				break
  1171			}
  1172			if x > (1<<63-1)/10 {
  1173				// overflow
  1174				return 0, "", errLeadingInt
  1175			}
  1176			x = x*10 + int64(c) - '0'
  1177			if x < 0 {
  1178				// overflow
  1179				return 0, "", errLeadingInt
  1180			}
  1181		}
  1182		return x, s[i:], nil
  1183	}
  1184	
  1185	// leadingFraction consumes the leading [0-9]* from s.
  1186	// It is used only for fractions, so does not return an error on overflow,
  1187	// it just stops accumulating precision.
  1188	func leadingFraction(s string) (x int64, scale float64, rem string) {
  1189		i := 0
  1190		scale = 1
  1191		overflow := false
  1192		for ; i < len(s); i++ {
  1193			c := s[i]
  1194			if c < '0' || c > '9' {
  1195				break
  1196			}
  1197			if overflow {
  1198				continue
  1199			}
  1200			if x > (1<<63-1)/10 {
  1201				// It's possible for overflow to give a positive number, so take care.
  1202				overflow = true
  1203				continue
  1204			}
  1205			y := x*10 + int64(c) - '0'
  1206			if y < 0 {
  1207				overflow = true
  1208				continue
  1209			}
  1210			x = y
  1211			scale *= 10
  1212		}
  1213		return x, scale, s[i:]
  1214	}
  1215	
  1216	var unitMap = map[string]int64{
  1217		"ns": int64(Nanosecond),
  1218		"us": int64(Microsecond),
  1219		"µs": int64(Microsecond), // U+00B5 = micro symbol
  1220		"μs": int64(Microsecond), // U+03BC = Greek letter mu
  1221		"ms": int64(Millisecond),
  1222		"s":  int64(Second),
  1223		"m":  int64(Minute),
  1224		"h":  int64(Hour),
  1225	}
  1226	
  1227	// ParseDuration parses a duration string.
  1228	// A duration string is a possibly signed sequence of
  1229	// decimal numbers, each with optional fraction and a unit suffix,
  1230	// such as "300ms", "-1.5h" or "2h45m".
  1231	// Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
  1232	func ParseDuration(s string) (Duration, error) {
  1233		// [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+
  1234		orig := s
  1235		var d int64
  1236		neg := false
  1237	
  1238		// Consume [-+]?
  1239		if s != "" {
  1240			c := s[0]
  1241			if c == '-' || c == '+' {
  1242				neg = c == '-'
  1243				s = s[1:]
  1244			}
  1245		}
  1246		// Special case: if all that is left is "0", this is zero.
  1247		if s == "0" {
  1248			return 0, nil
  1249		}
  1250		if s == "" {
  1251			return 0, errors.New("time: invalid duration " + orig)
  1252		}
  1253		for s != "" {
  1254			var (
  1255				v, f  int64       // integers before, after decimal point
  1256				scale float64 = 1 // value = v + f/scale
  1257			)
  1258	
  1259			var err error
  1260	
  1261			// The next character must be [0-9.]
  1262			if !(s[0] == '.' || '0' <= s[0] && s[0] <= '9') {
  1263				return 0, errors.New("time: invalid duration " + orig)
  1264			}
  1265			// Consume [0-9]*
  1266			pl := len(s)
  1267			v, s, err = leadingInt(s)
  1268			if err != nil {
  1269				return 0, errors.New("time: invalid duration " + orig)
  1270			}
  1271			pre := pl != len(s) // whether we consumed anything before a period
  1272	
  1273			// Consume (\.[0-9]*)?
  1274			post := false
  1275			if s != "" && s[0] == '.' {
  1276				s = s[1:]
  1277				pl := len(s)
  1278				f, scale, s = leadingFraction(s)
  1279				post = pl != len(s)
  1280			}
  1281			if !pre && !post {
  1282				// no digits (e.g. ".s" or "-.s")
  1283				return 0, errors.New("time: invalid duration " + orig)
  1284			}
  1285	
  1286			// Consume unit.
  1287			i := 0
  1288			for ; i < len(s); i++ {
  1289				c := s[i]
  1290				if c == '.' || '0' <= c && c <= '9' {
  1291					break
  1292				}
  1293			}
  1294			if i == 0 {
  1295				return 0, errors.New("time: missing unit in duration " + orig)
  1296			}
  1297			u := s[:i]
  1298			s = s[i:]
  1299			unit, ok := unitMap[u]
  1300			if !ok {
  1301				return 0, errors.New("time: unknown unit " + u + " in duration " + orig)
  1302			}
  1303			if v > (1<<63-1)/unit {
  1304				// overflow
  1305				return 0, errors.New("time: invalid duration " + orig)
  1306			}
  1307			v *= unit
  1308			if f > 0 {
  1309				// float64 is needed to be nanosecond accurate for fractions of hours.
  1310				// v >= 0 && (f*unit/scale) <= 3.6e+12 (ns/h, h is the largest unit)
  1311				v += int64(float64(f) * (float64(unit) / scale))
  1312				if v < 0 {
  1313					// overflow
  1314					return 0, errors.New("time: invalid duration " + orig)
  1315				}
  1316			}
  1317			d += v
  1318			if d < 0 {
  1319				// overflow
  1320				return 0, errors.New("time: invalid duration " + orig)
  1321			}
  1322		}
  1323	
  1324		if neg {
  1325			d = -d
  1326		}
  1327		return Duration(d), nil
  1328	}
  1329	

View as plain text