]> Cypherpunks repositories - gostls13.git/commitdiff
time: fix handling of -07, handle Z07
authorIan Lance Taylor <iant@golang.org>
Mon, 30 Nov 2015 17:21:34 +0000 (09:21 -0800)
committerIan Lance Taylor <iant@golang.org>
Wed, 2 Dec 2015 01:35:09 +0000 (01:35 +0000)
The existing code has partial support for -07 (just the hours of a time
zone offset).  Complete the support, add support for Z07, and add a few
tests.

Fixes #13426.

Change-Id: Ic6377bbf3e65b4bb761b9779f7e80c07ce4f57e8
Reviewed-on: https://go-review.googlesource.com/17260
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
src/time/format.go
src/time/format_test.go

index 697e1dd4ab74914401355eba17c5891104e9e140..949390196ab052109d1416119718d9242b79e007 100644 (file)
@@ -34,11 +34,13 @@ import "errors"
 // 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 executable example for time.Format demonstrates the working
 // of the layout string in detail and is a good reference.
@@ -86,6 +88,7 @@ const (
        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
@@ -220,6 +223,9 @@ func nextStdChunk(layout string) (prefix string, std int, suffix string) {
                        if len(layout) >= i+6 && layout[i:i+6] == "Z07:00" {
                                return layout[0:i], stdISO8601ColonTZ, layout[i+6:]
                        }
+                       if len(layout) >= i+3 && layout[i:i+3] == "Z07" {
+                               return layout[0:i], stdISO8601ShortTZ, layout[i+3:]
+                       }
 
                case '.': // .000 or .999 - repeated digits for fractional seconds.
                        if i+1 < len(layout) && (layout[i+1] == '0' || layout[i+1] == '9') {
@@ -537,10 +543,10 @@ func (t Time) AppendFormat(b []byte, layout string) []byte {
                        } else {
                                b = append(b, "am"...)
                        }
-               case stdISO8601TZ, stdISO8601ColonTZ, stdISO8601SecondsTZ, stdISO8601ColonSecondsTZ, stdNumTZ, stdNumColonTZ, stdNumSecondsTz, stdNumColonSecondsTZ:
+               case stdISO8601TZ, stdISO8601ColonTZ, stdISO8601SecondsTZ, stdISO8601ShortTZ, stdISO8601ColonSecondsTZ, stdNumTZ, stdNumColonTZ, stdNumSecondsTz, stdNumShortTZ, stdNumColonSecondsTZ:
                        // Ugly special case.  We cheat and take the "Z" variants
                        // to mean "the time zone as formatted for ISO 8601".
-                       if offset == 0 && (std == stdISO8601TZ || std == stdISO8601ColonTZ || std == stdISO8601SecondsTZ || std == stdISO8601ColonSecondsTZ) {
+                       if offset == 0 && (std == stdISO8601TZ || std == stdISO8601ColonTZ || std == stdISO8601SecondsTZ || std == stdISO8601ShortTZ || std == stdISO8601ColonSecondsTZ) {
                                b = append(b, 'Z')
                                break
                        }
@@ -557,7 +563,9 @@ func (t Time) AppendFormat(b []byte, layout string) []byte {
                        if std == stdISO8601ColonTZ || std == stdNumColonTZ || std == stdISO8601ColonSecondsTZ || std == stdNumColonSecondsTZ {
                                b = append(b, ':')
                        }
-                       b = appendInt(b, zone%60, 2)
+                       if std != stdNumShortTZ && std != stdISO8601ShortTZ {
+                               b = appendInt(b, zone%60, 2)
+                       }
 
                        // append seconds if appropriate
                        if std == stdISO8601SecondsTZ || std == stdNumSecondsTz || std == stdNumColonSecondsTZ || std == stdISO8601ColonSecondsTZ {
@@ -871,8 +879,8 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error)
                        default:
                                err = errBad
                        }
-               case stdISO8601TZ, stdISO8601ColonTZ, stdISO8601SecondsTZ, stdISO8601ColonSecondsTZ, stdNumTZ, stdNumShortTZ, stdNumColonTZ, stdNumSecondsTz, stdNumColonSecondsTZ:
-                       if (std == stdISO8601TZ || std == stdISO8601ColonTZ) && len(value) >= 1 && value[0] == 'Z' {
+               case stdISO8601TZ, stdISO8601ColonTZ, stdISO8601SecondsTZ, stdISO8601ShortTZ, stdISO8601ColonSecondsTZ, stdNumTZ, stdNumShortTZ, stdNumColonTZ, stdNumSecondsTz, stdNumColonSecondsTZ:
+                       if (std == stdISO8601TZ || std == stdISO8601ShortTZ || std == stdISO8601ColonTZ) && len(value) >= 1 && value[0] == 'Z' {
                                value = value[1:]
                                z = UTC
                                break
@@ -888,7 +896,7 @@ func parse(layout, value string, defaultLocation, local *Location) (Time, error)
                                        break
                                }
                                sign, hour, min, seconds, value = value[0:1], value[1:3], value[4:6], "00", value[6:]
-                       } else if std == stdNumShortTZ {
+                       } else if std == stdNumShortTZ || std == stdISO8601ShortTZ {
                                if len(value) < 3 {
                                        err = errBad
                                        break
index b1b7a005d41be8cef34321216eaba7e8e31b7c02..976c1df5f767f97b62e772298666ebba684f4d1f 100644 (file)
@@ -504,6 +504,9 @@ var secondsTimeZoneOffsetTests = []SecondsTimeZoneOffsetTest{
        {"2006-01-02T15:04:05-07:00:00", "1871-01-01T05:33:02+00:34:08", 34*60 + 8},
        {"2006-01-02T15:04:05Z070000", "1871-01-01T05:33:02-003408", -(34*60 + 8)},
        {"2006-01-02T15:04:05Z07:00:00", "1871-01-01T05:33:02+00:34:08", 34*60 + 8},
+       {"2006-01-02T15:04:05-07", "1871-01-01T05:33:02+01", 1 * 60 * 60},
+       {"2006-01-02T15:04:05-07", "1871-01-01T05:33:02-02", -2 * 60 * 60},
+       {"2006-01-02T15:04:05Z07", "1871-01-01T05:33:02-02", -2 * 60 * 60},
 }
 
 func TestParseSecondsInTimeZone(t *testing.T) {