forked from gookit/goutil
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtimex.go
373 lines (311 loc) · 8.73 KB
/
timex.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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
// Package timex provides an enhanced time.Time implementation.
// Add more commonly used functional methods.
//
// such as: DayStart(), DayAfter(), DayAgo(), DateFormat() and more.
package timex
import (
"time"
"github.com/gookit/goutil/mathutil"
"github.com/gookit/goutil/strutil"
)
// provide some commonly time constants
const (
OneSecond = 1
OneMinSec = 60
OneHourSec = 3600
OneDaySec = 86400
OneWeekSec = 7 * 86400
OneMonthSec = 30 * 86400
MinSec = OneMinSec
HourSec = OneHourSec
DaySec = OneDaySec
WeekSec = OneWeekSec
MonthSec = OneMonthSec
Microsecond = time.Microsecond
Millisecond = time.Millisecond
Second = time.Second
OneMin = time.Minute
Minute = time.Minute
OneHour = time.Hour
Hour = time.Hour
OneDay = 24 * time.Hour
Day = OneDay
OneWeek = 7 * 24 * time.Hour
Week = OneWeek
Month = 30 * 24 * time.Hour
)
// TimeX alias of Time
// Deprecated: use Time instead
type TimeX = Time
// Time an enhanced time.Time implementation.
type Time struct {
time.Time
// Layout set the default date format layout. default use DefaultLayout
Layout string
}
/*************************************************************
* Create timex instance
*************************************************************/
// Now time instance
func Now() *Time {
return &Time{Time: time.Now(), Layout: DefaultLayout}
}
// New instance form given time
func New(t time.Time) *Time {
return &Time{Time: t, Layout: DefaultLayout}
}
// Wrap the go time instance. alias of the New()
func Wrap(t time.Time) *Time {
return &Time{Time: t, Layout: DefaultLayout}
}
// FromTime new instance form given time.Time. alias of the New()
func FromTime(t time.Time) *Time {
return &Time{Time: t, Layout: DefaultLayout}
}
// Local time for now
func Local() *Time {
return New(time.Now().In(time.Local))
}
// FromUnix create from unix time
func FromUnix(sec int64) *Time {
return New(time.Unix(sec, 0))
}
// FromDate create from datetime string.
func FromDate(s string, template ...string) (*Time, error) {
if len(template) > 0 && template[0] != "" {
return FromString(s, ToLayout(template[0]))
}
return FromString(s)
}
// FromString create from datetime string. see strutil.ToTime()
func FromString(s string, layouts ...string) (*Time, error) {
t, err := strutil.ToTime(s, layouts...)
if err != nil {
return nil, err
}
return New(t), nil
}
// LocalByName time for now
func LocalByName(tzName string) *Time {
loc, err := time.LoadLocation(tzName)
if err != nil {
panic(err)
}
return New(time.Now().In(loc))
}
/*************************************************************
* timex usage
*************************************************************/
// T returns the t.Time
func (t Time) T() time.Time {
return t.Time
}
// Format returns a textual representation of the time value formatted according to the layout defined by the argument.
//
// see time.Time.Format()
func (t *Time) Format(layout string) string {
if layout == "" {
layout = t.Layout
}
return t.Time.Format(layout)
}
// Datetime use DefaultLayout format time to date. see Format()
func (t *Time) Datetime() string {
return t.Format(t.Layout)
}
// TplFormat use input template format time to date.
//
// alias of DateFormat()
func (t *Time) TplFormat(template string) string {
return t.DateFormat(template)
}
// DateFormat use input template format time to date.
//
// Example:
//
// tn := timex.Now()
// tn.DateFormat("Y-m-d H:i:s") // Output: 2019-01-01 12:12:12
// tn.DateFormat("Y-m-d H:i") // Output: 2019-01-01 12:12
// tn.DateFormat("Y-m-d") // Output: 2019-01-01
// tn.DateFormat("Y-m") // Output: 2019-01
// tn.DateFormat("y-m-d") // Output: 19-01-01
// tn.DateFormat("ymd") // Output: 190101
//
// see ToLayout() for convert template to layout.
func (t *Time) DateFormat(template string) string {
return t.Format(ToLayout(template))
}
// Yesterday get day ago time for the time
func (t *Time) Yesterday() *Time {
return t.AddSeconds(-OneDaySec)
}
// DayAgo get some day ago time for the time
func (t *Time) DayAgo(day int) *Time {
return t.AddSeconds(-day * OneDaySec)
}
// AddDay add some day time for the time
func (t *Time) AddDay(day int) *Time {
return t.AddSeconds(day * OneDaySec)
}
// SubDay add some day time for the time
func (t *Time) SubDay(day int) *Time {
return t.AddSeconds(-day * OneDaySec)
}
// Tomorrow time. get tomorrow time for the time
func (t *Time) Tomorrow() *Time {
return t.AddSeconds(OneDaySec)
}
// DayAfter get some day after time for the time.
// alias of Time.AddDay()
func (t *Time) DayAfter(day int) *Time {
return t.AddDay(day)
}
// AddDur some duration time
func (t *Time) AddDur(dur time.Duration) *Time {
return &Time{
Time: t.Add(dur),
Layout: DefaultLayout,
}
}
// AddString add duration time string.
//
// Example:
//
// tn := timex.Now() // example as "2019-01-01 12:12:12"
// nt := tn.AddString("1h")
// nt.Datetime() // Output: 2019-01-01 13:12:12
func (t *Time) AddString(dur string) *Time {
d, err := ToDuration(dur)
if err != nil {
panic(err)
}
return t.AddDur(d)
}
// AddHour add some hour time
func (t *Time) AddHour(hours int) *Time {
return t.AddSeconds(hours * OneHourSec)
}
// SubHour minus some hour time
func (t *Time) SubHour(hours int) *Time {
return t.SubSeconds(hours * OneHourSec)
}
// AddMinutes add some minutes time for the time
func (t *Time) AddMinutes(minutes int) *Time {
return t.AddSeconds(minutes * OneMinSec)
}
// SubMinutes minus some minutes time for the time
func (t *Time) SubMinutes(minutes int) *Time {
return t.AddSeconds(-minutes * OneMinSec)
}
// AddSeconds add some seconds time the time
func (t *Time) AddSeconds(seconds int) *Time {
return &Time{
Time: t.Add(time.Duration(seconds) * time.Second),
// with layout
Layout: DefaultLayout,
}
}
// SubSeconds minus some seconds time the time
func (t *Time) SubSeconds(seconds int) *Time {
return &Time{
Time: t.Add(time.Duration(-seconds) * time.Second),
// with layout
Layout: DefaultLayout,
}
}
// Diff calc diff duration for t - u. alias of time.Time.Sub()
func (t Time) Diff(u time.Time) time.Duration {
return t.Sub(u)
}
// DiffSec calc diff seconds for t - u
func (t Time) DiffSec(u time.Time) int {
return int(t.Sub(u) / time.Second)
}
// DiffUnix calc diff seconds for t.Unix() - u
func (t Time) DiffUnix(u int64) int {
return int(t.Unix() - u)
}
// SubUnix calc diff seconds for t - u
func (t Time) SubUnix(u time.Time) int {
return int(t.Sub(u) / time.Second)
}
// HourStart time
func (t *Time) HourStart() *Time {
y, m, d := t.Date()
newTime := time.Date(y, m, d, t.Hour(), 0, 0, 0, t.Location())
return New(newTime)
}
// HourEnd time
func (t *Time) HourEnd() *Time {
y, m, d := t.Date()
newTime := time.Date(y, m, d, t.Hour(), 59, 59, int(time.Second-time.Nanosecond), t.Location())
return New(newTime)
}
// DayStart get time at 00:00:00
func (t *Time) DayStart() *Time {
y, m, d := t.Date()
newTime := time.Date(y, m, d, 0, 0, 0, 0, t.Location())
return New(newTime)
}
// DayEnd get time at 23:59:59
func (t *Time) DayEnd() *Time {
y, m, d := t.Date()
newTime := time.Date(y, m, d, 23, 59, 59, int(time.Second-time.Nanosecond), t.Location())
return New(newTime)
}
// CustomHMS custom change the hour, minute, second for create new time.
func (t *Time) CustomHMS(hour, min, sec int) *Time {
y, m, d := t.Date()
newTime := time.Date(y, m, d, hour, min, sec, int(time.Second-time.Nanosecond), t.Location())
return FromTime(newTime)
}
// IsBefore the given time
func (t *Time) IsBefore(u time.Time) bool {
return t.Before(u)
}
// IsBeforeUnix the given unix timestamp
func (t *Time) IsBeforeUnix(ux int64) bool {
return t.Before(time.Unix(ux, 0))
}
// IsAfter the given time
func (t *Time) IsAfter(u time.Time) bool {
return t.After(u)
}
// IsAfterUnix the given unix timestamp
func (t *Time) IsAfterUnix(ux int64) bool {
return t.After(time.Unix(ux, 0))
}
// Timestamp value. alias of t.Unix()
func (t Time) Timestamp() int64 {
return t.Unix()
}
// HowLongAgo format diff time to string.
func (t Time) HowLongAgo(before time.Time) string {
return mathutil.HowLongAgo(t.Unix() - before.Unix())
}
// UnmarshalJSON implements the json.Unmarshaler interface.
//
// Tip: will auto match a format by strutil.ToTime()
func (t *Time) UnmarshalJSON(data []byte) error {
// Ignore null, like in the main JSON package.
if string(data) == "null" {
return nil
}
// Fractional seconds are handled implicitly by Parse.
tt, err := strutil.ToTime(string(data[1 : len(data)-1]))
if err == nil {
t.Time = tt
}
return err
}
// UnmarshalText implements the encoding.TextUnmarshaler interface.
//
// Tip: will auto match a format by strutil.ToTime()
func (t *Time) UnmarshalText(data []byte) error {
// Fractional seconds are handled implicitly by Parse.
tt, err := strutil.ToTime(string(data))
if err == nil {
t.Time = tt
}
return err
}