diff --git a/time/consts.go b/time/consts.go new file mode 100644 index 0000000..68dc3ed --- /dev/null +++ b/time/consts.go @@ -0,0 +1,9 @@ +package util + +const ( + DateLayout = "2006-01-02" + ClockLayout = "15:04:05" + TimeLayout = DateLayout + " " + ClockLayout + + DefaultTimeLocationName = "Asia/Shanghai" +) diff --git a/time/diff.go b/time/diff.go new file mode 100644 index 0000000..3d2e1f0 --- /dev/null +++ b/time/diff.go @@ -0,0 +1,61 @@ +package util + +import ( + "math" + "time" +) + +// DayDifferenceHours 两天之间相差了多少小时 +func DayDifferenceHours(startDate, endDate string) float64 { + startTime, _ := time.Parse(DateLayout, startDate) + endTime, _ := time.Parse(DateLayout, endDate) + + duration := endTime.Sub(startTime) + + return duration.Hours() +} + +// StringDifferenceDays 两天之间相差了多少天 +func StringDifferenceDays(startDate, endDate string) int { + hours := DayDifferenceHours(startDate, endDate) + if hours == 0 { + return 0 + } + return int(math.Ceil(hours / 24)) +} + +func DayTimeDifferenceHours(startDate, endDate time.Time) float64 { + startTime := time.Date(startDate.Year(), startDate.Month(), startDate.Day(), 0, 0, 0, 0, time.Local) + endTime := time.Date(endDate.Year(), endDate.Month(), endDate.Day(), 0, 0, 0, 0, time.Local) + + duration := endTime.Sub(startTime) + + return duration.Hours() +} + +// TimeDifferenceDays 两天之间相差了多少天 +func TimeDifferenceDays(startDate, endDate time.Time) int { + hours := DayTimeDifferenceHours(startDate, endDate) + if hours == 0 { + return 0 + } + return int(math.Ceil(hours / 24)) +} + +func DaySecondsDifferenceHours(startSecond, endSecond int64) float64 { + startTime := time.Unix(startSecond, 0) + endTime := time.Unix(endSecond, 0) + + duration := endTime.Sub(startTime) + + return duration.Hours() +} + +// SecondsDifferenceDays 两天之间相差了多少天 +func SecondsDifferenceDays(startSecond, endSecond int64) int { + hours := DaySecondsDifferenceHours(startSecond, endSecond) + if hours == 0 { + return 0 + } + return int(math.Ceil(hours / 24)) +} diff --git a/time/diff_test.go b/time/diff_test.go new file mode 100644 index 0000000..0f69738 --- /dev/null +++ b/time/diff_test.go @@ -0,0 +1,57 @@ +package util + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" +) + +func parseDate(str string) time.Time { + t, _ := time.Parse(DateLayout, str) + return t +} + +func toSecond(str string) int64 { + t, _ := time.Parse(DateLayout, str) + return t.Unix() +} + +func TestDifferenceDays(t *testing.T) { + assert.Equal(t, StringDifferenceDays("2017-09-01", "2017-09-01"), 0) + assert.Equal(t, StringDifferenceDays("2017-09-01", "2017-09-02"), 1) + assert.Equal(t, StringDifferenceDays("2017-09-01", "2017-09-03"), 2) + assert.Equal(t, StringDifferenceDays("2017-09-01", "2017-09-04"), 3) + + assert.Equal(t, StringDifferenceDays("2017-09-01", "2018-03-11"), 191) + + assert.True(t, (StringDifferenceDays("2017-09-01", "2017-09-01")) == 0) + assert.True(t, (StringDifferenceDays("2017-09-01", "2017-09-02"))%1 == 0) + assert.True(t, (StringDifferenceDays("2017-09-01", "2017-09-03"))%2 == 0) +} + +func TestTimeDifferenceDays(t *testing.T) { + assert.Equal(t, TimeDifferenceDays(parseDate("2017-09-01"), parseDate("2017-09-01")), 0) + assert.Equal(t, TimeDifferenceDays(parseDate("2017-09-01"), parseDate("2017-09-02")), 1) + assert.Equal(t, TimeDifferenceDays(parseDate("2017-09-01"), parseDate("2017-09-03")), 2) + assert.Equal(t, TimeDifferenceDays(parseDate("2017-09-01"), parseDate("2017-09-04")), 3) + + assert.Equal(t, TimeDifferenceDays(parseDate("2017-09-01"), parseDate("2018-03-11")), 191) + + assert.True(t, (TimeDifferenceDays(parseDate("2017-09-01"), parseDate("2017-09-01"))) == 0) + assert.True(t, (TimeDifferenceDays(parseDate("2017-09-01"), parseDate("2017-09-02")))%1 == 0) + assert.True(t, (TimeDifferenceDays(parseDate("2017-09-01"), parseDate("2017-09-03")))%2 == 0) +} + +func TestSecondsDifferenceDays(t *testing.T) { + assert.Equal(t, SecondsDifferenceDays(toSecond("2017-09-01"), toSecond("2017-09-01")), 0) + assert.Equal(t, SecondsDifferenceDays(toSecond("2017-09-01"), toSecond("2017-09-02")), 1) + assert.Equal(t, SecondsDifferenceDays(toSecond("2017-09-01"), toSecond("2017-09-03")), 2) + assert.Equal(t, SecondsDifferenceDays(toSecond("2017-09-01"), toSecond("2017-09-04")), 3) + + assert.Equal(t, SecondsDifferenceDays(toSecond("2017-09-01"), toSecond("2018-03-11")), 191) + + assert.True(t, (SecondsDifferenceDays(toSecond("2017-09-01"), toSecond("2017-09-01"))) == 0) + assert.True(t, (SecondsDifferenceDays(toSecond("2017-09-01"), toSecond("2017-09-02")))%1 == 0) + assert.True(t, (SecondsDifferenceDays(toSecond("2017-09-01"), toSecond("2017-09-03")))%2 == 0) +} diff --git a/time/trans.go b/time/trans.go index ff05732..af8300e 100644 --- a/time/trans.go +++ b/time/trans.go @@ -6,10 +6,11 @@ import ( "github.com/tx7do/kratos-utils/trans" ) -const ( - TimeLayout = "2006-01-02 15:04:05" - DateLayout = "2006-01-02" -) +var DefaultTimeLocation *time.Location + +func RefreshDefaultTimeLocation(name string) { + DefaultTimeLocation, _ = time.LoadLocation(name) +} // UnixMilliToStringPtr 毫秒时间戳 -> 字符串 func UnixMilliToStringPtr(tm *int64) *string { @@ -38,12 +39,30 @@ func StringTimeToTime(str *string) *time.Time { if len(*str) == 0 { return nil } - loc, _ := time.LoadLocation("Asia/Shanghai") - theTime, err := time.ParseInLocation(TimeLayout, *str, loc) - if err != nil { - return nil + + if DefaultTimeLocation == nil { + RefreshDefaultTimeLocation(DefaultTimeLocationName) } - return &theTime + + var err error + var theTime time.Time + + theTime, err = time.ParseInLocation(TimeLayout, *str, DefaultTimeLocation) + if err == nil { + return &theTime + } + + theTime, err = time.ParseInLocation(DateLayout, *str, DefaultTimeLocation) + if err == nil { + return &theTime + } + + theTime, err = time.ParseInLocation(ClockLayout, *str, DefaultTimeLocation) + if err == nil { + return &theTime + } + + return nil } // TimeToTimeString 时间 -> 时间字符串 @@ -62,12 +81,30 @@ func StringDateToTime(str *string) *time.Time { if len(*str) == 0 { return nil } - loc, _ := time.LoadLocation("Asia/Shanghai") - theTime, err := time.ParseInLocation(DateLayout, *str, loc) - if err != nil { - return nil + + if DefaultTimeLocation == nil { + RefreshDefaultTimeLocation(DefaultTimeLocationName) } - return &theTime + + var err error + var theTime time.Time + + theTime, err = time.ParseInLocation(TimeLayout, *str, DefaultTimeLocation) + if err == nil { + return &theTime + } + + theTime, err = time.ParseInLocation(DateLayout, *str, DefaultTimeLocation) + if err == nil { + return &theTime + } + + theTime, err = time.ParseInLocation(ClockLayout, *str, DefaultTimeLocation) + if err == nil { + return &theTime + } + + return nil } // TimeToDateString 时间 -> 日期字符串