Home | History | Annotate | Download | only in time
      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