Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / libgo / go / time / format.go
1 // Copyright 2010 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
4
5 package time
6
7 import "errors"
8
9 // These are predefined layouts for use in Time.Format.
10 // The standard time used in the layouts is:
11 //      Mon Jan 2 15:04:05 MST 2006
12 // which is Unix time 1136239445. Since MST is GMT-0700,
13 // the standard time can be thought of as
14 //      01/02 03:04:05PM '06 -0700
15 // To define your own format, write down what the standard time would look
16 // like formatted your way; see the values of constants like ANSIC,
17 // StampMicro or Kitchen for examples.
18 //
19 // Within the format string, an underscore _ represents a space that may be
20 // replaced by a digit if the following number (a day) has two digits; for
21 // compatibility with fixed-width Unix time formats.
22 //
23 // A decimal point followed by one or more zeros represents a fractional
24 // second, printed to the given number of decimal places.  A decimal point
25 // followed by one or more nines represents a fractional second, printed to
26 // the given number of decimal places, with trailing zeros removed.
27 // When parsing (only), the input may contain a fractional second
28 // field immediately after the seconds field, even if the layout does not
29 // signify its presence. In that case a decimal point followed by a maximal
30 // series of digits is parsed as a fractional second.
31 //
32 // Numeric time zone offsets format as follows:
33 //      -0700  ±hhmm
34 //      -07:00 ±hh:mm
35 // Replacing the sign in the format with a Z triggers
36 // the ISO 8601 behavior of printing Z instead of an
37 // offset for the UTC zone.  Thus:
38 //      Z0700  Z or ±hhmm
39 //      Z07:00 Z or ±hh:mm
40 const (
41         ANSIC       = "Mon Jan _2 15:04:05 2006"
42         UnixDate    = "Mon Jan _2 15:04:05 MST 2006"
43         RubyDate    = "Mon Jan 02 15:04:05 -0700 2006"
44         RFC822      = "02 Jan 06 15:04 MST"
45         RFC822Z     = "02 Jan 06 15:04 -0700" // RFC822 with numeric zone
46         RFC850      = "Monday, 02-Jan-06 15:04:05 MST"
47         RFC1123     = "Mon, 02 Jan 2006 15:04:05 MST"
48         RFC1123Z    = "Mon, 02 Jan 2006 15:04:05 -0700" // RFC1123 with numeric zone
49         RFC3339     = "2006-01-02T15:04:05Z07:00"
50         RFC3339Nano = "2006-01-02T15:04:05.999999999Z07:00"
51         Kitchen     = "3:04PM"
52         // Handy time stamps.
53         Stamp      = "Jan _2 15:04:05"
54         StampMilli = "Jan _2 15:04:05.000"
55         StampMicro = "Jan _2 15:04:05.000000"
56         StampNano  = "Jan _2 15:04:05.000000000"
57 )
58
59 const (
60         _                 = iota
61         stdLongMonth      = iota + stdNeedDate  // "January"
62         stdMonth                                // "Jan"
63         stdNumMonth                             // "1"
64         stdZeroMonth                            // "01"
65         stdLongWeekDay                          // "Monday"
66         stdWeekDay                              // "Mon"
67         stdDay                                  // "2"
68         stdUnderDay                             // "_2"
69         stdZeroDay                              // "02"
70         stdHour           = iota + stdNeedClock // "15"
71         stdHour12                               // "3"
72         stdZeroHour12                           // "03"
73         stdMinute                               // "4"
74         stdZeroMinute                           // "04"
75         stdSecond                               // "5"
76         stdZeroSecond                           // "05"
77         stdLongYear       = iota + stdNeedDate  // "2006"
78         stdYear                                 // "06"
79         stdPM             = iota + stdNeedClock // "PM"
80         stdpm                                   // "pm"
81         stdTZ             = iota                // "MST"
82         stdISO8601TZ                            // "Z0700"  // prints Z for UTC
83         stdISO8601ColonTZ                       // "Z07:00" // prints Z for UTC
84         stdNumTZ                                // "-0700"  // always numeric
85         stdNumShortTZ                           // "-07"    // always numeric
86         stdNumColonTZ                           // "-07:00" // always numeric
87         stdFracSecond0                          // ".0", ".00", ... , trailing zeros included
88         stdFracSecond9                          // ".9", ".99", ..., trailing zeros omitted
89
90         stdNeedDate  = 1 << 8             // need month, day, year
91         stdNeedClock = 2 << 8             // need hour, minute, second
92         stdArgShift  = 16                 // extra argument in high bits, above low stdArgShift
93         stdMask      = 1<<stdArgShift - 1 // mask out argument
94 )
95
96 // std0x records the std values for "01", "02", ..., "06".
97 var std0x = [...]int{stdZeroMonth, stdZeroDay, stdZeroHour12, stdZeroMinute, stdZeroSecond, stdYear}
98
99 // nextStdChunk finds the first occurrence of a std string in
100 // layout and returns the text before, the std string, and the text after.
101 func nextStdChunk(layout string) (prefix string, std int, suffix string) {
102         for i := 0; i < len(layout); i++ {
103                 switch c := int(layout[i]); c {
104                 case 'J': // January, Jan
105                         if len(layout) >= i+3 && layout[i:i+3] == "Jan" {
106                                 if len(layout) >= i+7 && layout[i:i+7] == "January" {
107                                         return layout[0:i], stdLongMonth, layout[i+7:]
108                                 }
109                                 return layout[0:i], stdMonth, layout[i+3:]
110                         }
111
112                 case 'M': // Monday, Mon, MST
113                         if len(layout) >= i+3 {
114                                 if layout[i:i+3] == "Mon" {
115                                         if len(layout) >= i+6 && layout[i:i+6] == "Monday" {
116                                                 return layout[0:i], stdLongWeekDay, layout[i+6:]
117                                         }
118                                         return layout[0:i], stdWeekDay, layout[i+3:]
119                                 }
120                                 if layout[i:i+3] == "MST" {
121                                         return layout[0:i], stdTZ, layout[i+3:]
122                                 }
123                         }
124
125                 case '0': // 01, 02, 03, 04, 05, 06
126                         if len(layout) >= i+2 && '1' <= layout[i+1] && layout[i+1] <= '6' {
127                                 return layout[0:i], std0x[layout[i+1]-'1'], layout[i+2:]
128                         }
129
130                 case '1': // 15, 1
131                         if len(layout) >= i+2 && layout[i+1] == '5' {
132                                 return layout[0:i], stdHour, layout[i+2:]
133                         }
134                         return layout[0:i], stdNumMonth, layout[i+1:]
135
136                 case '2': // 2006, 2
137                         if len(layout) >= i+4 && layout[i:i+4] == "2006" {
138                                 return layout[0:i], stdLongYear, layout[i+4:]
139                         }
140                         return layout[0:i], stdDay, layout[i+1:]
141
142                 case '_': // _2
143                         if len(layout) >= i+2 && layout[i+1] == '2' {
144                                 return layout[0:i], stdUnderDay, layout[i+2:]
145                         }
146
147                 case '3':
148                         return layout[0:i], stdHour12, layout[i+1:]
149
150                 case '4':
151                         return layout[0:i], stdMinute, layout[i+1:]
152
153                 case '5':
154                         return layout[0:i], stdSecond, layout[i+1:]
155
156                 case 'P': // PM
157                         if len(layout) >= i+2 && layout[i+1] == 'M' {
158                                 return layout[0:i], stdPM, layout[i+2:]
159                         }
160
161                 case 'p': // pm
162                         if len(layout) >= i+2 && layout[i+1] == 'm' {
163                                 return layout[0:i], stdpm, layout[i+2:]
164                         }
165
166                 case '-': // -0700, -07:00, -07
167                         if len(layout) >= i+5 && layout[i:i+5] == "-0700" {
168                                 return layout[0:i], stdNumTZ, layout[i+5:]
169                         }
170                         if len(layout) >= i+6 && layout[i:i+6] == "-07:00" {
171                                 return layout[0:i], stdNumColonTZ, layout[i+6:]
172                         }
173                         if len(layout) >= i+3 && layout[i:i+3] == "-07" {
174                                 return layout[0:i], stdNumShortTZ, layout[i+3:]
175                         }
176                 case 'Z': // Z0700, Z07:00
177                         if len(layout) >= i+5 && layout[i:i+5] == "Z0700" {
178                                 return layout[0:i], stdISO8601TZ, layout[i+5:]
179                         }
180                         if len(layout) >= i+6 && layout[i:i+6] == "Z07:00" {
181                                 return layout[0:i], stdISO8601ColonTZ, layout[i+6:]
182                         }
183                 case '.': // .000 or .999 - repeated digits for fractional seconds.
184                         if i+1 < len(layout) && (layout[i+1] == '0' || layout[i+1] == '9') {
185                                 ch := layout[i+1]
186                                 j := i + 1
187                                 for j < len(layout) && layout[j] == ch {
188                                         j++
189                                 }
190                                 // String of digits must end here - only fractional second is all digits.
191                                 if !isDigit(layout, j) {
192                                         std := stdFracSecond0
193                                         if layout[i+1] == '9' {
194                                                 std = stdFracSecond9
195                                         }
196                                         std |= (j - (i + 1)) << stdArgShift
197                                         return layout[0:i], std, layout[j:]
198                                 }
199                         }
200                 }
201         }
202         return layout, 0, ""
203 }
204
205 var longDayNames = []string{
206         "Sunday",
207         "Monday",
208         "Tuesday",
209         "Wednesday",
210         "Thursday",
211         "Friday",
212         "Saturday",
213 }
214
215 var shortDayNames = []string{
216         "Sun",
217         "Mon",
218         "Tue",
219         "Wed",
220         "Thu",
221         "Fri",
222         "Sat",
223 }
224
225 var shortMonthNames = []string{
226         "---",
227         "Jan",
228         "Feb",
229         "Mar",
230         "Apr",
231         "May",
232         "Jun",
233         "Jul",
234         "Aug",
235         "Sep",
236         "Oct",
237         "Nov",
238         "Dec",
239 }
240
241 var longMonthNames = []string{
242         "---",
243         "January",
244         "February",
245         "March",
246         "April",
247         "May",
248         "June",
249         "July",
250         "August",
251         "September",
252         "October",
253         "November",
254         "December",
255 }
256
257 // match returns true if s1 and s2 match ignoring case.
258 // It is assumed s1 and s2 are the same length.
259 func match(s1, s2 string) bool {
260         for i := 0; i < len(s1); i++ {
261                 c1 := s1[i]
262                 c2 := s2[i]
263                 if c1 != c2 {
264                         // Switch to lower-case; 'a'-'A' is known to be a single bit.
265                         c1 |= 'a' - 'A'
266                         c2 |= 'a' - 'A'
267                         if c1 != c2 || c1 < 'a' || c1 > 'z' {
268                                 return false
269                         }
270                 }
271         }
272         return true
273 }
274
275 func lookup(tab []string, val string) (int, string, error) {
276         for i, v := range tab {
277                 if len(val) >= len(v) && match(val[0:len(v)], v) {
278                         return i, val[len(v):], nil
279                 }
280         }
281         return -1, val, errBad
282 }
283
284 // appendUint appends the decimal form of x to b and returns the result.
285 // If x is a single-digit number and pad != 0, appendUint inserts the pad byte
286 // before the digit.
287 // Duplicates functionality in strconv, but avoids dependency.
288 func appendUint(b []byte, x uint, pad byte) []byte {
289         if x < 10 {
290                 if pad != 0 {
291                         b = append(b, pad)
292                 }
293                 return append(b, byte('0'+x))
294         }
295         if x < 100 {
296                 b = append(b, byte('0'+x/10))
297                 b = append(b, byte('0'+x%10))
298                 return b
299         }
300
301         var buf [32]byte
302         n := len(buf)
303         if x == 0 {
304                 return append(b, '0')
305         }
306         for x >= 10 {
307                 n--
308                 buf[n] = byte(x%10 + '0')
309                 x /= 10
310         }
311         n--
312         buf[n] = byte(x + '0')
313         return append(b, buf[n:]...)
314 }
315
316 // Never printed, just needs to be non-nil for return by atoi.
317 var atoiError = errors.New("time: invalid number")
318
319 // Duplicates functionality in strconv, but avoids dependency.
320 func atoi(s string) (x int, err error) {
321         neg := false
322         if s != "" && s[0] == '-' {
323                 neg = true
324                 s = s[1:]
325         }
326         q, rem, err := leadingInt(s)
327         x = int(q)
328         if err != nil || rem != "" {
329                 return 0, atoiError
330         }
331         if neg {
332                 x = -x
333         }
334         return x, nil
335 }
336
337 // formatNano appends a fractional second, as nanoseconds, to b
338 // and returns the result.
339 func formatNano(b []byte, nanosec uint, n int, trim bool) []byte {
340         u := nanosec
341         var buf [9]byte
342         for start := len(buf); start > 0; {
343                 start--
344                 buf[start] = byte(u%10 + '0')
345                 u /= 10
346         }
347
348         if n > 9 {
349                 n = 9
350         }
351         if trim {
352                 for n > 0 && buf[n-1] == '0' {
353                         n--
354                 }
355                 if n == 0 {
356                         return b
357                 }
358         }
359         b = append(b, '.')
360         return append(b, buf[:n]...)
361 }
362
363 // String returns the time formatted using the format string
364 //      "2006-01-02 15:04:05.999999999 -0700 MST"
365 func (t Time) String() string {
366         return t.Format("2006-01-02 15:04:05.999999999 -0700 MST")
367 }
368
369 // Format returns a textual representation of the time value formatted
370 // according to layout.  The layout defines the format by showing the
371 // representation of the standard time,
372 //      Mon Jan 2 15:04:05 -0700 MST 2006
373 // which is then used to describe the time to be formatted. Predefined
374 // layouts ANSIC, UnixDate, RFC3339 and others describe standard
375 // representations. For more information about the formats and the
376 // definition of the standard time, see the documentation for ANSIC.
377 func (t Time) Format(layout string) string {
378         var (
379                 name, offset, abs = t.locabs()
380
381                 year  int = -1
382                 month Month
383                 day   int
384                 hour  int = -1
385                 min   int
386                 sec   int
387
388                 b   []byte
389                 buf [64]byte
390         )
391         max := len(layout) + 10
392         if max <= len(buf) {
393                 b = buf[:0]
394         } else {
395                 b = make([]byte, 0, max)
396         }
397         // Each iteration generates one std value.
398         for layout != "" {
399                 prefix, std, suffix := nextStdChunk(layout)
400                 if prefix != "" {
401                         b = append(b, prefix...)
402                 }
403                 if std == 0 {
404                         break
405                 }
406                 layout = suffix
407
408                 // Compute year, month, day if needed.
409                 if year < 0 && std&stdNeedDate != 0 {
410                         year, month, day, _ = absDate(abs, true)
411                 }
412
413                 // Compute hour, minute, second if needed.
414                 if hour < 0 && std&stdNeedClock != 0 {
415                         hour, min, sec = absClock(abs)
416                 }
417
418                 switch std & stdMask {
419                 case stdYear:
420                         y := year
421                         if y < 0 {
422                                 y = -y
423                         }
424                         b = appendUint(b, uint(y%100), '0')
425                 case stdLongYear:
426                         // Pad year to at least 4 digits.
427                         y := year
428                         switch {
429                         case year <= -1000:
430                                 b = append(b, '-')
431                                 y = -y
432                         case year <= -100:
433                                 b = append(b, "-0"...)
434                                 y = -y
435                         case year <= -10:
436                                 b = append(b, "-00"...)
437                                 y = -y
438                         case year < 0:
439                                 b = append(b, "-000"...)
440                                 y = -y
441                         case year < 10:
442                                 b = append(b, "000"...)
443                         case year < 100:
444                                 b = append(b, "00"...)
445                         case year < 1000:
446                                 b = append(b, '0')
447                         }
448                         b = appendUint(b, uint(y), 0)
449                 case stdMonth:
450                         b = append(b, month.String()[:3]...)
451                 case stdLongMonth:
452                         m := month.String()
453                         b = append(b, m...)
454                 case stdNumMonth:
455                         b = appendUint(b, uint(month), 0)
456                 case stdZeroMonth:
457                         b = appendUint(b, uint(month), '0')
458                 case stdWeekDay:
459                         b = append(b, absWeekday(abs).String()[:3]...)
460                 case stdLongWeekDay:
461                         s := absWeekday(abs).String()
462                         b = append(b, s...)
463                 case stdDay:
464                         b = appendUint(b, uint(day), 0)
465                 case stdUnderDay:
466                         b = appendUint(b, uint(day), ' ')
467                 case stdZeroDay:
468                         b = appendUint(b, uint(day), '0')
469                 case stdHour:
470                         b = appendUint(b, uint(hour), '0')
471                 case stdHour12:
472                         // Noon is 12PM, midnight is 12AM.
473                         hr := hour % 12
474                         if hr == 0 {
475                                 hr = 12
476                         }
477                         b = appendUint(b, uint(hr), 0)
478                 case stdZeroHour12:
479                         // Noon is 12PM, midnight is 12AM.
480                         hr := hour % 12
481                         if hr == 0 {
482                                 hr = 12
483                         }
484                         b = appendUint(b, uint(hr), '0')
485                 case stdMinute:
486                         b = appendUint(b, uint(min), 0)
487                 case stdZeroMinute:
488                         b = appendUint(b, uint(min), '0')
489                 case stdSecond:
490                         b = appendUint(b, uint(sec), 0)
491                 case stdZeroSecond:
492                         b = appendUint(b, uint(sec), '0')
493                 case stdPM:
494                         if hour >= 12 {
495                                 b = append(b, "PM"...)
496                         } else {
497                                 b = append(b, "AM"...)
498                         }
499                 case stdpm:
500                         if hour >= 12 {
501                                 b = append(b, "pm"...)
502                         } else {
503                                 b = append(b, "am"...)
504                         }
505                 case stdISO8601TZ, stdISO8601ColonTZ, stdNumTZ, stdNumColonTZ:
506                         // Ugly special case.  We cheat and take the "Z" variants
507                         // to mean "the time zone as formatted for ISO 8601".
508                         if offset == 0 && (std == stdISO8601TZ || std == stdISO8601ColonTZ) {
509                                 b = append(b, 'Z')
510                                 break
511                         }
512                         zone := offset / 60 // convert to minutes
513                         if zone < 0 {
514                                 b = append(b, '-')
515                                 zone = -zone
516                         } else {
517                                 b = append(b, '+')
518                         }
519                         b = appendUint(b, uint(zone/60), '0')
520                         if std == stdISO8601ColonTZ || std == stdNumColonTZ {
521                                 b = append(b, ':')
522                         }
523                         b = appendUint(b, uint(zone%60), '0')
524                 case stdTZ:
525                         if name != "" {
526                                 b = append(b, name...)
527                                 break
528                         }
529                         // No time zone known for this time, but we must print one.
530                         // Use the -0700 format.
531                         zone := offset / 60 // convert to minutes
532                         if zone < 0 {
533                                 b = append(b, '-')
534                                 zone = -zone
535                         } else {
536                                 b = append(b, '+')
537                         }
538                         b = appendUint(b, uint(zone/60), '0')
539                         b = appendUint(b, uint(zone%60), '0')
540                 case stdFracSecond0, stdFracSecond9:
541                         b = formatNano(b, uint(t.Nanosecond()), std>>stdArgShift, std&stdMask == stdFracSecond9)
542                 }
543         }
544         return string(b)
545 }
546
547 var errBad = errors.New("bad value for field") // placeholder not passed to user
548
549 // ParseError describes a problem parsing a time string.
550 type ParseError struct {
551         Layout     string
552         Value      string
553         LayoutElem string
554         ValueElem  string
555         Message    string
556 }
557
558 func quote(s string) string {
559         return "\"" + s + "\""
560 }
561
562 // Error returns the string representation of a ParseError.
563 func (e *ParseError) Error() string {
564         if e.Message == "" {
565                 return "parsing time " +
566                         quote(e.Value) + " as " +
567                         quote(e.Layout) + ": cannot parse " +
568                         quote(e.ValueElem) + " as " +
569                         quote(e.LayoutElem)
570         }
571         return "parsing time " +
572                 quote(e.Value) + e.Message
573 }
574
575 // isDigit returns true if s[i] is a decimal digit, false if not or
576 // if s[i] is out of range.
577 func isDigit(s string, i int) bool {
578         if len(s) <= i {
579                 return false
580         }
581         c := s[i]
582         return '0' <= c && c <= '9'
583 }
584
585 // getnum parses s[0:1] or s[0:2] (fixed forces the latter)
586 // as a decimal integer and returns the integer and the
587 // remainder of the string.
588 func getnum(s string, fixed bool) (int, string, error) {
589         if !isDigit(s, 0) {
590                 return 0, s, errBad
591         }
592         if !isDigit(s, 1) {
593                 if fixed {
594                         return 0, s, errBad
595                 }
596                 return int(s[0] - '0'), s[1:], nil
597         }
598         return int(s[0]-'0')*10 + int(s[1]-'0'), s[2:], nil
599 }
600
601 func cutspace(s string) string {
602         for len(s) > 0 && s[0] == ' ' {
603                 s = s[1:]
604         }
605         return s
606 }
607
608 // skip removes the given prefix from value,
609 // treating runs of space characters as equivalent.
610 func skip(value, prefix string) (string, error) {
611         for len(prefix) > 0 {
612                 if prefix[0] == ' ' {
613                         if len(value) > 0 && value[0] != ' ' {
614                                 return "", errBad
615                         }
616                         prefix = cutspace(prefix)
617                         value = cutspace(value)
618                         continue
619                 }
620                 if len(value) == 0 || value[0] != prefix[0] {
621                         return "", errBad
622                 }
623                 prefix = prefix[1:]
624                 value = value[1:]
625         }
626         return value, nil
627 }
628
629 // Parse parses a formatted string and returns the time value it represents.
630 // The layout defines the format by showing the representation of the
631 // standard time,
632 //      Mon Jan 2 15:04:05 -0700 MST 2006
633 // which is then used to describe the string to be parsed. Predefined layouts
634 // ANSIC, UnixDate, RFC3339 and others describe standard representations. For
635 // more information about the formats and the definition of the standard
636 // time, see the documentation for ANSIC.
637 //
638 // Elements omitted from the value are assumed to be zero or, when
639 // zero is impossible, one, so parsing "3:04pm" returns the time
640 // corresponding to Jan 1, year 0, 15:04:00 UTC (note that because the year is
641 // 0, this time is before the zero Time).
642 // Years must be in the range 0000..9999. The day of the week is checked
643 // for syntax but it is otherwise ignored.
644 func Parse(layout, value string) (Time, error) {
645         alayout, avalue := layout, value
646         rangeErrString := "" // set if a value is out of range
647         amSet := false       // do we need to subtract 12 from the hour for midnight?
648         pmSet := false       // do we need to add 12 to the hour?
649
650         // Time being constructed.
651         var (
652                 year       int
653                 month      int = 1 // January
654                 day        int = 1
655                 hour       int
656                 min        int
657                 sec        int
658                 nsec       int
659                 z          *Location
660                 zoneOffset int = -1
661                 zoneName   string
662         )
663
664         // Each iteration processes one std value.
665         for {
666                 var err error
667                 prefix, std, suffix := nextStdChunk(layout)
668                 stdstr := layout[len(prefix) : len(layout)-len(suffix)]
669                 value, err = skip(value, prefix)
670                 if err != nil {
671                         return Time{}, &ParseError{alayout, avalue, prefix, value, ""}
672                 }
673                 if std == 0 {
674                         if len(value) != 0 {
675                                 return Time{}, &ParseError{alayout, avalue, "", value, ": extra text: " + value}
676                         }
677                         break
678                 }
679                 layout = suffix
680                 var p string
681                 switch std & stdMask {
682                 case stdYear:
683                         if len(value) < 2 {
684                                 err = errBad
685                                 break
686                         }
687                         p, value = value[0:2], value[2:]
688                         year, err = atoi(p)
689                         if year >= 69 { // Unix time starts Dec 31 1969 in some time zones
690                                 year += 1900
691                         } else {
692                                 year += 2000
693                         }
694                 case stdLongYear:
695                         if len(value) < 4 || !isDigit(value, 0) {
696                                 err = errBad
697                                 break
698                         }
699                         p, value = value[0:4], value[4:]
700                         year, err = atoi(p)
701                 case stdMonth:
702                         month, value, err = lookup(shortMonthNames, value)
703                 case stdLongMonth:
704                         month, value, err = lookup(longMonthNames, value)
705                 case stdNumMonth, stdZeroMonth:
706                         month, value, err = getnum(value, std == stdZeroMonth)
707                         if month <= 0 || 12 < month {
708                                 rangeErrString = "month"
709                         }
710                 case stdWeekDay:
711                         // Ignore weekday except for error checking.
712                         _, value, err = lookup(shortDayNames, value)
713                 case stdLongWeekDay:
714                         _, value, err = lookup(longDayNames, value)
715                 case stdDay, stdUnderDay, stdZeroDay:
716                         if std == stdUnderDay && len(value) > 0 && value[0] == ' ' {
717                                 value = value[1:]
718                         }
719                         day, value, err = getnum(value, std == stdZeroDay)
720                         if day < 0 || 31 < day {
721                                 rangeErrString = "day"
722                         }
723                 case stdHour:
724                         hour, value, err = getnum(value, false)
725                         if hour < 0 || 24 <= hour {
726                                 rangeErrString = "hour"
727                         }
728                 case stdHour12, stdZeroHour12:
729                         hour, value, err = getnum(value, std == stdZeroHour12)
730                         if hour < 0 || 12 < hour {
731                                 rangeErrString = "hour"
732                         }
733                 case stdMinute, stdZeroMinute:
734                         min, value, err = getnum(value, std == stdZeroMinute)
735                         if min < 0 || 60 <= min {
736                                 rangeErrString = "minute"
737                         }
738                 case stdSecond, stdZeroSecond:
739                         sec, value, err = getnum(value, std == stdZeroSecond)
740                         if sec < 0 || 60 <= sec {
741                                 rangeErrString = "second"
742                         }
743                         // Special case: do we have a fractional second but no
744                         // fractional second in the format?
745                         if len(value) >= 2 && value[0] == '.' && isDigit(value, 1) {
746                                 _, std, _ := nextStdChunk(layout)
747                                 std &= stdMask
748                                 if std == stdFracSecond0 || std == stdFracSecond9 {
749                                         // Fractional second in the layout; proceed normally
750                                         break
751                                 }
752                                 // No fractional second in the layout but we have one in the input.
753                                 n := 2
754                                 for ; n < len(value) && isDigit(value, n); n++ {
755                                 }
756                                 nsec, rangeErrString, err = parseNanoseconds(value, n)
757                                 value = value[n:]
758                         }
759                 case stdPM:
760                         if len(value) < 2 {
761                                 err = errBad
762                                 break
763                         }
764                         p, value = value[0:2], value[2:]
765                         switch p {
766                         case "PM":
767                                 pmSet = true
768                         case "AM":
769                                 amSet = true
770                         default:
771                                 err = errBad
772                         }
773                 case stdpm:
774                         if len(value) < 2 {
775                                 err = errBad
776                                 break
777                         }
778                         p, value = value[0:2], value[2:]
779                         switch p {
780                         case "pm":
781                                 pmSet = true
782                         case "am":
783                                 amSet = true
784                         default:
785                                 err = errBad
786                         }
787                 case stdISO8601TZ, stdISO8601ColonTZ, stdNumTZ, stdNumShortTZ, stdNumColonTZ:
788                         if (std == stdISO8601TZ || std == stdISO8601ColonTZ) && len(value) >= 1 && value[0] == 'Z' {
789                                 value = value[1:]
790                                 z = UTC
791                                 break
792                         }
793                         var sign, hour, min string
794                         if std == stdISO8601ColonTZ || std == stdNumColonTZ {
795                                 if len(value) < 6 {
796                                         err = errBad
797                                         break
798                                 }
799                                 if value[3] != ':' {
800                                         err = errBad
801                                         break
802                                 }
803                                 sign, hour, min, value = value[0:1], value[1:3], value[4:6], value[6:]
804                         } else if std == stdNumShortTZ {
805                                 if len(value) < 3 {
806                                         err = errBad
807                                         break
808                                 }
809                                 sign, hour, min, value = value[0:1], value[1:3], "00", value[3:]
810                         } else {
811                                 if len(value) < 5 {
812                                         err = errBad
813                                         break
814                                 }
815                                 sign, hour, min, value = value[0:1], value[1:3], value[3:5], value[5:]
816                         }
817                         var hr, mm int
818                         hr, err = atoi(hour)
819                         if err == nil {
820                                 mm, err = atoi(min)
821                         }
822                         zoneOffset = (hr*60 + mm) * 60 // offset is in seconds
823                         switch sign[0] {
824                         case '+':
825                         case '-':
826                                 zoneOffset = -zoneOffset
827                         default:
828                                 err = errBad
829                         }
830                 case stdTZ:
831                         // Does it look like a time zone?
832                         if len(value) >= 3 && value[0:3] == "UTC" {
833                                 z = UTC
834                                 value = value[3:]
835                                 break
836                         }
837
838                         if len(value) >= 3 && value[2] == 'T' {
839                                 p, value = value[0:3], value[3:]
840                         } else if len(value) >= 4 && value[3] == 'T' {
841                                 p, value = value[0:4], value[4:]
842                         } else {
843                                 err = errBad
844                                 break
845                         }
846                         for i := 0; i < len(p); i++ {
847                                 if p[i] < 'A' || 'Z' < p[i] {
848                                         err = errBad
849                                 }
850                         }
851                         if err != nil {
852                                 break
853                         }
854                         // It's a valid format.
855                         zoneName = p
856
857                 case stdFracSecond0:
858                         // stdFracSecond0 requires the exact number of digits as specified in
859                         // the layout.
860                         ndigit := 1 + (std >> stdArgShift)
861                         if len(value) < ndigit {
862                                 err = errBad
863                                 break
864                         }
865                         nsec, rangeErrString, err = parseNanoseconds(value, ndigit)
866                         value = value[ndigit:]
867
868                 case stdFracSecond9:
869                         if len(value) < 2 || value[0] != '.' || value[1] < '0' || '9' < value[1] {
870                                 // Fractional second omitted.
871                                 break
872                         }
873                         // Take any number of digits, even more than asked for,
874                         // because it is what the stdSecond case would do.
875                         i := 0
876                         for i < 9 && i+1 < len(value) && '0' <= value[i+1] && value[i+1] <= '9' {
877                                 i++
878                         }
879                         nsec, rangeErrString, err = parseNanoseconds(value, 1+i)
880                         value = value[1+i:]
881                 }
882                 if rangeErrString != "" {
883                         return Time{}, &ParseError{alayout, avalue, stdstr, value, ": " + rangeErrString + " out of range"}
884                 }
885                 if err != nil {
886                         return Time{}, &ParseError{alayout, avalue, stdstr, value, ""}
887                 }
888         }
889         if pmSet && hour < 12 {
890                 hour += 12
891         } else if amSet && hour == 12 {
892                 hour = 0
893         }
894
895         // TODO: be more aggressive checking day?
896         if z != nil {
897                 return Date(year, Month(month), day, hour, min, sec, nsec, z), nil
898         }
899
900         t := Date(year, Month(month), day, hour, min, sec, nsec, UTC)
901         if zoneOffset != -1 {
902                 t.sec -= int64(zoneOffset)
903
904                 // Look for local zone with the given offset.
905                 // If that zone was in effect at the given time, use it.
906                 name, offset, _, _, _ := Local.lookup(t.sec + internalToUnix)
907                 if offset == zoneOffset && (zoneName == "" || name == zoneName) {
908                         t.loc = Local
909                         return t, nil
910                 }
911
912                 // Otherwise create fake zone to record offset.
913                 t.loc = FixedZone(zoneName, zoneOffset)
914                 return t, nil
915         }
916
917         if zoneName != "" {
918                 // Look for local zone with the given offset.
919                 // If that zone was in effect at the given time, use it.
920                 offset, _, ok := Local.lookupName(zoneName)
921                 if ok {
922                         name, off, _, _, _ := Local.lookup(t.sec + internalToUnix - int64(offset))
923                         if name == zoneName && off == offset {
924                                 t.sec -= int64(offset)
925                                 t.loc = Local
926                                 return t, nil
927                         }
928                 }
929
930                 // Otherwise, create fake zone with unknown offset.
931                 t.loc = FixedZone(zoneName, 0)
932                 return t, nil
933         }
934
935         // Otherwise, fall back to UTC.
936         return t, nil
937 }
938
939 func parseNanoseconds(value string, nbytes int) (ns int, rangeErrString string, err error) {
940         if value[0] != '.' {
941                 err = errBad
942                 return
943         }
944         if ns, err = atoi(value[1:nbytes]); err != nil {
945                 return
946         }
947         if ns < 0 || 1e9 <= ns {
948                 rangeErrString = "fractional second"
949                 return
950         }
951         // We need nanoseconds, which means scaling by the number
952         // of missing digits in the format, maximum length 10. If it's
953         // longer than 10, we won't scale.
954         scaleDigits := 10 - nbytes
955         for i := 0; i < scaleDigits; i++ {
956                 ns *= 10
957         }
958         return
959 }
960
961 var errLeadingInt = errors.New("time: bad [0-9]*") // never printed
962
963 // leadingInt consumes the leading [0-9]* from s.
964 func leadingInt(s string) (x int64, rem string, err error) {
965         i := 0
966         for ; i < len(s); i++ {
967                 c := s[i]
968                 if c < '0' || c > '9' {
969                         break
970                 }
971                 if x >= (1<<63-10)/10 {
972                         // overflow
973                         return 0, "", errLeadingInt
974                 }
975                 x = x*10 + int64(c) - '0'
976         }
977         return x, s[i:], nil
978 }
979
980 var unitMap = map[string]float64{
981         "ns": float64(Nanosecond),
982         "us": float64(Microsecond),
983         "µs": float64(Microsecond), // U+00B5 = micro symbol
984         "μs": float64(Microsecond), // U+03BC = Greek letter mu
985         "ms": float64(Millisecond),
986         "s":  float64(Second),
987         "m":  float64(Minute),
988         "h":  float64(Hour),
989 }
990
991 // ParseDuration parses a duration string.
992 // A duration string is a possibly signed sequence of
993 // decimal numbers, each with optional fraction and a unit suffix,
994 // such as "300ms", "-1.5h" or "2h45m".
995 // Valid time units are "ns", "us" (or "µs"), "ms", "s", "m", "h".
996 func ParseDuration(s string) (Duration, error) {
997         // [-+]?([0-9]*(\.[0-9]*)?[a-z]+)+
998         orig := s
999         f := float64(0)
1000         neg := false
1001
1002         // Consume [-+]?
1003         if s != "" {
1004                 c := s[0]
1005                 if c == '-' || c == '+' {
1006                         neg = c == '-'
1007                         s = s[1:]
1008                 }
1009         }
1010         // Special case: if all that is left is "0", this is zero.
1011         if s == "0" {
1012                 return 0, nil
1013         }
1014         if s == "" {
1015                 return 0, errors.New("time: invalid duration " + orig)
1016         }
1017         for s != "" {
1018                 g := float64(0) // this element of the sequence
1019
1020                 var x int64
1021                 var err error
1022
1023                 // The next character must be [0-9.]
1024                 if !(s[0] == '.' || ('0' <= s[0] && s[0] <= '9')) {
1025                         return 0, errors.New("time: invalid duration " + orig)
1026                 }
1027                 // Consume [0-9]*
1028                 pl := len(s)
1029                 x, s, err = leadingInt(s)
1030                 if err != nil {
1031                         return 0, errors.New("time: invalid duration " + orig)
1032                 }
1033                 g = float64(x)
1034                 pre := pl != len(s) // whether we consumed anything before a period
1035
1036                 // Consume (\.[0-9]*)?
1037                 post := false
1038                 if s != "" && s[0] == '.' {
1039                         s = s[1:]
1040                         pl := len(s)
1041                         x, s, err = leadingInt(s)
1042                         if err != nil {
1043                                 return 0, errors.New("time: invalid duration " + orig)
1044                         }
1045                         scale := 1
1046                         for n := pl - len(s); n > 0; n-- {
1047                                 scale *= 10
1048                         }
1049                         g += float64(x) / float64(scale)
1050                         post = pl != len(s)
1051                 }
1052                 if !pre && !post {
1053                         // no digits (e.g. ".s" or "-.s")
1054                         return 0, errors.New("time: invalid duration " + orig)
1055                 }
1056
1057                 // Consume unit.
1058                 i := 0
1059                 for ; i < len(s); i++ {
1060                         c := s[i]
1061                         if c == '.' || ('0' <= c && c <= '9') {
1062                                 break
1063                         }
1064                 }
1065                 if i == 0 {
1066                         return 0, errors.New("time: missing unit in duration " + orig)
1067                 }
1068                 u := s[:i]
1069                 s = s[i:]
1070                 unit, ok := unitMap[u]
1071                 if !ok {
1072                         return 0, errors.New("time: unknown unit " + u + " in duration " + orig)
1073                 }
1074
1075                 f += g * unit
1076         }
1077
1078         if neg {
1079                 f = -f
1080         }
1081         return Duration(f), nil
1082 }