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