Skip to content

Commit 4c6a7a7

Browse files
committed
Added more cases to DATETIME handling, along with microsecond support in parsing
Signed-off-by: Daylon Wilkins <daylon@liquidata.co>
1 parent db42340 commit 4c6a7a7

File tree

1 file changed

+25
-20
lines changed

1 file changed

+25
-20
lines changed

sql/type.go

Lines changed: 25 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -542,14 +542,15 @@ func (t timestampT) Type() query.Type {
542542

543543
// TimestampLayout is the formatting string with the layout of the timestamp
544544
// using the format of Go "time" package.
545-
const TimestampLayout = "2006-01-02 15:04:05"
545+
const TimestampLayout = "2006-01-02 15:04:05.999999"
546546

547547
// TimestampLayouts hold extra timestamps allowed for parsing. It does
548548
// not have all the layouts supported by mysql. Missing are two digit year
549549
// versions of common cases and dates that use non common separators.
550550
//
551551
// https://github.com/MariaDB/server/blob/mysql-5.5.36/sql-common/my_time.c#L124
552552
var TimestampLayouts = []string{
553+
"2006-01-02 15:04:05.999999",
553554
"2006-01-02",
554555
time.RFC3339,
555556
"20060102150405",
@@ -579,22 +580,12 @@ func (t timestampT) Convert(v interface{}) (interface{}, error) {
579580
case time.Time:
580581
return value.UTC(), nil
581582
case string:
582-
t, err := time.Parse(TimestampLayout, value)
583-
if err != nil {
584-
failed := true
585-
for _, fmt := range TimestampLayouts {
586-
if t2, err2 := time.Parse(fmt, value); err2 == nil {
587-
t = t2
588-
failed = false
589-
break
590-
}
591-
}
592-
593-
if failed {
594-
return nil, ErrConvertingToTime.Wrap(err, v)
583+
for _, fmt := range TimestampLayouts {
584+
if t, err := time.Parse(fmt, value); err == nil {
585+
return t.UTC(), nil
595586
}
596587
}
597-
return t.UTC(), nil
588+
return nil, ErrConvertingToTime.New(v)
598589
default:
599590
ts, err := Int64.Convert(v)
600591
if err != nil {
@@ -700,7 +691,20 @@ func (t datetimeT) Zero() interface{} {
700691

701692
// DatetimeLayout is the layout of the MySQL date format in the representation
702693
// Go understands.
703-
const DatetimeLayout = "2006-01-02 15:04:05"
694+
const DatetimeLayout = "2006-01-02 15:04:05.999999"
695+
696+
// DatetimeLayouts hold extra configurations allowed for parsing. It does
697+
// not have all the layouts supported by mysql. Missing are two digit year
698+
// versions of common cases and dates that use non common separators.
699+
//
700+
// https://github.com/MariaDB/server/blob/mysql-5.5.36/sql-common/my_time.c#L124
701+
var DatetimeLayouts = []string{
702+
"2006-01-02 15:04:05.999999",
703+
"2006-01-02",
704+
time.RFC3339,
705+
"20060102150405",
706+
"20060102",
707+
}
704708

705709
func (t datetimeT) String() string { return "DATETIME" }
706710

@@ -729,11 +733,12 @@ func (t datetimeT) Convert(v interface{}) (interface{}, error) {
729733
case time.Time:
730734
return value.UTC(), nil
731735
case string:
732-
t, err := time.Parse(DatetimeLayout, value)
733-
if err != nil {
734-
return nil, ErrConvertingToTime.Wrap(err, v)
736+
for _, fmt := range DatetimeLayouts {
737+
if t, err := time.Parse(fmt, value); err == nil {
738+
return t.UTC(), nil
739+
}
735740
}
736-
return t.UTC(), nil
741+
return nil, ErrConvertingToTime.New(v)
737742
default:
738743
ts, err := Int64.Convert(v)
739744
if err != nil {

0 commit comments

Comments
 (0)