Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 45 additions & 4 deletions date.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,28 +3,69 @@ package datatypes
import (
"database/sql"
"database/sql/driver"
"fmt"
"time"

"gorm.io/gorm"
"gorm.io/gorm/schema"
)

type Date time.Time

// Scan implements sql.Scanner. Values returned from the database are always in UTC,
// as Date.Value() stores dates as timezone-free "YYYY-MM-DD" strings.
func (date *Date) Scan(value interface{}) (err error) {
nullTime := &sql.NullTime{}
err = nullTime.Scan(value)
*date = Date(nullTime.Time)
switch v := value.(type) {
case time.Time:
*date = Date(v)
case string:
t, err := time.ParseInLocation("2006-01-02", v, time.UTC)
if err != nil {
return err
}
*date = Date(t)
case []byte:
t, err := time.ParseInLocation("2006-01-02", string(v), time.UTC)
if err != nil {
return err
}
*date = Date(t)
default:
nullTime := &sql.NullTime{}
err = nullTime.Scan(value)
*date = Date(nullTime.Time)
}
return
}

// Value implements driver.Valuer. Returns the date as a "YYYY-MM-DD" string
// to prevent database drivers from applying timezone conversions that shift the date.
func (date Date) Value() (driver.Value, error) {
y, m, d := time.Time(date).Date()
return time.Date(y, m, d, 0, 0, 0, 0, time.Time(date).Location()), nil
return fmt.Sprintf("%04d-%02d-%02d", y, m, d), nil
}

// GormDataType gorm common data type
func (date Date) GormDataType() string {
return "date"
}

// GormDBDataType gorm db data type
func (Date) GormDBDataType(db *gorm.DB, field *schema.Field) string {
switch db.Dialector.Name() {
case "mysql":
return "DATE"
case "postgres":
return "DATE"
case "sqlserver":
return "DATE"
case "sqlite":
return "date"
default:
return ""
}
}

func (date Date) GobEncode() ([]byte, error) {
return time.Time(date).GobEncode()
}
Expand Down
2 changes: 1 addition & 1 deletion date_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ func TestDate(t *testing.T) {
t.Fatalf("Failed to find record with date")
}

AssertEqual(t, result.Date, beginningOfDay)
AssertEqual(t, time.Time(result.Date).Format("2006-01-02"), beginningOfDay.Format("2006-01-02"))
}

func TestGobEncoding(t *testing.T) {
Expand Down
Loading