1package gofakes3
2
3import "time"
4
5type TimeSource interface {
6	Now() time.Time
7	Since(time.Time) time.Duration
8}
9
10type TimeSourceAdvancer interface {
11	TimeSource
12	Advance(by time.Duration)
13}
14
15// FixedTimeSource provides a source of time that always returns the
16// specified time.
17func FixedTimeSource(at time.Time) TimeSourceAdvancer {
18	return &fixedTimeSource{time: at}
19}
20
21func DefaultTimeSource() TimeSource {
22	return &locatedTimeSource{
23		// XXX: uses time.FixedZone to 'fake' the GMT timezone that S3 uses
24		// (which is basically just UTC with a different name) to avoid
25		// time.LoadLocation, which requires zoneinfo.zip to be available and
26		// can break spectacularly on Windows (https://github.com/golang/go/issues/21881)
27		// or Docker.
28		timeLocation: time.FixedZone("GMT", 0),
29	}
30}
31
32type locatedTimeSource struct {
33	timeLocation *time.Location
34}
35
36func (l *locatedTimeSource) Now() time.Time {
37	return time.Now().In(l.timeLocation)
38}
39
40func (l *locatedTimeSource) Since(t time.Time) time.Duration {
41	return time.Since(t)
42}
43
44type fixedTimeSource struct {
45	time time.Time
46}
47
48func (l *fixedTimeSource) Now() time.Time {
49	return l.time
50}
51
52func (l *fixedTimeSource) Since(t time.Time) time.Duration {
53	return l.time.Sub(t)
54}
55
56func (l *fixedTimeSource) Advance(by time.Duration) {
57	l.time = l.time.Add(by)
58}
59