diff --git a/carbon.go b/carbon.go index 3785de2..6dc5718 100644 --- a/carbon.go +++ b/carbon.go @@ -14,7 +14,7 @@ import ( // Version current version // 当前版本号 -const Version = "2.4.0" +const Version = "2.4.1" // timezone constants // 时区常量 diff --git a/database.go b/database.go index 05802ac..a3c5cc9 100644 --- a/database.go +++ b/database.go @@ -33,3 +33,99 @@ func (c Carbon) Value() (driver.Value, error) { func (c Carbon) GormDataType() string { return "time" } + +// GormDataType implements the interface GormDataTypeInterface for DateTime struct. +// 实现 GormDataTypeInterface 接口 +func (t DateTime) GormDataType() string { + return "time" +} + +// GormDataType implements the interface GormDataTypeInterface for DateTimeMilli struct. +// 实现 GormDataTypeInterface 接口 +func (t DateTimeMilli) GormDataType() string { + return "time" +} + +// GormDataType implements the interface GormDataTypeInterface for DateTimeMicro struct. +// 实现 GormDataTypeInterface 接口 +func (t DateTimeMicro) GormDataType() string { + return "time" +} + +// GormDataType implements the interface GormDataTypeInterface for DateTimeNano struct. +// 实现 GormDataTypeInterface 接口 +func (t DateTimeNano) GormDataType() string { + return "time" +} + +// GormDataType implements the interface GormDataTypeInterface for Date struct. +// 实现 GormDataTypeInterface 接口 +func (t Date) GormDataType() string { + return "time" +} + +// GormDataType implements the interface GormDataTypeInterface for DateMilli struct. +// 实现 GormDataTypeInterface 接口 +func (t DateMilli) GormDataType() string { + return "time" +} + +// GormDataType implements the interface GormDataTypeInterface for DateMicro struct. +// 实现 GormDataTypeInterface 接口 +func (t DateMicro) GormDataType() string { + return "time" +} + +// GormDataType implements the interface GormDataTypeInterface for DateNano struct. +// 实现 GormDataTypeInterface 接口 +func (t DateNano) GormDataType() string { + return "time" +} + +// GormDataType implements the interface GormDataTypeInterface for Time struct. +// 实现 GormDataTypeInterface 接口 +func (t Time) GormDataType() string { + return "time" +} + +// GormDataType implements the interface GormDataTypeInterface for TimeMilli struct. +// 实现 GormDataTypeInterface 接口 +func (t TimeMilli) GormDataType() string { + return "time" +} + +// GormDataType implements the interface GormDataTypeInterface for TimeMicro struct. +// 实现 GormDataTypeInterface 接口 +func (t TimeMicro) GormDataType() string { + return "time" +} + +// GormDataType implements the interface GormDataTypeInterface for TimeNano struct. +// 实现 GormDataTypeInterface 接口 +func (t TimeNano) GormDataType() string { + return "time" +} + +// GormDataType implements the interface GormDataTypeInterface for Timestamp struct. +// 实现 GormDataTypeInterface 接口 +func (t Timestamp) GormDataType() string { + return "int" +} + +// GormDataType implements the interface GormDataTypeInterface for TimestampMilli struct. +// 实现 GormDataTypeInterface 接口 +func (t TimestampMilli) GormDataType() string { + return "int" +} + +// GormDataType implements the interface GormDataTypeInterface for TimestampMicro struct. +// 实现 GormDataTypeInterface 接口 +func (t TimestampMicro) GormDataType() string { + return "int" +} + +// GormDataType implements the interface GormDataTypeInterface for TimestampNano struct. +// 实现 GormDataTypeInterface 接口 +func (t TimestampNano) GormDataType() string { + return "int" +} diff --git a/encoding.go b/encoding.go index 04a4ebd..c16a77f 100644 --- a/encoding.go +++ b/encoding.go @@ -105,17 +105,17 @@ type TimestampNano struct { // MarshalJSON implements the interface json.Marshal for Carbon struct. // 实现 json.Marshaler 接口 func (c Carbon) MarshalJSON() ([]byte, error) { - data := fmt.Sprintf(`"%s"`, c.Layout(c.layout, c.Location())) - return []byte(data), nil + return []byte(fmt.Sprintf(`"%s"`, c.Layout(c.layout, c.Location()))), nil } // UnmarshalJSON implements the interface json.Unmarshal for Carbon struct. // 实现 json.Unmarshaler 接口 func (c *Carbon) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - *c = ParseByLayout(fmt.Sprintf("%s", bytes.Trim(b, `"`)), c.layout, c.Location()) + *c = ParseByLayout(value, c.layout, c.Location()) return c.Error } @@ -128,10 +128,11 @@ func (t DateTime) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for DateTime struct. // 实现 UnmarshalJSON 接口 func (t *DateTime) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - c := ParseByLayout(string(bytes.Trim(b, `"`)), DateTimeLayout, t.Location()) + c := ParseByLayout(value, DateTimeLayout, t.Location()) if c.Error == nil { *t = DateTime{Carbon: c} } @@ -147,10 +148,11 @@ func (t DateTimeMilli) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for DateTimeMilli struct. // 实现 UnmarshalJSON 接口 func (t *DateTimeMilli) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - c := ParseByLayout(string(bytes.Trim(b, `"`)), DateTimeMilliLayout, t.Location()) + c := ParseByLayout(value, DateTimeMilliLayout, t.Location()) if c.Error == nil { *t = DateTimeMilli{Carbon: c} } @@ -166,10 +168,11 @@ func (t DateTimeMicro) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for DateTimeMicro struct. // 实现 UnmarshalJSON 接口 func (t *DateTimeMicro) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - c := ParseByLayout(string(bytes.Trim(b, `"`)), DateTimeMicroLayout, t.Location()) + c := ParseByLayout(value, DateTimeMicroLayout, t.Location()) if c.Error == nil { *t = DateTimeMicro{Carbon: c} } @@ -185,10 +188,11 @@ func (t DateTimeNano) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for DateTimeNano struct. // 实现 UnmarshalJSON 接口 func (t *DateTimeNano) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - c := ParseByLayout(string(bytes.Trim(b, `"`)), DateTimeNanoLayout, t.Location()) + c := ParseByLayout(value, DateTimeNanoLayout, t.Location()) if c.Error == nil { *t = DateTimeNano{Carbon: c} } @@ -204,10 +208,11 @@ func (t Date) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for Date struct. // 实现 UnmarshalJSON 接口 func (t *Date) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - c := ParseByLayout(string(bytes.Trim(b, `"`)), DateLayout, t.Location()) + c := ParseByLayout(value, DateLayout, t.Location()) if c.Error == nil { *t = Date{Carbon: c} } @@ -223,10 +228,11 @@ func (t DateMilli) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for DateMilli struct. // 实现 UnmarshalJSON 接口 func (t *DateMilli) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - c := ParseByLayout(string(bytes.Trim(b, `"`)), DateMilliLayout, t.Location()) + c := ParseByLayout(value, DateMilliLayout, t.Location()) if c.Error == nil { *t = DateMilli{Carbon: c} } @@ -242,10 +248,11 @@ func (t DateMicro) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for DateMicro struct. // 实现 UnmarshalJSON 接口 func (t *DateMicro) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - c := ParseByLayout(string(bytes.Trim(b, `"`)), DateMicroLayout, t.Location()) + c := ParseByLayout(value, DateMicroLayout, t.Location()) if c.Error == nil { *t = DateMicro{Carbon: c} } @@ -261,10 +268,11 @@ func (t DateNano) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for DateNano struct. // 实现 UnmarshalJSON 接口 func (t *DateNano) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - c := ParseByLayout(string(bytes.Trim(b, `"`)), DateNanoLayout, t.Location()) + c := ParseByLayout(value, DateNanoLayout, t.Location()) if c.Error == nil { *t = DateNano{Carbon: c} } @@ -280,10 +288,11 @@ func (t Time) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for Time struct. // 实现 UnmarshalJSON 接口 func (t *Time) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - c := ParseByLayout(string(bytes.Trim(b, `"`)), TimeLayout, t.Location()) + c := ParseByLayout(value, TimeLayout, t.Location()) if c.Error == nil { *t = Time{Carbon: c} } @@ -299,10 +308,11 @@ func (t TimeMilli) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for TimeMilli struct. // 实现 UnmarshalJSON 接口 func (t *TimeMilli) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - c := ParseByLayout(string(bytes.Trim(b, `"`)), TimeMilliLayout, t.Location()) + c := ParseByLayout(value, TimeMilliLayout, t.Location()) if c.Error == nil { *t = TimeMilli{Carbon: c} } @@ -318,10 +328,11 @@ func (t TimeMicro) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for TimeMicro struct. // 实现 UnmarshalJSON 接口 func (t *TimeMicro) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - c := ParseByLayout(string(bytes.Trim(b, `"`)), TimeMicroLayout, t.Location()) + c := ParseByLayout(value, TimeMicroLayout, t.Location()) if c.Error == nil { *t = TimeMicro{Carbon: c} } @@ -337,10 +348,11 @@ func (t TimeNano) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for TimeNano struct. // 实现 UnmarshalJSON 接口 func (t *TimeNano) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - c := ParseByLayout(string(bytes.Trim(b, `"`)), TimeNanoLayout, t.Location()) + c := ParseByLayout(value, TimeNanoLayout, t.Location()) if c.Error == nil { *t = TimeNano{Carbon: c} } @@ -356,10 +368,11 @@ func (t Timestamp) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for Timestamp struct. // 实现 UnmarshalJSON 接口 func (t *Timestamp) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - ts, _ := strconv.ParseInt(string(b), 10, 64) + ts, _ := strconv.ParseInt(value, 10, 64) c := CreateFromTimestamp(ts) if c.Error == nil { *t = Timestamp{Carbon: c} @@ -376,10 +389,11 @@ func (t TimestampMilli) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for TimestampMilli struct. // 实现 UnmarshalJSON 接口 func (t *TimestampMilli) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - ts, _ := strconv.ParseInt(string(b), 10, 64) + ts, _ := strconv.ParseInt(value, 10, 64) c := CreateFromTimestampMilli(ts) if c.Error == nil { *t = TimestampMilli{Carbon: c} @@ -396,10 +410,11 @@ func (t TimestampMicro) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for TimestampMicro struct. // 实现 UnmarshalJSON 接口 func (t *TimestampMicro) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - ts, _ := strconv.ParseInt(string(b), 10, 64) + ts, _ := strconv.ParseInt(value, 10, 64) c := CreateFromTimestampMicro(ts) if c.Error == nil { *t = TimestampMicro{Carbon: c} @@ -416,10 +431,11 @@ func (t TimestampNano) MarshalJSON() ([]byte, error) { // UnmarshalJSON implements the interface json.Unmarshal for TimestampNano struct. // 实现 UnmarshalJSON 接口 func (t *TimestampNano) UnmarshalJSON(b []byte) error { - if string(b) == "" || string(b) == "null" { + value := fmt.Sprintf("%s", bytes.Trim(b, `"`)) + if value == "" || value == "null" { return nil } - ts, _ := strconv.ParseInt(string(b), 10, 64) + ts, _ := strconv.ParseInt(value, 10, 64) c := CreateFromTimestampNano(ts) if c.Error == nil { *t = TimestampNano{Carbon: c} @@ -547,102 +563,6 @@ func (t TimestampNano) String() string { return strconv.FormatInt(t.TimestampNano(), 10) } -// GormDataType implements the interface GormDataTypeInterface for DateTime struct. -// 实现 GormDataTypeInterface 接口 -func (t DateTime) GormDataType() string { - return "time" -} - -// GormDataType implements the interface GormDataTypeInterface for DateTimeMilli struct. -// 实现 GormDataTypeInterface 接口 -func (t DateTimeMilli) GormDataType() string { - return "time" -} - -// GormDataType implements the interface GormDataTypeInterface for DateTimeMicro struct. -// 实现 GormDataTypeInterface 接口 -func (t DateTimeMicro) GormDataType() string { - return "time" -} - -// GormDataType implements the interface GormDataTypeInterface for DateTimeNano struct. -// 实现 GormDataTypeInterface 接口 -func (t DateTimeNano) GormDataType() string { - return "time" -} - -// GormDataType implements the interface GormDataTypeInterface for Date struct. -// 实现 GormDataTypeInterface 接口 -func (t Date) GormDataType() string { - return "time" -} - -// GormDataType implements the interface GormDataTypeInterface for DateMilli struct. -// 实现 GormDataTypeInterface 接口 -func (t DateMilli) GormDataType() string { - return "time" -} - -// GormDataType implements the interface GormDataTypeInterface for DateMicro struct. -// 实现 GormDataTypeInterface 接口 -func (t DateMicro) GormDataType() string { - return "time" -} - -// GormDataType implements the interface GormDataTypeInterface for DateNano struct. -// 实现 GormDataTypeInterface 接口 -func (t DateNano) GormDataType() string { - return "time" -} - -// GormDataType implements the interface GormDataTypeInterface for Time struct. -// 实现 GormDataTypeInterface 接口 -func (t Time) GormDataType() string { - return "time" -} - -// GormDataType implements the interface GormDataTypeInterface for TimeMilli struct. -// 实现 GormDataTypeInterface 接口 -func (t TimeMilli) GormDataType() string { - return "time" -} - -// GormDataType implements the interface GormDataTypeInterface for TimeMicro struct. -// 实现 GormDataTypeInterface 接口 -func (t TimeMicro) GormDataType() string { - return "time" -} - -// GormDataType implements the interface GormDataTypeInterface for TimeNano struct. -// 实现 GormDataTypeInterface 接口 -func (t TimeNano) GormDataType() string { - return "time" -} - -// GormDataType implements the interface GormDataTypeInterface for Timestamp struct. -// 实现 GormDataTypeInterface 接口 -func (t Timestamp) GormDataType() string { - return "int" -} - -// GormDataType implements the interface GormDataTypeInterface for TimestampMilli struct. -// 实现 GormDataTypeInterface 接口 -func (t TimestampMilli) GormDataType() string { - return "int" -} - -// GormDataType implements the interface GormDataTypeInterface for TimestampMicro struct. -// 实现 GormDataTypeInterface 接口 -func (t TimestampMicro) GormDataType() string { - return "int" -} - -// GormDataType implements the interface GormDataTypeInterface for TimestampNano struct. -// 实现 GormDataTypeInterface 接口 -func (t TimestampNano) GormDataType() string { - return "int" -} - // ToDateTimeStruct converts Carbon to DateTime. // 将 Carbon 结构体转换成 DateTime 结构体 func (c Carbon) ToDateTimeStruct() DateTime { diff --git a/encoding_unit_test.go b/encoding_unit_test.go index 5f952b3..98805b0 100644 --- a/encoding_unit_test.go +++ b/encoding_unit_test.go @@ -345,8 +345,6 @@ func TestCarbon_TimestampToInt64(t *testing.T) { // https://github.com/golang-module/carbon/issues/225 func TestCarbon_Issue225(t *testing.T) { - var person Person - emptyStr := `{ "birthday1":"", "birthday2":"", @@ -366,9 +364,6 @@ func TestCarbon_Issue225(t *testing.T) { "birthday16":"", "birthday17":"" }` - emptyErr := json.Unmarshal([]byte(emptyStr), &person) - assert.Nil(t, emptyErr) - nullStr := `{ "birthday1":null, "birthday2":null, @@ -388,6 +383,29 @@ func TestCarbon_Issue225(t *testing.T) { "birthday16":null, "birthday17":null }` + + var person Person + emptyErr := json.Unmarshal([]byte(emptyStr), &person) + assert.Nil(t, emptyErr) + nullErr := json.Unmarshal([]byte(nullStr), &person) assert.Nil(t, nullErr) } + +// https://github.com/golang-module/carbon/issues/240 +func TestCarbon_Issue240(t *testing.T) { + jsonStr := `{ + "birthday1":"", + "birthday2":null + }` + + var person Person + emptyErr := json.Unmarshal([]byte(jsonStr), &person) + assert.Nil(t, emptyErr) + assert.Equal(t, "0001-01-01 00:00:00 +0000 UTC", person.Birthday1.StdTime().String()) + assert.Equal(t, "0001-01-01 00:00:00 +0000 UTC", person.Birthday2.StdTime().String()) + assert.Equal(t, true, person.Birthday1.IsZero()) + assert.Equal(t, true, person.Birthday2.IsZero()) + assert.Equal(t, false, person.Birthday1.IsValid()) + assert.Equal(t, false, person.Birthday2.IsValid()) +} diff --git a/getter.go b/getter.go index 5fbe468..112848c 100755 --- a/getter.go +++ b/getter.go @@ -7,6 +7,9 @@ import ( // StdTime gets standard time.Time. // 获取标准 time.Time func (c Carbon) StdTime() time.Time { + if c.time.IsZero() { + return c.time + } return c.time.In(c.loc) } @@ -28,7 +31,7 @@ func (c Carbon) DaysInMonth() int { if c.Error != nil { return 0 } - return c.EndOfMonth().time.In(c.loc).Day() + return c.EndOfMonth().StdTime().Day() } // MonthOfYear gets month of year like 12. diff --git a/lang/hu.json b/lang/hu.json new file mode 100644 index 0000000..edcf23f --- /dev/null +++ b/lang/hu.json @@ -0,0 +1,21 @@ +{ + "name": "Hungarian", + "months": "január|február|március|április|május|június|július|augusztus|szeptember|október|november|december", + "short_months": "jan.|febr.|márc.|ápr.|máj.|jún.|júl.|aug.|szept.|okt.|nov.|dec.", + "weeks": "Vasárnap|Hétfő|Kedd|Szerda|Csütörtök|Péntek|Szombat", + "short_weeks": "Vas|Hét|Ke|Sze|Csü|Pé|Szo", + "seasons": "Tavasz|Nyár|Ősz|Tél", + "constellations": "Kos|Bika|Ikrek|Rák|Oroszlán|Szűz|Mérleg|Skorpió|Nyilas|Bak|Vízöntő|Halak", + "year": "1 év|%d év", + "month": "1 hónap|%d hónap", + "week": "1 hét|%d hét", + "day": "1 nap|%d nap", + "hour": "1 óra|%d óra", + "minute": "1 perc|%d perc", + "second": "1 másodperc|%d másodperc", + "now": "most", + "ago": "%s", + "from_now": "%s múlva", + "before": "%s korábban", + "after": "%s később" +}