Repository navigation
Expand file tree
/
Copy pathapi.go
More file actions
153 lines (123 loc) · 5.66 KB
/
Copy pathapi.go
File metadata and controls
153 lines (123 loc) · 5.66 KB
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
package time
import "webtyp.com/calendar"
// Unix is an instant in whole seconds since 1970-01-01 UTC: the unit of dates and deadlines (an expiry, the day of a
// booking, the end of a session, the exp of a JWT). Every calendar function and every formatter takes a Unix.
type Unix int64
// Nano is an instant in nanoseconds since 1970-01-01 UTC: the unit of the instant an event happened (created_at,
// updated_at), fine enough to order two events of the same second. Convert it to a date with its Unix method.
type Nano int64
// Durations in seconds, typed: NowUnix() + 30*Day compiles; NowNano() + 30*Day does not, because it mixes units.
const (
Minute Unix = 60
Hour Unix = 3600
Day Unix = 86400
)
// Duration is a length of time in nanoseconds: how long to wait, never an instant. A wait is a Duration and an instant
// is a Nano or a Unix, so passing one for the other does not compile. A Duration is written with its unit:
// 250*time.Millisecond, 2*time.Second; a minute is 60*time.Second (Minute, Hour and Day are Unix seconds, see above).
type Duration int64
// Durations in nanoseconds, typed: backoff.New(time.Second, 60*time.Second) says what it means.
const (
Nanosecond Duration = 1
Microsecond = 1000 * Nanosecond
Millisecond = 1000 * Microsecond
Second = 1000 * Millisecond
)
const nanosPerSecond = int64(Second)
// Milliseconds is the whole milliseconds of d, the unit of AfterFunc and of a browser timer; a fraction is dropped.
//
// Example: AfterFunc(int((1500*Millisecond).Milliseconds()), f) // 1500
func (d Duration) Milliseconds() int64 { return int64(d / Millisecond) }
// Add is the instant d after n: when the next attempt is due, when a wait ends.
//
// Example: due := NowNano().Add(30 * Second)
func (n Nano) Add(d Duration) Nano { return n + Nano(d) }
// Unix truncates an event instant to the second, for comparing it with a date or formatting it.
func (n Nano) Unix() Unix { return Unix(int64(n) / nanosPerSecond) }
// Nano is the first nanosecond of a date's second, for comparing it with an event instant.
func (u Unix) Nano() Nano { return Nano(int64(u) * nanosPerSecond) }
// Timer represents a cancelable timer.
type Timer interface {
// Stop prevents the timer from firing. Returns true if the timer was active.
Stop() bool
}
// NowUnix is the current instant in seconds, for dates and deadlines.
func NowUnix() Unix { return Unix(provider.UnixNano() / nanosPerSecond) }
// NowNano is the current instant in nanoseconds, for the instant of an event.
func NowNano() Nano { return Nano(provider.UnixNano()) }
// FormatMinutes formats minutes since midnight as "HH:MM".
func FormatMinutes(minutes int) string {
return twoDigits(minutes/60) + ":" + twoDigits(minutes%60)
}
// FormatISO8601 formats an instant as "YYYY-MM-DDTHH:MM:SSZ" (UTC).
func FormatISO8601(u Unix) string { return provider.FormatISO8601(u) }
// FormatCompact formats an instant as "YYYYMMDDHHmmss" (UTC): PDF metadata, file names.
func FormatCompact(u Unix) string { return provider.FormatCompact(u) }
// ParseDateUTC parses "YYYY-MM-DD" into the instant of its midnight UTC: a date as a key, in no place's clock.
// For a place's midnight use Zone.At(date, 0).
func ParseDateUTC(dateStr string) (Unix, error) { return provider.ParseDateUTC(dateStr) }
// ParseTime parses "HH:MM" or "HH:MM:SS" into minutes since midnight.
func ParseTime(timeStr string) (int16, error) { return provider.ParseTime(timeStr) }
// IsPast reports whether the instant is before now.
func IsPast(u Unix) bool { return u < NowUnix() }
// IsFuture reports whether the instant is after now.
func IsFuture(u Unix) bool { return u > NowUnix() }
// DaysBetween is the number of full days from a to b (negative when b is before a).
func DaysBetween(a, b Unix) int { return int((b - a) / Day) }
// WeekdayUTC returns the day of the week (0=Sunday … 6=Saturday) of an instant in UTC. A place's weekday is
// Zone.Weekday.
func WeekdayUTC(u Unix) int {
y, m, d, _, _, _ := CivilUTC(u)
return calendar.Weekday(y, m, d)
}
// MidnightUTC returns midnight UTC of the day that contains the instant.
func MidnightUTC(u Unix) Unix {
days := u / Day
if u < 0 && u%Day != 0 {
days--
}
return days * Day
}
// DateUTC returns the instant of a UTC date and time. Pure arithmetic, deterministic in WASM and backend. A place's
// date and time is Zone.At.
func DateUTC(year, month, day, hour, min, sec int) Unix {
days := calendar.DaysSinceEpoch(year, month, day)
return Unix(days*86400 + int64(hour*3600+min*60+sec))
}
// CivilUTC splits an instant into its UTC year, month, day, hour, minute and second. A place's are Zone.Date and
// Zone.Clock.
func CivilUTC(u Unix) (year, month, day, hour, min, sec int) {
days := int64(u) / 86400
rem := int64(u) % 86400
if rem < 0 {
days--
rem += 86400
}
year, month, day = calendar.FromDaysSinceEpoch(days)
hour = int(rem / 3600)
rem %= 3600
min = int(rem / 60)
sec = int(rem % 60)
return
}
// AfterFunc waits for the specified milliseconds then calls f.
func AfterFunc(milliseconds int, f func()) Timer { return provider.AfterFunc(milliseconds, f) }
func twoDigits(n int) string {
if n < 10 {
return "0" + string(rune('0'+n))
}
return string(rune('0'+n/10)) + string(rune('0'+n%10))
}
// timeProvider is what each platform (standard Go, WASM) supplies.
type timeProvider interface {
UnixNano() int64
FormatISO8601(u Unix) string
FormatCompact(u Unix) string
ParseDateUTC(dateStr string) (Unix, error)
ParseTime(timeStr string) (int16, error)
// zoneOffset is the zone's offset from UTC at u, in seconds; name "" = this computer's zone.
zoneOffset(name string, u Unix) (int, error)
machineZoneName() string
AfterFunc(milliseconds int, f func()) Timer
}
var provider timeProvider