gob/datetime/util.go

134 lines
3.2 KiB
Go

package datetime
import (
"time"
)
type integer interface {
~int | ~int8 | ~int16 | ~int32 | ~int64
}
type uinteger interface {
~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64
}
type float interface {
~float32 | ~float64
}
type number interface {
integer | uinteger | float
}
func cmp[N number](n1, n2 N) int {
switch {
case n1 < n2:
return -1
case n1 == n2:
return 0
default:
return 1
}
}
func abs[N integer | float](n N) N {
if n < 0 {
return -n
}
return n
}
func spl[N integer | uinteger](e []N, n int) (ed, ec []N) {
ed = e
if len(e) > n {
ed, ec = e[:n], e[n:]
}
return
}
func bissextil(y int) bool { return y%4 == 0 && !(y%100 == 0 && y%400 != 0) }
func monthLen(y int, m uint) uint {
switch m {
case February:
if bissextil(y) {
return 29
}
return 28
case April, June, September, November:
return 30
case January, March, May, July, August, October, December:
return 31
default:
return 0
}
}
func yearLen(y int) uint {
if bissextil(y) {
return 366
}
return 365
}
func sit(h, i uint, args ...uint) float64 {
var s, v uint
if len(args) > 0 {
s = args[0]
if len(args) > 1 {
v = args[1]
}
}
v += s*MillisecondPerSecond + i*MillisecondPerMinute + h*MillisecondPerHour
return float64(v) * float64(BeatPerDay) / float64(MillisecondPerDay)
}
func timezone(tz ...string) *time.Location {
if len(tz) > 0 {
if l, err := time.LoadLocation(tz[0]); err == nil {
return l
}
}
return DefaultTZ
}
func toTZ(t time.Time, tz ...string) time.Time { return t.In(timezone(tz...)) }
func now(tz ...string) time.Time { return toTZ(time.Now(), tz...) }
func yesterday(tz ...string) time.Time { return now(tz...).AddDate(0, 0, -1) }
func tomorrow(tz ...string) time.Time { return now(tz...).AddDate(0, 0, 1) }
func fromDT(y int, m, d, h, i, s, v uint, l *time.Location) time.Time {
return time.Date(y, time.Month(m-1), int(d), int(h), int(i), int(s), int(d*NanosecondPerMillisecond), l)
}
func fromD(y int, m, d uint, l *time.Location) time.Time { return fromDT(y, m, d, 0, 0, 0, 0, l) }
func fromT(h, i, s, v uint, l *time.Location) time.Time {
t := now().In(l)
y, m, d := t.Year(), uint(t.Month()-1), uint(t.Day())
return fromDT(y, m, d, h, i, s, v, l)
}
// Clock
func formatC(h, i uint, args ...uint) (uint, uint, uint, uint, Precision) {
l := len(args)
p, s, v := PrecisionMinute-Precision(l), uint(0), uint(0)
if l > 0 {
s = args[0]
if l > 1 {
v = args[1]
}
}
return h, i, s, v, p
}
func ms(h, i, s, n uint) uint {
return h*MillisecondPerHour + i*MillisecondPerMinute + s*MillisecondPerSecond + n
}
// Date
func validM(m uint) bool { return m >= January && m <= December }
func validD(y int, m, d uint) bool { return validM(m) && d > 0 && d < monthLen(y, m) }
func getD[N integer | uinteger](d date, t string) N { return N((d & maskDate[t]) >> shiftDate[t]) }
func setD[N integer | uinteger](e N, t string) date { return date(e<<shiftDate[t]) & maskDate[t] }
func replD[N integer | uinteger](d date, e N, t string) date {
return (d & ^maskDate[t]) | setD(e, t)
}
func diffBow(d uint) int { return int(Monday) - ((int(d) + DayPerWeek) % DayPerWeek) }
func diffEow(d uint) int { return DayPerWeek - ((int(d) + DayPerWeek) % DayPerWeek) }