267 lines
6.9 KiB
Go
267 lines
6.9 KiB
Go
package datetime
|
||
|
||
import (
|
||
"fmt"
|
||
"time"
|
||
|
||
. "gitea.zaclys.com/bvaudour/gob/option"
|
||
)
|
||
|
||
func addUnit[I int | int64](t time.Time, duration I, unit time.Duration) time.Time {
|
||
return t.Add(time.Duration(duration) * unit)
|
||
}
|
||
|
||
// AddNanoseconds ajoute d ns à la date.
|
||
func AddNanoseconds[I int | int64](t time.Time, d I) time.Time {
|
||
return addUnit(t, d, Nanosecond)
|
||
}
|
||
|
||
// AddMicroseconds ajoute d μs à la date.
|
||
func AddMicroseconds[I int | int64](t time.Time, d I) time.Time {
|
||
return addUnit(t, d, Microsecond)
|
||
}
|
||
|
||
// AddMilliseconds ajoute d ms à la date.
|
||
func AddMilliseconds[I int | int64](t time.Time, d I) time.Time {
|
||
return addUnit(t, d, Millisecond)
|
||
}
|
||
|
||
// AddSeconds ajoute d s à la date.
|
||
func AddSeconds[I int | int64](t time.Time, d I) time.Time {
|
||
return addUnit(t, d, Second)
|
||
}
|
||
|
||
// AddMinutes ajoute d min à la date.
|
||
func AddMinutes[I int | int64](t time.Time, d I) time.Time {
|
||
return addUnit(t, d, Minute)
|
||
}
|
||
|
||
// AddHours ajoute d heures à la date.
|
||
func AddHours[I int | int64](t time.Time, d I) time.Time {
|
||
return addUnit(t, d, Hour)
|
||
}
|
||
|
||
// AddDays ajoute d jours à la date.
|
||
func AddDays[I int | int64](t time.Time, d I) time.Time {
|
||
return addUnit(t, d, Day)
|
||
}
|
||
|
||
// AddWeeks ajoute d semaines à la date.
|
||
func AddWeeks[I int | int64](t time.Time, d I) time.Time {
|
||
return addUnit(t, d, Week)
|
||
}
|
||
|
||
// AddMonths ajoute d mois à la date.
|
||
func AddMonths[I int | int64](t time.Time, d I) time.Time {
|
||
return t.AddDate(0, int(d), 0)
|
||
}
|
||
|
||
// AddYears ajoute d années à la date.
|
||
func AddYears[I int | int64](t time.Time, d I) time.Time {
|
||
return t.AddDate(int(d), 0, 0)
|
||
}
|
||
|
||
// AddDecades ajoute d×10 années à la date.
|
||
func AddDecades[I int | int64](t time.Time, d I) time.Time {
|
||
return AddYears(t, 10*d)
|
||
}
|
||
|
||
// AddCenturies ajoute d siècles à la date.
|
||
func AddCenturies[I int | int64](t time.Time, d I) time.Time {
|
||
return AddYears(t, 100*d)
|
||
}
|
||
|
||
func getTZ(tz ...string) (result Option[*time.Location]) {
|
||
if len(tz) > 0 {
|
||
location, err := time.LoadLocation(tz[0])
|
||
if err == nil {
|
||
return Some(location)
|
||
}
|
||
return
|
||
}
|
||
|
||
return Some(DefaultTZ)
|
||
}
|
||
|
||
func toTZ(t time.Time, tz ...string) Result[time.Time] {
|
||
if l, ok := getTZ(tz...).Get(); ok {
|
||
return Ok(t.In(l))
|
||
}
|
||
|
||
if len(tz) == 0 {
|
||
return Ok(t.In(DefaultTZ))
|
||
}
|
||
|
||
return Err[time.Time](fmt.Errorf(errInvalidTZ, tz))
|
||
}
|
||
|
||
// ToTimezone retourne la date dans le fuseau horaire indiqué.
|
||
func ToTimezone(t time.Time, tz string) Result[time.Time] {
|
||
return toTZ(t, tz)
|
||
}
|
||
|
||
// Local retourne la date dans le fuseau horaire local.
|
||
func Local(t time.Time) time.Time {
|
||
return t.In(time.Local)
|
||
}
|
||
|
||
// UTC retourne la date dans le fuseau UTC.
|
||
func UTC(t time.Time) time.Time {
|
||
return t.In(time.UTC)
|
||
}
|
||
|
||
// Date modifie la date avec l’année, le mois et le jour fournis.
|
||
func Date(t time.Time, year, month, day int) time.Time {
|
||
h, m, s := t.Clock()
|
||
e := t.Nanosecond()
|
||
l := t.Location()
|
||
|
||
return time.Date(year, time.Month(month-1), day, h, m, s, e, l)
|
||
}
|
||
|
||
// Clock modifie l’heure de la date.
|
||
func Clock(t time.Time, hour, minute, second int, nano ...int) time.Time {
|
||
y, m, d := t.Date()
|
||
l := t.Location()
|
||
e := 0
|
||
|
||
if len(nano) > 0 {
|
||
e = nano[0]
|
||
}
|
||
|
||
return time.Date(y, m, d, hour, minute, second, e, l)
|
||
}
|
||
|
||
// SetNano modifie les nanosecondes de la date.
|
||
func SetNano(t time.Time, nano int) time.Time {
|
||
h, m, s := t.Clock()
|
||
|
||
return Clock(t, h, m, s, nano)
|
||
}
|
||
|
||
// SetSecond modifie la seconde de la date (et éventuellement la ns).
|
||
func SetSecond(t time.Time, second int, nano ...int) time.Time {
|
||
h, m := t.Hour(), t.Minute()
|
||
e := t.Nanosecond()
|
||
if len(nano) > 0 {
|
||
e = nano[0]
|
||
}
|
||
|
||
return Clock(t, h, m, second, e)
|
||
}
|
||
|
||
// SetMinute modifie la minute de la date (et éventuellement la s et la ns).
|
||
func SetMinute(t time.Time, minute int, other ...int) time.Time {
|
||
h, s, e := t.Hour(), t.Second(), t.Nanosecond()
|
||
if len(other) > 0 {
|
||
s = other[0]
|
||
if len(other) > 1 {
|
||
e = other[1]
|
||
}
|
||
}
|
||
|
||
return Clock(t, h, minute, s, e)
|
||
}
|
||
|
||
// SetHour modifie l’heure de la date (et éventuellement la min, s & ns).
|
||
func SetHour(t time.Time, hour int, other ...int) time.Time {
|
||
m, s, e := t.Minute(), t.Second(), t.Nanosecond()
|
||
if len(other) > 0 {
|
||
m = other[0]
|
||
if len(other) > 1 {
|
||
s = other[1]
|
||
if len(other) > 2 {
|
||
e = other[2]
|
||
}
|
||
}
|
||
}
|
||
|
||
return Clock(t, hour, m, s, e)
|
||
}
|
||
|
||
// SetDay modifie le jour de la date.
|
||
func SetDay(t time.Time, day int) time.Time {
|
||
y, m := t.Year(), t.Month()
|
||
|
||
return Date(t, y, int(m+1), day)
|
||
}
|
||
|
||
// SetMonth modifie le mois de la date (et éventuellement le jour).
|
||
func SetMonth(t time.Time, month int, day ...int) time.Time {
|
||
y, d := t.Year(), t.Day()
|
||
if len(day) > 0 {
|
||
d = day[0]
|
||
}
|
||
|
||
return Date(t, y, month, d)
|
||
}
|
||
|
||
// SetYear modifie l’année de la date (et éventuellement le mois et le jour).
|
||
func SetYear(t time.Time, year int, other ...int) time.Time {
|
||
m, d := int(t.Month()+1), t.Day()
|
||
if len(other) > 0 {
|
||
m = other[0]
|
||
if len(other) > 1 {
|
||
d = other[1]
|
||
}
|
||
}
|
||
|
||
return Date(t, year, m, d)
|
||
}
|
||
|
||
// BeginOfSecond retourne la date au début de la seconde en cours.
|
||
func BeginOfSecond(t time.Time) time.Time { return SetNano(t, 0) }
|
||
|
||
// EndOfSecond retourne la date à la fin de la seconde en cours.
|
||
func EndOfSecond(t time.Time) time.Time { return SetNano(t, 999999999) }
|
||
|
||
// BeginOfMinute retourne la date au début de la minute en cours.
|
||
func BeginOfMinute(t time.Time) time.Time { return SetSecond(t, 0, 0) }
|
||
|
||
// EndOfMinute retourne la date à la fin de la minute en cours.
|
||
func EndOfMinute(t time.Time) time.Time { return SetSecond(t, 59, 999999999) }
|
||
|
||
// BeginOfHour retourne la date au début de l’heure en cours.
|
||
func BeginOfHour(t time.Time) time.Time { return SetMinute(t, 0, 0, 0) }
|
||
|
||
// EndOfHour retourne la date à la fin de l’heure en cours.
|
||
func EndOfHour(t time.Time) time.Time { return SetMinute(t, 59, 59, 999999999) }
|
||
|
||
// BeginOfDay retourne la date au début du jour en cours.
|
||
func BeginOfDay(t time.Time) time.Time { return SetHour(t, 0, 0, 0, 0) }
|
||
|
||
// EndOfDay retourne la date à la fin du jour en cours.
|
||
func EndOfDay(t time.Time) time.Time { return SetHour(t, 23, 59, 59, 999999999) }
|
||
|
||
// BeginOfWeek retourne la date au début de la semaine en cours.
|
||
func BeginOfWeek(t time.Time) time.Time {
|
||
d := t.Weekday()
|
||
if d == time.Sunday {
|
||
d += 7
|
||
}
|
||
|
||
return BeginOfDay(t.AddDate(0, 0, 1-int(d)))
|
||
}
|
||
|
||
// EndOfWeek retourne la date à la fin de la semaine en cours.
|
||
func EndOfWeek(t time.Time) time.Time {
|
||
d := t.Weekday()
|
||
if d == time.Sunday {
|
||
d += 7
|
||
}
|
||
|
||
return EndOfDay(t.AddDate(0, 0, 7-int(d)))
|
||
}
|
||
|
||
// BeginOfMonth retourne la date au début du mois en cours.
|
||
func BeginOfMonth(t time.Time) time.Time { return BeginOfDay(SetDay(t, 1)) }
|
||
|
||
// EndOfMonth retourne la date à la fin du mois en cours.
|
||
func EndOfMonth(t time.Time) time.Time { return EndOfDay(SetDay(t, DaysInMonth(t))) }
|
||
|
||
// BeginOfYear retourne la date au début de l’année en cours.
|
||
func BeginOfYear(t time.Time) time.Time { return BeginOfDay(SetMonth(t, 1, 1)) }
|
||
|
||
// EndOfYear retourne la date à la fin de l’année en cours.
|
||
func EndOfYear(t time.Time) time.Time { return EndOfDay(SetMonth(t, 12, 31)) }
|