Copyright 2010 The Go Authors. All rights reserved. Use of this source code is governed by a BSD-style license that can be found in the LICENSE file.

package time

import 
These are predefined layouts for use in Time.Format and time.Parse. The reference time used in the layouts is the specific time: Mon Jan 2 15:04:05 MST 2006 which is Unix time 1136239445. Since MST is GMT-0700, the reference time can be thought of as 01/02 03:04:05PM '06 -0700 To define your own format, write down what the reference time would look like formatted your way; see the values of constants like ANSIC, StampMicro or Kitchen for examples. The model is to demonstrate what the reference time looks like so that the Format and Parse methods can apply the same transformation to a general time value. Some valid layouts are invalid time values for time.Parse, due to formats such as _ for space padding and Z for zone information. Within the format string, an underscore _ represents a space that may be replaced by a digit if the following number (a day) has two digits; for compatibility with fixed-width Unix time formats. A decimal point followed by one or more zeros represents a fractional second, printed to the given number of decimal places. A decimal point followed by one or more nines represents a fractional second, printed to the given number of decimal places, with trailing zeros removed. When parsing (only), the input may contain a fractional second field immediately after the seconds field, even if the layout does not signify its presence. In that case a decimal point followed by a maximal series of digits is parsed as a fractional second. Numeric time zone offsets format as follows: -0700 ±hhmm -07:00 ±hh:mm -07 ±hh Replacing the sign in the format with a Z triggers the ISO 8601 behavior of printing Z instead of an offset for the UTC zone. Thus: Z0700 Z or ±hhmm Z07:00 Z or ±hh:mm Z07 Z or ±hh The recognized day of week formats are "Mon" and "Monday". The recognized month formats are "Jan" and "January". The formats 2, _2, and 02 are unpadded, space-padded, and zero-padded day of month. The formats __2 and 002 are space-padded and zero-padded three-character day of year; there is no unpadded day of year format. Text in the format string that is not recognized as part of the reference time is echoed verbatim during Format and expected to appear verbatim in the input to Parse. The executable example for Time.Format demonstrates the working of the layout string in detail and is a good reference. Note that the RFC822, RFC850, and RFC1123 formats should be applied only to local times. Applying them to UTC times will use "UTC" as the time zone abbreviation, while strictly speaking those RFCs require the use of "GMT" in that case. In general RFC1123Z should be used instead of RFC1123 for servers that insist on that format, and RFC3339 should be preferred for new protocols. RFC3339, RFC822, RFC822Z, RFC1123, and RFC1123Z are useful for formatting; when used with time.Parse they do not accept all the time formats permitted by the RFCs and they do accept time formats not formally defined. The RFC3339Nano format removes trailing zeros from the seconds field and thus may not sort correctly once formatted.
const (
	ANSIC       = "Mon Jan _2 15:04:05 2006"
	UnixDate    = "Mon Jan _2 15:04:05 MST 2006"
	RubyDate    = "Mon Jan 02 15:04:05 -0700 2006"
	RFC822      = "02 Jan 06 15:04 MST"
	RFC822Z     = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
	RFC850      = "Monday, 02-Jan-06 15:04:05 MST"
	RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST"
	RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
	RFC3339     = "2006-01-02T15:04:05Z07:00"
	RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
Handy time stamps.
	Stamp      = "Jan _2 15:04:05"
	StampMilli = "Jan _2 15:04:05.000"
	StampMicro = "Jan _2 15:04:05.000000"
	StampNano  = "Jan _2 15:04:05.000000000"
)

const (
	_                        = iota
	stdLongMonth             = iota + stdNeedDate  // "January"
	stdMonth                                       // "Jan"
	stdNumMonth                                    // "1"
	stdZeroMonth                                   // "01"
	stdLongWeekDay                                 // "Monday"
	stdWeekDay                                     // "Mon"
	stdDay                                         // "2"
	stdUnderDay                                    // "_2"
	stdZeroDay                                     // "02"
	stdUnderYearDay                                // "__2"
	stdZeroYearDay                                 // "002"
	stdHour                  = iota + stdNeedClock // "15"
	stdHour12                                      // "3"
	stdZeroHour12                                  // "03"
	stdMinute                                      // "4"
	stdZeroMinute                                  // "04"
	stdSecond                                      // "5"
	stdZeroSecond                                  // "05"
	stdLongYear              = iota + stdNeedDate  // "2006"
	stdYear                                        // "06"
	stdPM                    = iota + stdNeedClock // "PM"
	stdpm                                          // "pm"
	stdTZ                    = iota                // "MST"
	stdISO8601TZ                                   // "Z0700"  // prints Z for UTC
	stdISO8601SecondsTZ                            // "Z070000"
	stdISO8601ShortTZ                              // "Z07"
	stdISO8601ColonTZ                              // "Z07:00" // prints Z for UTC
	stdISO8601ColonSecondsTZ                       // "Z07:00:00"
	stdNumTZ                                       // "-0700"  // always numeric
	stdNumSecondsTz                                // "-070000"
	stdNumShortTZ                                  // "-07"    // always numeric
	stdNumColonTZ                                  // "-07:00" // always numeric
	stdNumColonSecondsTZ                           // "-07:00:00"
	stdFracSecond0                                 // ".0", ".00", ... , trailing zeros included
	stdFracSecond9                                 // ".9", ".99", ..., trailing zeros omitted

	stdNeedDate  = 1 << 8             // need month, day, year
	stdNeedClock = 2 << 8             // need hour, minute, second
	stdArgShift  = 16                 // extra argument in high bits, above low stdArgShift
	stdMask      = 1<<stdArgShift - 1 // mask out argument
)
std0x records the std values for "01", "02", ..., "06".
startsWithLowerCase reports whether the string has a lower-case letter at the beginning. Its purpose is to prevent matching strings like "Month" when looking for "Mon".
func ( string) bool {
	if len() == 0 {
		return false
	}
	 := [0]
	return 'a' <=  &&  <= 'z'
}
nextStdChunk finds the first occurrence of a std string in layout and returns the text before, the std string, and the text after.
func ( string) ( string,  int,  string) {
	for  := 0;  < len(); ++ {
		switch  := int([]);  {
		case 'J': // January, Jan
			if len() >= +3 && [:+3] == "Jan" {
				if len() >= +7 && [:+7] == "January" {
					return [0:], stdLongMonth, [+7:]
				}
				if !startsWithLowerCase([+3:]) {
					return [0:], stdMonth, [+3:]
				}
			}

		case 'M': // Monday, Mon, MST
			if len() >= +3 {
				if [:+3] == "Mon" {
					if len() >= +6 && [:+6] == "Monday" {
						return [0:], stdLongWeekDay, [+6:]
					}
					if !startsWithLowerCase([+3:]) {
						return [0:], stdWeekDay, [+3:]
					}
				}
				if [:+3] == "MST" {
					return [0:], stdTZ, [+3:]
				}
			}

		case '0': // 01, 02, 03, 04, 05, 06, 002
			if len() >= +2 && '1' <= [+1] && [+1] <= '6' {
				return [0:], std0x[[+1]-'1'], [+2:]
			}
			if len() >= +3 && [+1] == '0' && [+2] == '2' {
				return [0:], stdZeroYearDay, [+3:]
			}

		case '1': // 15, 1
			if len() >= +2 && [+1] == '5' {
				return [0:], stdHour, [+2:]
			}
			return [0:], stdNumMonth, [+1:]

		case '2': // 2006, 2
			if len() >= +4 && [:+4] == "2006" {
				return [0:], stdLongYear, [+4:]
			}
			return [0:], stdDay, [+1:]

		case '_': // _2, _2006, __2
_2006 is really a literal _, followed by stdLongYear
				if len() >= +5 && [+1:+5] == "2006" {
					return [0 : +1], stdLongYear, [+5:]
				}
				return [0:], stdUnderDay, [+2:]
			}
			if len() >= +3 && [+1] == '_' && [+2] == '2' {
				return [0:], stdUnderYearDay, [+3:]
			}

		case '3':
			return [0:], stdHour12, [+1:]

		case '4':
			return [0:], stdMinute, [+1:]

		case '5':
			return [0:], stdSecond, [+1:]

		case 'P': // PM
			if len() >= +2 && [+1] == 'M' {
				return [0:], stdPM, [+2:]
			}

		case 'p': // pm
			if len() >= +2 && [+1] == 'm' {
				return [0:], stdpm, [+2:]
			}

		case '-': // -070000, -07:00:00, -0700, -07:00, -07
			if len() >= +7 && [:+7] == "-070000" {
				return [0:], stdNumSecondsTz, [+7:]
			}
			if len() >= +9 && [:+9] == "-07:00:00" {
				return [0:], stdNumColonSecondsTZ, [+9:]
			}
			if len() >= +5 && [:+5] == "-0700" {
				return [0:], stdNumTZ, [+5:]
			}
			if len() >= +6 && [:+6] == "-07:00" {
				return [0:], stdNumColonTZ, [+6:]
			}
			if len() >= +3 && [:+3] == "-07" {
				return [0:], stdNumShortTZ, [+3:]
			}

		case 'Z': // Z070000, Z07:00:00, Z0700, Z07:00,
			if len() >= +7 && [:+7] == "Z070000" {
				return [0:], stdISO8601SecondsTZ, [+7:]
			}
			if len() >= +9 && [:+9] == "Z07:00:00" {
				return [0:], stdISO8601ColonSecondsTZ, [+9:]
			}
			if len() >= +5 && [:+5] == "Z0700" {
				return [0:], stdISO8601TZ, [+5:]
			}
			if len() >= +6 && [:+6] == "Z07:00" {
				return [0:], stdISO8601ColonTZ, [+6:]
			}
			if len() >= +3 && [:+3] == "Z07" {
				return [0:], stdISO8601ShortTZ, [+3:]
			}

		case '.': // .000 or .999 - repeated digits for fractional seconds.
			if +1 < len() && ([+1] == '0' || [+1] == '9') {
				 := [+1]
				 :=  + 1
				for  < len() && [] ==  {
					++
String of digits must end here - only fractional second is all digits.
				if !isDigit(, ) {
					 := stdFracSecond0
					if [+1] == '9' {
						 = stdFracSecond9
					}
					 |= ( - ( + 1)) << stdArgShift
					return [0:], , [:]
				}
			}
		}
	}
	return , 0, ""
}

var longDayNames = []string{
	"Sunday",
	"Monday",
	"Tuesday",
	"Wednesday",
	"Thursday",
	"Friday",
	"Saturday",
}

var shortDayNames = []string{
	"Sun",
	"Mon",
	"Tue",
	"Wed",
	"Thu",
	"Fri",
	"Sat",
}

var shortMonthNames = []string{
	"Jan",
	"Feb",
	"Mar",
	"Apr",
	"May",
	"Jun",
	"Jul",
	"Aug",
	"Sep",
	"Oct",
	"Nov",
	"Dec",
}

var longMonthNames = []string{
	"January",
	"February",
	"March",
	"April",
	"May",
	"June",
	"July",
	"August",
	"September",
	"October",
	"November",
	"December",
}
match reports whether s1 and s2 match ignoring case. It is assumed s1 and s2 are the same length.
func (,  string) bool {
	for  := 0;  < len(); ++ {
		 := []
		 := []
Switch to lower-case; 'a'-'A' is known to be a single bit.
			 |= 'a' - 'A'
			 |= 'a' - 'A'
			if  !=  ||  < 'a' ||  > 'z' {
				return false
			}
		}
	}
	return true
}

func ( []string,  string) (int, string, error) {
	for ,  := range  {
		if len() >= len() && match([0:len()], ) {
			return , [len():], nil
		}
	}
	return -1, , errBad
}
appendInt appends the decimal form of x to b and returns the result. If the decimal form (excluding sign) is shorter than width, the result is padded with leading 0's. Duplicates functionality in strconv, but avoids dependency.
func ( []byte,  int,  int) []byte {
	 := uint()
	if  < 0 {
		 = append(, '-')
		 = uint(-)
	}
Assemble decimal in reverse order.
	var  [20]byte
	 := len()
	for  >= 10 {
		--
		 :=  / 10
		[] = byte('0' +  - *10)
		 = 
	}
	--
	[] = byte('0' + )
Add 0-padding.
	for  := len() - ;  < ; ++ {
		 = append(, '0')
	}

	return append(, [:]...)
}
Never printed, just needs to be non-nil for return by atoi.
var atoiError = errors.New("time: invalid number")
Duplicates functionality in strconv, but avoids dependency.
func ( string) ( int,  error) {
	 := false
	if  != "" && ([0] == '-' || [0] == '+') {
		 = [0] == '-'
		 = [1:]
	}
	, ,  := leadingInt()
	 = int()
	if  != nil ||  != "" {
		return 0, atoiError
	}
	if  {
		 = -
	}
	return , nil
}
formatNano appends a fractional second, as nanoseconds, to b and returns the result.
func ( []byte,  uint,  int,  bool) []byte {
	 := 
	var  [9]byte
	for  := len();  > 0; {
		--
		[] = byte(%10 + '0')
		 /= 10
	}

	if  > 9 {
		 = 9
	}
	if  {
		for  > 0 && [-1] == '0' {
			--
		}
		if  == 0 {
			return 
		}
	}
	 = append(, '.')
	return append(, [:]...)
}
String returns the time formatted using the format string "2006-01-02 15:04:05.999999999 -0700 MST" If the time has a monotonic clock reading, the returned string includes a final field "m=±<value>", where value is the monotonic clock reading formatted as a decimal number of seconds. The returned string is meant for debugging; for a stable serialized representation, use t.MarshalText, t.MarshalBinary, or t.Format with an explicit format string.
func ( Time) () string {
	 := .Format("2006-01-02 15:04:05.999999999 -0700 MST")
Format monotonic clock reading as m=±ddd.nnnnnnnnn.
	if .wall&hasMonotonic != 0 {
		 := uint64(.ext)
		 := byte('+')
		if .ext < 0 {
			 = '-'
			 = -
		}
		,  := /1e9, %1e9
		,  := /1e9, %1e9
		var  []byte
		 = append(, " m="...)
		 = append(, )
		 := 0
		if  != 0 {
			 = appendInt(, int(), 0)
			 = 9
		}
		 = appendInt(, int(), )
		 = append(, '.')
		 = appendInt(, int(), 9)
		 += string()
	}
	return 
}
Format returns a textual representation of the time value formatted according to layout, which defines the format by showing how the reference time, defined to be Mon Jan 2 15:04:05 -0700 MST 2006 would be displayed if it were the value; it serves as an example of the desired output. The same display rules will then be applied to the time value. A fractional second is represented by adding a period and zeros to the end of the seconds section of layout string, as in "15:04:05.000" to format a time stamp with millisecond precision. Predefined layouts ANSIC, UnixDate, RFC3339 and others describe standard and convenient representations of the reference time. For more information about the formats and the definition of the reference time, see the documentation for ANSIC and the other constants defined by this package.
func ( Time) ( string) string {
	const  = 64
	var  []byte
	 := len() + 10
	if  <  {
		var  []byte
		 = [:0]
	} else {
		 = make([]byte, 0, )
	}
	 = .AppendFormat(, )
	return string()
}
AppendFormat is like Format but appends the textual representation to b and returns the extended buffer.
func ( Time) ( []byte,  string) []byte {
	var (
		, ,  = .locabs()

		  int = -1
		 Month
		   int
		  int
		  int = -1
		   int
		   int
Each iteration generates one std value.
	for  != "" {
		, ,  := nextStdChunk()
		if  != "" {
			 = append(, ...)
		}
		if  == 0 {
			break
		}
		 = 
Compute year, month, day if needed.
		if  < 0 && &stdNeedDate != 0 {
			, , ,  = absDate(, true)
			++
		}
Compute hour, minute, second if needed.
		if  < 0 && &stdNeedClock != 0 {
			, ,  = absClock()
		}

		switch  & stdMask {
		case stdYear:
			 := 
			if  < 0 {
				 = -
			}
			 = appendInt(, %100, 2)
		case stdLongYear:
			 = appendInt(, , 4)
		case stdMonth:
			 = append(, .String()[:3]...)
		case stdLongMonth:
			 := .String()
			 = append(, ...)
		case stdNumMonth:
			 = appendInt(, int(), 0)
		case stdZeroMonth:
			 = appendInt(, int(), 2)
		case stdWeekDay:
			 = append(, absWeekday().String()[:3]...)
		case stdLongWeekDay:
			 := absWeekday().String()
			 = append(, ...)
		case stdDay:
			 = appendInt(, , 0)
		case stdUnderDay:
			if  < 10 {
				 = append(, ' ')
			}
			 = appendInt(, , 0)
		case stdZeroDay:
			 = appendInt(, , 2)
		case stdUnderYearDay:
			if  < 100 {
				 = append(, ' ')
				if  < 10 {
					 = append(, ' ')
				}
			}
			 = appendInt(, , 0)
		case stdZeroYearDay:
			 = appendInt(, , 3)
		case stdHour:
			 = appendInt(, , 2)
Noon is 12PM, midnight is 12AM.
			 :=  % 12
			if  == 0 {
				 = 12
			}
			 = appendInt(, , 0)
Noon is 12PM, midnight is 12AM.
			 :=  % 12
			if  == 0 {
				 = 12
			}
			 = appendInt(, , 2)
		case stdMinute:
			 = appendInt(, , 0)
		case stdZeroMinute:
			 = appendInt(, , 2)
		case stdSecond:
			 = appendInt(, , 0)
		case stdZeroSecond:
			 = appendInt(, , 2)
		case stdPM:
			if  >= 12 {
				 = append(, "PM"...)
			} else {
				 = append(, "AM"...)
			}
		case stdpm:
			if  >= 12 {
				 = append(, "pm"...)
			} else {
				 = append(, "am"...)
			}
Ugly special case. We cheat and take the "Z" variants to mean "the time zone as formatted for ISO 8601".
			if  == 0 && ( == stdISO8601TZ ||  == stdISO8601ColonTZ ||  == stdISO8601SecondsTZ ||  == stdISO8601ShortTZ ||  == stdISO8601ColonSecondsTZ) {
				 = append(, 'Z')
				break
			}
			 :=  / 60 // convert to minutes
			 := 
			if  < 0 {
				 = append(, '-')
				 = -
				 = -
			} else {
				 = append(, '+')
			}
			 = appendInt(, /60, 2)
			if  == stdISO8601ColonTZ ||  == stdNumColonTZ ||  == stdISO8601ColonSecondsTZ ||  == stdNumColonSecondsTZ {
				 = append(, ':')
			}
			if  != stdNumShortTZ &&  != stdISO8601ShortTZ {
				 = appendInt(, %60, 2)
			}
append seconds if appropriate
			if  == stdISO8601SecondsTZ ||  == stdNumSecondsTz ||  == stdNumColonSecondsTZ ||  == stdISO8601ColonSecondsTZ {
				if  == stdNumColonSecondsTZ ||  == stdISO8601ColonSecondsTZ {
					 = append(, ':')
				}
				 = appendInt(, %60, 2)
			}

		case stdTZ:
			if  != "" {
				 = append(, ...)
				break
No time zone known for this time, but we must print one. Use the -0700 format.
			 :=  / 60 // convert to minutes
			if  < 0 {
				 = append(, '-')
				 = -
			} else {
				 = append(, '+')
			}
			 = appendInt(, /60, 2)
			 = appendInt(, %60, 2)
		case stdFracSecond0, stdFracSecond9:
			 = formatNano(, uint(.Nanosecond()), >>stdArgShift, &stdMask == stdFracSecond9)
		}
	}
	return 
}

var errBad = errors.New("bad value for field") // placeholder not passed to user
ParseError describes a problem parsing a time string.
type ParseError struct {
	Layout     string
	Value      string
	LayoutElem string
	ValueElem  string
	Message    string
}

func ( string) string {
	return "\"" +  + "\""
}
Error returns the string representation of a ParseError.
func ( *ParseError) () string {
	if .Message == "" {
		return "parsing time " +
			quote(.Value) + " as " +
			quote(.Layout) + ": cannot parse " +
			quote(.ValueElem) + " as " +
			quote(.LayoutElem)
	}
	return "parsing time " +
		quote(.Value) + .Message
}
isDigit reports whether s[i] is in range and is a decimal digit.
func ( string,  int) bool {
	if len() <=  {
		return false
	}
	 := []
	return '0' <=  &&  <= '9'
}
getnum parses s[0:1] or s[0:2] (fixed forces s[0:2]) as a decimal integer and returns the integer and the remainder of the string.
func ( string,  bool) (int, string, error) {
	if !isDigit(, 0) {
		return 0, , errBad
	}
	if !isDigit(, 1) {
		if  {
			return 0, , errBad
		}
		return int([0] - '0'), [1:], nil
	}
	return int([0]-'0')*10 + int([1]-'0'), [2:], nil
}
getnum3 parses s[0:1], s[0:2], or s[0:3] (fixed forces s[0:3]) as a decimal integer and returns the integer and the remainder of the string.
func ( string,  bool) (int, string, error) {
	var ,  int
	for  = 0;  < 3 && isDigit(, ); ++ {
		 = *10 + int([]-'0')
	}
	if  == 0 ||  &&  != 3 {
		return 0, , errBad
	}
	return , [:], nil
}

func ( string) string {
	for len() > 0 && [0] == ' ' {
		 = [1:]
	}
	return 
}
skip removes the given prefix from value, treating runs of space characters as equivalent.
func (,  string) (string, error) {
	for len() > 0 {
		if [0] == ' ' {
			if len() > 0 && [0] != ' ' {
				return , errBad
			}
			 = cutspace()
			 = cutspace()
			continue
		}
		if len() == 0 || [0] != [0] {
			return , errBad
		}
		 = [1:]
		 = [1:]
	}
	return , nil
}
Parse parses a formatted string and returns the time value it represents. The layout defines the format by showing how the reference time, defined to be Mon Jan 2 15:04:05 -0700 MST 2006 would be interpreted if it were the value; it serves as an example of the input format. The same interpretation will then be made to the input string. Predefined layouts ANSIC, UnixDate, RFC3339 and others describe standard and convenient representations of the reference time. For more information about the formats and the definition of the reference time, see the documentation for ANSIC and the other constants defined by this package. Also, the executable example for Time.Format demonstrates the working of the layout string in detail and is a good reference. Elements omitted from the value are assumed to be zero or, when zero is impossible, one, so parsing "3:04pm" returns the time corresponding to Jan 1, year 0, 15:04:00 UTC (note that because the year is 0, this time is before the zero Time). Years must be in the range 0000..9999. The day of the week is checked for syntax but it is otherwise ignored. For layouts specifying the two-digit year 06, a value NN >= 69 will be treated as 19NN and a value NN < 69 will be treated as 20NN. In the absence of a time zone indicator, Parse returns a time in UTC. When parsing a time with a zone offset like -0700, if the offset corresponds to a time zone used by the current location (Local), then Parse uses that location and zone in the returned time. Otherwise it records the time as being in a fabricated location with time fixed at the given zone offset. When parsing a time with a zone abbreviation like MST, if the zone abbreviation has a defined offset in the current location, then that offset is used. The zone abbreviation "UTC" is recognized as UTC regardless of location. If the zone abbreviation is unknown, Parse records the time as being in a fabricated location with the given zone abbreviation and a zero offset. This choice means that such a time can be parsed and reformatted with the same layout losslessly, but the exact instant used in the representation will differ by the actual zone offset. To avoid such problems, prefer time layouts that use a numeric zone offset, or use ParseInLocation.
func (,  string) (Time, error) {
	return parse(, , UTC, Local)
}
ParseInLocation is like Parse but differs in two important ways. First, in the absence of time zone information, Parse interprets a time as UTC; ParseInLocation interprets the time as in the given location. Second, when given a zone offset or abbreviation, Parse tries to match it against the Local location; ParseInLocation uses the given location.
func (,  string,  *Location) (Time, error) {
	return parse(, , , )
}

func (,  string, ,  *Location) (Time, error) {
	,  := , 
	 := "" // set if a value is out of range
	 := false       // do we need to subtract 12 from the hour for midnight?
	 := false       // do we need to add 12 to the hour?
Time being constructed.
	var (
		       int
		      int = -1
		        int = -1
		       int = -1
		       int
		        int
		        int
		       int
		          *Location
		 int = -1
		   string
	)
Each iteration processes one std value.
	for {
		var  error
		, ,  := nextStdChunk()
		 := [len() : len()-len()]
		,  = skip(, )
		if  != nil {
			return Time{}, &ParseError{, , , , ""}
		}
		if  == 0 {
			if len() != 0 {
				return Time{}, &ParseError{, , "", , ": extra text: " + quote()}
			}
			break
		}
		 = 
		var  string
		switch  & stdMask {
		case stdYear:
			if len() < 2 {
				 = errBad
				break
			}
			 := 
			,  = [0:2], [2:]
			,  = atoi()
			if  != nil {
				 = 
			} else if  >= 69 { // Unix time starts Dec 31 1969 in some time zones
				 += 1900
			} else {
				 += 2000
			}
		case stdLongYear:
			if len() < 4 || !isDigit(, 0) {
				 = errBad
				break
			}
			,  = [0:4], [4:]
			,  = atoi()
		case stdMonth:
			, ,  = lookup(shortMonthNames, )
			++
		case stdLongMonth:
			, ,  = lookup(longMonthNames, )
			++
		case stdNumMonth, stdZeroMonth:
			, ,  = getnum(,  == stdZeroMonth)
			if  == nil && ( <= 0 || 12 < ) {
				 = "month"
			}
Ignore weekday except for error checking.
			_, ,  = lookup(shortDayNames, )
		case stdLongWeekDay:
			_, ,  = lookup(longDayNames, )
		case stdDay, stdUnderDay, stdZeroDay:
			if  == stdUnderDay && len() > 0 && [0] == ' ' {
				 = [1:]
			}
Note that we allow any one- or two-digit day here. The month, day, year combination is validated after we've completed parsing.
		case stdUnderYearDay, stdZeroYearDay:
			for  := 0;  < 2; ++ {
				if  == stdUnderYearDay && len() > 0 && [0] == ' ' {
					 = [1:]
				}
			}
Note that we allow any one-, two-, or three-digit year-day here. The year-day, year combination is validated after we've completed parsing.
		case stdHour:
			, ,  = getnum(, false)
			if  < 0 || 24 <=  {
				 = "hour"
			}
		case stdHour12, stdZeroHour12:
			, ,  = getnum(,  == stdZeroHour12)
			if  < 0 || 12 <  {
				 = "hour"
			}
		case stdMinute, stdZeroMinute:
			, ,  = getnum(,  == stdZeroMinute)
			if  < 0 || 60 <=  {
				 = "minute"
			}
		case stdSecond, stdZeroSecond:
			, ,  = getnum(,  == stdZeroSecond)
			if  < 0 || 60 <=  {
				 = "second"
				break
Special case: do we have a fractional second but no fractional second in the format?
			if len() >= 2 && [0] == '.' && isDigit(, 1) {
				_, , _ = nextStdChunk()
				 &= stdMask
Fractional second in the layout; proceed normally
					break
No fractional second in the layout but we have one in the input.
				 := 2
				for ;  < len() && isDigit(, ); ++ {
				}
				, ,  = parseNanoseconds(, )
				 = [:]
			}
		case stdPM:
			if len() < 2 {
				 = errBad
				break
			}
			,  = [0:2], [2:]
			switch  {
			case "PM":
				 = true
			case "AM":
				 = true
			default:
				 = errBad
			}
		case stdpm:
			if len() < 2 {
				 = errBad
				break
			}
			,  = [0:2], [2:]
			switch  {
			case "pm":
				 = true
			case "am":
				 = true
			default:
				 = errBad
			}
		case stdISO8601TZ, stdISO8601ColonTZ, stdISO8601SecondsTZ, stdISO8601ShortTZ, stdISO8601ColonSecondsTZ, stdNumTZ, stdNumShortTZ, stdNumColonTZ, stdNumSecondsTz, stdNumColonSecondsTZ:
			if ( == stdISO8601TZ ||  == stdISO8601ShortTZ ||  == stdISO8601ColonTZ) && len() >= 1 && [0] == 'Z' {
				 = [1:]
				 = UTC
				break
			}
			var , , ,  string
			if  == stdISO8601ColonTZ ||  == stdNumColonTZ {
				if len() < 6 {
					 = errBad
					break
				}
				if [3] != ':' {
					 = errBad
					break
				}
				, , , ,  = [0:1], [1:3], [4:6], "00", [6:]
			} else if  == stdNumShortTZ ||  == stdISO8601ShortTZ {
				if len() < 3 {
					 = errBad
					break
				}
				, , , ,  = [0:1], [1:3], "00", "00", [3:]
			} else if  == stdISO8601ColonSecondsTZ ||  == stdNumColonSecondsTZ {
				if len() < 9 {
					 = errBad
					break
				}
				if [3] != ':' || [6] != ':' {
					 = errBad
					break
				}
				, , , ,  = [0:1], [1:3], [4:6], [7:9], [9:]
			} else if  == stdISO8601SecondsTZ ||  == stdNumSecondsTz {
				if len() < 7 {
					 = errBad
					break
				}
				, , , ,  = [0:1], [1:3], [3:5], [5:7], [7:]
			} else {
				if len() < 5 {
					 = errBad
					break
				}
				, , , ,  = [0:1], [1:3], [3:5], "00", [5:]
			}
			var , ,  int
			,  = atoi()
			if  == nil {
				,  = atoi()
			}
			if  == nil {
				,  = atoi()
			}
			 = (*60+)*60 +  // offset is in seconds
			switch [0] {
			case '+':
			case '-':
				 = -
			default:
				 = errBad
			}
Does it look like a time zone?
			if len() >= 3 && [0:3] == "UTC" {
				 = UTC
				 = [3:]
				break
			}
			,  := parseTimeZone()
			if ! {
				 = errBad
				break
			}
			,  = [:], [:]

stdFracSecond0 requires the exact number of digits as specified in the layout.
			 := 1 + ( >> stdArgShift)
			if len() <  {
				 = errBad
				break
			}
			, ,  = parseNanoseconds(, )
			 = [:]

		case stdFracSecond9:
Fractional second omitted.
				break
Take any number of digits, even more than asked for, because it is what the stdSecond case would do.
			 := 0
			for  < 9 && +1 < len() && '0' <= [+1] && [+1] <= '9' {
				++
			}
			, ,  = parseNanoseconds(, 1+)
			 = [1+:]
		}
		if  != "" {
			return Time{}, &ParseError{, , , , ": " +  + " out of range"}
		}
		if  != nil {
			return Time{}, &ParseError{, , , , ""}
		}
	}
	if  &&  < 12 {
		 += 12
	} else if  &&  == 12 {
		 = 0
	}
Convert yday to day, month.
	if  >= 0 {
		var  int
		var  int
		if isLeap() {
			if  == 31+29 {
				 = int(February)
				 = 29
			} else if  > 31+29 {
				--
			}
		}
		if  < 1 ||  > 365 {
			return Time{}, &ParseError{, , "", , ": day-of-year out of range"}
		}
		if  == 0 {
			 = (-1)/31 + 1
			if int(daysBefore[]) <  {
				++
			}
			 =  - int(daysBefore[-1])
If month, day already seen, yday's m, d must match. Otherwise, set them from m, d.
		if  >= 0 &&  !=  {
			return Time{}, &ParseError{, , "", , ": day-of-year does not match month"}
		}
		 = 
		if  >= 0 &&  !=  {
			return Time{}, &ParseError{, , "", , ": day-of-year does not match day"}
		}
		 = 
	} else {
		if  < 0 {
			 = int(January)
		}
		if  < 0 {
			 = 1
		}
	}
Validate the day of the month.
	if  < 1 ||  > daysIn(Month(), ) {
		return Time{}, &ParseError{, , "", , ": day out of range"}
	}

	if  != nil {
		return Date(, Month(), , , , , , ), nil
	}

	if  != -1 {
		 := Date(, Month(), , , , , , UTC)
		.addSec(-int64())
Look for local zone with the given offset. If that zone was in effect at the given time, use it.
		, , ,  := .lookup(.unixSec())
		if  ==  && ( == "" ||  == ) {
			.setLoc()
			return , nil
		}
Otherwise create fake zone to record offset.
		.setLoc(FixedZone(, ))
		return , nil
	}

	if  != "" {
Look for local zone with the given offset. If that zone was in effect at the given time, use it.
		,  := .lookupName(, .unixSec())
		if  {
			.addSec(-int64())
			.setLoc()
			return , nil
		}
Otherwise, create fake zone with unknown offset.
		if len() > 3 && [:3] == "GMT" {
			, _ = atoi([3:]) // Guaranteed OK by parseGMT.
			 *= 3600
		}
		.setLoc(FixedZone(, ))
		return , nil
	}
Otherwise, fall back to default.
	return Date(, Month(), , , , , , ), nil
}
parseTimeZone parses a time zone string and returns its length. Time zones are human-generated and unpredictable. We can't do precise error checking. On the other hand, for a correct parse there must be a time zone at the beginning of the string, so it's almost always true that there's one there. We look at the beginning of the string for a run of upper-case letters. If there are more than 5, it's an error. If there are 4 or 5 and the last is a T, it's a time zone. If there are 3, it's a time zone. Otherwise, other than special cases, it's not a time zone. GMT is special because it can have an hour offset.
func ( string) ( int,  bool) {
	if len() < 3 {
		return 0, false
Special case 1: ChST and MeST are the only zones with a lower-case letter.
	if len() >= 4 && ([:4] == "ChST" || [:4] == "MeST") {
		return 4, true
Special case 2: GMT may have an hour offset; treat it specially.
	if [:3] == "GMT" {
		 = parseGMT()
		return , true
Special Case 3: Some time zones are not named, but have +/-00 format
	if [0] == '+' || [0] == '-' {
		 = parseSignedOffset()
		 :=  > 0 // parseSignedOffset returns 0 in case of bad input
		return , 
How many upper-case letters are there? Need at least three, at most five.
	var  int
	for  = 0;  < 6; ++ {
		if  >= len() {
			break
		}
		if  := [];  < 'A' || 'Z' <  {
			break
		}
	}
	switch  {
	case 0, 1, 2, 6:
		return 0, false
	case 5: // Must end in T to match.
		if [4] == 'T' {
			return 5, true
		}
Must end in T, except one special case.
		if [3] == 'T' || [:4] == "WITA" {
			return 4, true
		}
	case 3:
		return 3, true
	}
	return 0, false
}
parseGMT parses a GMT time zone. The input string is known to start "GMT". The function checks whether that is followed by a sign and a number in the range -23 through +23 excluding zero.
func ( string) int {
	 = [3:]
	if len() == 0 {
		return 3
	}

	return 3 + parseSignedOffset()
}
parseSignedOffset parses a signed timezone offset (e.g. "+03" or "-04"). The function checks for a signed number in the range -23 through +23 excluding zero. Returns length of the found offset string or 0 otherwise
func ( string) int {
	 := [0]
	if  != '-' &&  != '+' {
		return 0
	}
	, ,  := leadingInt([1:])
fail if nothing consumed by leadingInt
	if  != nil || [1:] ==  {
		return 0
	}
	if  == '-' {
		 = -
	}
	if  < -23 || 23 <  {
		return 0
	}
	return len() - len()
}

func ( string,  int) ( int,  string,  error) {
	if [0] != '.' {
		 = errBad
		return
	}
	if ,  = atoi([1:]);  != nil {
		return
	}
	if  < 0 || 1e9 <=  {
		 = "fractional second"
		return
We need nanoseconds, which means scaling by the number of missing digits in the format, maximum length 10. If it's longer than 10, we won't scale.
	 := 10 - 
	for  := 0;  < ; ++ {
		 *= 10
	}
	return
}

var errLeadingInt = errors.New("time: bad [0-9]*") // never printed
leadingInt consumes the leading [0-9]* from s.
func ( string) ( int64,  string,  error) {
	 := 0
	for ;  < len(); ++ {
		 := []
		if  < '0' ||  > '9' {
			break
		}
overflow
			return 0, "", errLeadingInt
		}
		 = *10 + int64() - '0'
overflow
			return 0, "", errLeadingInt
		}
	}
	return , [:], nil
}
leadingFraction consumes the leading [0-9]* from s. It is used only for fractions, so does not return an error on overflow, it just stops accumulating precision.
func ( string) ( int64,  float64,  string) {
	 := 0
	 = 1
	 := false
	for ;  < len(); ++ {
		 := []
		if  < '0' ||  > '9' {
			break
		}
		if  {
			continue
		}
It's possible for overflow to give a positive number, so take care.
			 = true
			continue
		}
		 := *10 + int64() - '0'
		if  < 0 {
			 = true
			continue
		}
		 = 
		 *= 10
	}
	return , , [:]
}

var unitMap = map[string]int64{
	"ns": int64(Nanosecond),
	"us": int64(Microsecond),
	"µs": int64(Microsecond), // U+00B5 = micro symbol
	"μs": int64(Microsecond), // U+03BC = Greek letter mu
	"ms": int64(Millisecond),
	"s":  int64(Second),
	"m":  int64(Minute),
	"h":  int64(Hour),
}
ParseDuration parses a duration string. A duration string is a possibly signed sequence of decimal numbers, each with optional fraction and a unit suffix, such as "300ms", "-1.5h" or "2h45m". Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
[-+]?([0-9]*(\.[0-9]*)?[a-z]+)+
	 := 
	var  int64
	 := false
Consume [-+]?
	if  != "" {
		 := [0]
		if  == '-' ||  == '+' {
			 =  == '-'
			 = [1:]
		}
Special case: if all that is left is "0", this is zero.
	if  == "0" {
		return 0, nil
	}
	if  == "" {
		return 0, errors.New("time: invalid duration " + quote())
	}
	for  != "" {
		var (
			,   int64       // integers before, after decimal point
			 float64 = 1 // value = v + f/scale
		)

		var  error
The next character must be [0-9.]
		if !([0] == '.' || '0' <= [0] && [0] <= '9') {
			return 0, errors.New("time: invalid duration " + quote())
Consume [0-9]*
		 := len()
		, ,  = leadingInt()
		if  != nil {
			return 0, errors.New("time: invalid duration " + quote())
		}
		 :=  != len() // whether we consumed anything before a period
Consume (\.[0-9]*)?
		 := false
		if  != "" && [0] == '.' {
			 = [1:]
			 := len()
			, ,  = leadingFraction()
			 =  != len()
		}
no digits (e.g. ".s" or "-.s")
			return 0, errors.New("time: invalid duration " + quote())
		}
Consume unit.
		 := 0
		for ;  < len(); ++ {
			 := []
			if  == '.' || '0' <=  &&  <= '9' {
				break
			}
		}
		if  == 0 {
			return 0, errors.New("time: missing unit in duration " + quote())
		}
		 := [:]
		 = [:]
		,  := unitMap[]
		if ! {
			return 0, errors.New("time: unknown unit " + quote() + " in duration " + quote())
		}
overflow
			return 0, errors.New("time: invalid duration " + quote())
		}
		 *= 
float64 is needed to be nanosecond accurate for fractions of hours. v >= 0 && (f*unit/scale) <= 3.6e+12 (ns/h, h is the largest unit)
			 += int64(float64() * (float64() / ))
overflow
				return 0, errors.New("time: invalid duration " + quote())
			}
		}
		 += 
overflow
			return 0, errors.New("time: invalid duration " + quote())
		}
	}

	if  {
		 = -
	}
	return Duration(), nil