1package legacydata
2
3import (
4	"strconv"
5	"time"
6
7	"github.com/timberio/go-datemath"
8)
9
10type DataTimeRange struct {
11	From string
12	To   string
13	Now  time.Time
14}
15
16func NewDataTimeRange(from, to string) DataTimeRange {
17	return DataTimeRange{
18		From: from,
19		To:   to,
20		Now:  time.Now(),
21	}
22}
23
24func (tr *DataTimeRange) GetFromAsMsEpoch() int64 {
25	return tr.MustGetFrom().UnixNano() / int64(time.Millisecond)
26}
27
28func (tr *DataTimeRange) GetFromAsSecondsEpoch() int64 {
29	return tr.GetFromAsMsEpoch() / 1000
30}
31
32func (tr *DataTimeRange) GetFromAsTimeUTC() time.Time {
33	return tr.MustGetFrom().UTC()
34}
35
36func (tr *DataTimeRange) GetToAsMsEpoch() int64 {
37	return tr.MustGetTo().UnixNano() / int64(time.Millisecond)
38}
39
40func (tr *DataTimeRange) GetToAsSecondsEpoch() int64 {
41	return tr.GetToAsMsEpoch() / 1000
42}
43
44func (tr *DataTimeRange) GetToAsTimeUTC() time.Time {
45	return tr.MustGetTo().UTC()
46}
47
48func (tr *DataTimeRange) MustGetFrom() time.Time {
49	res, err := tr.ParseFrom()
50	if err != nil {
51		return time.Unix(0, 0)
52	}
53	return res
54}
55
56func (tr *DataTimeRange) MustGetTo() time.Time {
57	res, err := tr.ParseTo()
58	if err != nil {
59		return time.Unix(0, 0)
60	}
61	return res
62}
63
64func (tr DataTimeRange) ParseFrom() (time.Time, error) {
65	return parseTimeRange(tr.From, tr.Now, false, nil)
66}
67
68func (tr DataTimeRange) ParseTo() (time.Time, error) {
69	return parseTimeRange(tr.To, tr.Now, true, nil)
70}
71
72func (tr DataTimeRange) ParseFromWithLocation(location *time.Location) (time.Time, error) {
73	return parseTimeRange(tr.From, tr.Now, false, location)
74}
75
76func (tr DataTimeRange) ParseToWithLocation(location *time.Location) (time.Time, error) {
77	return parseTimeRange(tr.To, tr.Now, true, location)
78}
79
80func (tr DataTimeRange) ParseFromWithWeekStart(location *time.Location, weekstart time.Weekday) (time.Time, error) {
81	return parseTimeRangeWithWeekStart(tr.From, tr.Now, false, location, weekstart)
82}
83
84func (tr *DataTimeRange) ParseToWithWeekStart(location *time.Location, weekstart time.Weekday) (time.Time, error) {
85	return parseTimeRangeWithWeekStart(tr.To, tr.Now, true, location, weekstart)
86}
87
88func parseTimeRange(s string, now time.Time, withRoundUp bool, location *time.Location) (time.Time, error) {
89	return parseTimeRangeWithWeekStart(s, now, withRoundUp, location, -1)
90}
91
92func parseTimeRangeWithWeekStart(s string, now time.Time, withRoundUp bool, location *time.Location, weekstart time.Weekday) (time.Time, error) {
93	if val, err := strconv.ParseInt(s, 10, 64); err == nil {
94		seconds := val / 1000
95		nano := (val - seconds*1000) * 1000000
96		return time.Unix(seconds, nano), nil
97	}
98
99	diff, err := time.ParseDuration("-" + s)
100	if err != nil {
101		options := []func(*datemath.Options){
102			datemath.WithNow(now),
103			datemath.WithRoundUp(withRoundUp),
104		}
105		if location != nil {
106			options = append(options, datemath.WithLocation(location))
107		}
108		if weekstart != -1 {
109			if weekstart > now.Weekday() {
110				weekstart = weekstart - 7
111			}
112			options = append(options, datemath.WithStartOfWeek(weekstart))
113		}
114
115		return datemath.ParseAndEvaluate(s, options...)
116	}
117
118	return now.Add(diff), nil
119}
120