Fixes #31 : Use RFC 3339 for datetimes
diff --git a/lexer.go b/lexer.go index 41b8af7..7835116 100644 --- a/lexer.go +++ b/lexer.go
@@ -192,7 +192,10 @@ return l.lexKey } - if dateRegexp.FindString(l.input[l.pos:]) != "" { + dateMatch := dateRegexp.FindString(l.input[l.pos:]) + if dateMatch != "" { + l.ignore() + l.pos += len(dateMatch) return l.lexDate } @@ -214,8 +217,6 @@ } func (l *tomlLexer) lexDate() tomlLexStateFn { - l.ignore() - l.pos += 20 // Fixed size of a date in TOML l.emit(tokenDate) return l.lexRvalue } @@ -461,7 +462,7 @@ } func init() { - dateRegexp = regexp.MustCompile("^\\d{1,4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}Z") + dateRegexp = regexp.MustCompile("^\\d{1,4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{1,9})?(Z|[+-]\\d{2}:\\d{2})") } // Entry point
diff --git a/lexer_test.go b/lexer_test.go index 176abf8..cc8fb47 100644 --- a/lexer_test.go +++ b/lexer_test.go
@@ -273,7 +273,13 @@ func TestDateRegexp(t *testing.T) { if dateRegexp.FindString("1979-05-27T07:32:00Z") == "" { - t.Fail() + t.Error("basic lexing") + } + if dateRegexp.FindString("1979-05-27T00:32:00-07:00") == "" { + t.Error("offset lexing") + } + if dateRegexp.FindString("1979-05-27T00:32:00.999999-07:00") == "" { + t.Error("nano precision lexing") } } @@ -284,6 +290,18 @@ token{Position{1, 7}, tokenDate, "1979-05-27T07:32:00Z"}, token{Position{1, 27}, tokenEOF, ""}, }) + testFlow(t, "foo = 1979-05-27T00:32:00-07:00", []token{ + token{Position{1, 1}, tokenKey, "foo"}, + token{Position{1, 5}, tokenEqual, "="}, + token{Position{1, 7}, tokenDate, "1979-05-27T00:32:00-07:00"}, + token{Position{1, 32}, tokenEOF, ""}, + }) + testFlow(t, "foo = 1979-05-27T00:32:00.999999-07:00", []token{ + token{Position{1, 1}, tokenKey, "foo"}, + token{Position{1, 5}, tokenEqual, "="}, + token{Position{1, 7}, tokenDate, "1979-05-27T00:32:00.999999-07:00"}, + token{Position{1, 39}, tokenEOF, ""}, + }) } func TestFloatEndingWithDot(t *testing.T) {
diff --git a/parser.go b/parser.go index 60918cc..e83647d 100644 --- a/parser.go +++ b/parser.go
@@ -222,7 +222,7 @@ } return val case tokenDate: - val, err := time.Parse(time.RFC3339, tok.val) + val, err := time.Parse(time.RFC3339Nano, tok.val) if err != nil { p.raiseError(tok, "%s", err) }
diff --git a/parser_test.go b/parser_test.go index 136c795..afaabd3 100644 --- a/parser_test.go +++ b/parser_test.go
@@ -88,6 +88,21 @@ }) } +func TestDateOffset(t *testing.T) { + tree, err := Load("a = 1979-05-27T00:32:00-07:00") + assertTree(t, tree, err, map[string]interface{}{ + "a": time.Date(1979, time.May, 27, 0, 32, 0, 0, time.FixedZone("", -7 * 60 * 60)), + }) +} + +func TestDateNano(t *testing.T) { + tree, err := Load("a = 1979-05-27T00:32:00.999999999-07:00") + assertTree(t, tree, err, map[string]interface{}{ + "a": time.Date(1979, time.May, 27, 0, 32, 0, 999999999, time.FixedZone("", -7 * 60 * 60)), + }) +} + + func TestSimpleString(t *testing.T) { tree, err := Load("a = \"hello world\"") assertTree(t, tree, err, map[string]interface{}{