فهرست منبع

Drop unnecessary explicit timestamp tags.

Fixes #341.
Gustavo Niemeyer 8 سال پیش
والد
کامیت
86f5ed62f8
5فایلهای تغییر یافته به همراه27 افزوده شده و 11 حذف شده
  1. 1 0
      decode.go
  2. 12 0
      decode_test.go
  3. 2 4
      encode.go
  4. 8 3
      encode_test.go
  5. 4 4
      resolve.go

+ 1 - 0
decode.go

@@ -434,6 +434,7 @@ func (d *decoder) scalar(n *node, out reflect.Value) bool {
 			// reasons we set it as a string, so that code that unmarshals
 			// timestamp-like values into interface{} will continue to
 			// see a string and not a time.Time.
+			// TODO(v3) Drop this.
 			out.Set(reflect.ValueOf(n.value))
 		} else {
 			out.Set(reflect.ValueOf(resolved))

+ 12 - 0
decode_test.go

@@ -740,6 +740,18 @@ func (s *S) TestUnmarshal(c *C) {
 	}
 }
 
+// TODO(v3): This test should also work when unmarshaling onto an interface{}.
+func (s *S) TestUnmarshalFullTimestamp(c *C) {
+	// Full timestamp in same format as encoded. This is confirmed to be
+	// properly decoded by Python as a timestamp as well.
+	var str = "2015-02-24T18:19:39.123456789-03:00"
+	var t time.Time
+	err := yaml.Unmarshal([]byte(str), &t)
+	c.Assert(err, IsNil)
+	c.Assert(t, Equals, time.Date(2015, 2, 24, 18, 19, 39, 123456789, t.Location()))
+	c.Assert(t.In(time.UTC), Equals, time.Date(2015, 2, 24, 21, 19, 39, 123456789, time.UTC))
+}
+
 func (s *S) TestDecoderSingleDocument(c *C) {
 	// Test that Decoder.Decode works as expected on
 	// all the unmarshal tests.

+ 2 - 4
encode.go

@@ -328,10 +328,8 @@ func (e *encoder) uintv(tag string, in reflect.Value) {
 
 func (e *encoder) timev(tag string, in reflect.Value) {
 	t := in.Interface().(time.Time)
-	if tag == "" {
-		tag = yaml_TIMESTAMP_TAG
-	}
-	e.emitScalar(t.Format(time.RFC3339Nano), "", tag, yaml_PLAIN_SCALAR_STYLE)
+	s := t.Format(time.RFC3339Nano)
+	e.emitScalar(s, "", tag, yaml_PLAIN_SCALAR_STYLE)
 }
 
 func (e *encoder) floatv(tag string, in reflect.Value) {

+ 8 - 3
encode_test.go

@@ -215,7 +215,7 @@ var marshalTests = []struct {
 			T2: time.Date(2018, 1, 9, 10, 40, 47, 0, time.UTC),
 			T4: newTime(time.Date(2098, 1, 9, 10, 40, 47, 0, time.UTC)),
 		},
-		"t2: !!timestamp 2018-01-09T10:40:47Z\nt4: !!timestamp 2098-01-09T10:40:47Z\n",
+		"t2: 2018-01-09T10:40:47Z\nt4: 2098-01-09T10:40:47Z\n",
 	},
 	// Nil interface that implements Marshaler.
 	{
@@ -332,11 +332,16 @@ var marshalTests = []struct {
 	// time.Time gets a timestamp tag.
 	{
 		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC)},
-		"a: !!timestamp 2015-02-24T18:19:39Z\n",
+		"a: 2015-02-24T18:19:39Z\n",
 	},
 	{
 		map[string]*time.Time{"a": newTime(time.Date(2015, 2, 24, 18, 19, 39, 0, time.UTC))},
-		"a: !!timestamp 2015-02-24T18:19:39Z\n",
+		"a: 2015-02-24T18:19:39Z\n",
+	},
+	{
+		// This is confirmed to be properly decoded in Python (libyaml) without a timestamp tag.
+		map[string]time.Time{"a": time.Date(2015, 2, 24, 18, 19, 39, 123456789, time.FixedZone("FOO", -3*60*60))},
+		"a: 2015-02-24T18:19:39.123456789-03:00\n",
 	},
 	// Ensure timestamp-like strings are quoted.
 	{

+ 4 - 4
resolve.go

@@ -224,10 +224,10 @@ func encodeBase64(s string) string {
 // This is a subset of the formats allowed by the regular expression
 // defined at http://yaml.org/type/timestamp.html.
 var allowedTimestampFormats = []string{
-	"2006-1-2T15:4:5Z07:00",
-	"2006-1-2t15:4:5Z07:00", // RFC3339 with lower-case "t".
-	"2006-1-2 15:4:5",       // space separated with no time zone
-	"2006-1-2",              // date only
+	"2006-1-2T15:4:5.999999999Z07:00", // RCF3339Nano with short date fields.
+	"2006-1-2t15:4:5.999999999Z07:00", // RFC3339Nano with short date fields and lower-case "t".
+	"2006-1-2 15:4:5.999999999",       // space separated with no time zone
+	"2006-1-2",                        // date only
 	// Notable exception: time.Parse cannot handle: "2001-12-14 21:59:43.10 -5"
 	// from the set of examples.
 }