-
Notifications
You must be signed in to change notification settings - Fork 4
/
date_diff.go
93 lines (81 loc) · 1.71 KB
/
date_diff.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package jutil
import (
"fmt"
"time"
)
type DateDiff struct {
Year int
Month int
Day int
Hour int
Min int
Sec int
a time.Time
b time.Time
}
func (d DateDiff) String() string {
return fmt.Sprintf("%d years, %d months, %d days, %d hours, %d mins, %d secs",
d.Year, d.Month, d.Day, d.Hour, d.Min, d.Sec)
}
func (d DateDiff) Months() float32 {
return float32(d.Year*12+d.Month) + float32(d.DaysRounded())/float32(d.DaysInLastMonth())
}
func (d DateDiff) DaysRounded() int {
if d.Hour > 0 || d.Min > 0 || d.Sec > 0 {
return d.Day + 1
}
return d.Day
}
// https://github.com/jinzhu/now/blob/928c32c8eb60e699b591de5911a1c8f50d11d15a/now.go#L44
func (d DateDiff) DaysInLastMonth() int {
return GetDaysInMonth(d.b.AddDate(0, -1, 0))
}
func GetDaysInMonth(t time.Time) int {
lastDayOfMonth := time.
Date(t.Year(), t.Month(), 1, 0, 0, 0, 0, t.Location()).
AddDate(0, 1, 0).
Add(-time.Nanosecond)
return lastDayOfMonth.Day()
}
// https://stackoverflow.com/a/36531443/744298
func GetDateDiff(a, b time.Time) (diff DateDiff) {
if a.Location() != b.Location() {
b = b.In(a.Location())
}
if a.After(b) {
a, b = b, a
}
diff.a = a
diff.b = b
y1, M1, d1 := a.Date()
y2, M2, d2 := b.Date()
h1, m1, s1 := a.Clock()
h2, m2, s2 := b.Clock()
diff.Year = int(y2 - y1)
diff.Month = int(M2 - M1)
diff.Day = int(d2 - d1)
diff.Hour = int(h2 - h1)
diff.Min = int(m2 - m1)
diff.Sec = int(s2 - s1)
if diff.Sec < 0 {
diff.Sec += 60
diff.Min--
}
if diff.Min < 0 {
diff.Min += 60
diff.Hour--
}
if diff.Hour < 0 {
diff.Hour += 24
diff.Day--
}
if diff.Day < 0 {
diff.Day += GetDaysInMonth(b.AddDate(0, -1, 0))
diff.Month--
}
if diff.Month < 0 {
diff.Month += 12
diff.Year--
}
return
}