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)) }