2023-10-31 10:18:00 +00:00
|
|
|
|
package datetime
|
|
|
|
|
|
|
|
|
|
import (
|
2023-11-03 19:33:26 +00:00
|
|
|
|
"fmt"
|
2023-11-04 10:39:54 +00:00
|
|
|
|
"regexp"
|
|
|
|
|
"strconv"
|
2023-10-31 10:18:00 +00:00
|
|
|
|
)
|
|
|
|
|
|
2023-11-03 19:33:26 +00:00
|
|
|
|
// Unit est une unité de durée.
|
|
|
|
|
type Unit uint
|
2023-10-31 10:18:00 +00:00
|
|
|
|
|
2023-11-04 10:39:54 +00:00
|
|
|
|
func (u Unit) String() string { return unitToString[u] }
|
|
|
|
|
|
2023-11-03 19:33:26 +00:00
|
|
|
|
// Duration est une durée entre deux repères de temps.
|
|
|
|
|
type Duration int
|
|
|
|
|
|
|
|
|
|
// NewDuration retourne une durée à partir d’une valeur et d’une unité.
|
|
|
|
|
func NewDuration(value int, unit Unit) Duration {
|
|
|
|
|
if unit == NoUnit {
|
|
|
|
|
return DurationNil
|
2023-10-31 10:18:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-03 19:33:26 +00:00
|
|
|
|
return (Duration(value) << bitsUnit) | Duration(unit)
|
2023-10-31 10:18:00 +00:00
|
|
|
|
}
|
|
|
|
|
|
2023-11-04 10:39:54 +00:00
|
|
|
|
// ParseDuration retourne une durée à partir d’une chaîne de caractères.
|
|
|
|
|
func ParseDuration(e string) Duration {
|
|
|
|
|
r := regexp.MustCompile(`^(\d+)(\w+)$`)
|
|
|
|
|
if !r.MatchString(e) {
|
|
|
|
|
return DurationNil
|
|
|
|
|
}
|
|
|
|
|
spl := r.FindAllStringSubmatch(e, 1)[0]
|
|
|
|
|
|
|
|
|
|
v, _ := strconv.Atoi(spl[1])
|
|
|
|
|
u := NoUnit
|
|
|
|
|
for uu, su := range unitToString {
|
|
|
|
|
if su == spl[2] {
|
|
|
|
|
u = uu
|
|
|
|
|
break
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return NewDuration(v, u)
|
|
|
|
|
}
|
|
|
|
|
|
2023-11-03 19:33:26 +00:00
|
|
|
|
// Value retourne la valeur de la durée, sans l’unité.
|
|
|
|
|
func (d Duration) Value() int { return int(d >> bitsUnit) }
|
2023-10-31 10:18:00 +00:00
|
|
|
|
|
2023-11-03 19:33:26 +00:00
|
|
|
|
// Unit retourne l’unité de durée.
|
|
|
|
|
func (d Duration) Unit() Unit { return Unit(d & maskUnit) }
|
2023-10-31 10:18:00 +00:00
|
|
|
|
|
2023-11-03 19:33:26 +00:00
|
|
|
|
// Duration retourne la valeur et l’unité de la durée.
|
|
|
|
|
func (d Duration) Duration() (int, Unit) { return d.Value(), d.Unit() }
|
2023-10-31 10:18:00 +00:00
|
|
|
|
|
2023-11-03 19:33:26 +00:00
|
|
|
|
// IsNil retourne vrai si la durée ne représente pas une durée valide.
|
|
|
|
|
func (d Duration) IsNil() bool { return d.Unit() == NoUnit }
|
2023-10-31 10:18:00 +00:00
|
|
|
|
|
2023-11-03 19:33:26 +00:00
|
|
|
|
// IsClock retourne vrai si la durée est dans une unité de temps sur 24h.
|
|
|
|
|
func (d Duration) IsClock() bool { u := d.Unit(); return u > NoUnit && u < Day }
|
2023-10-31 10:18:00 +00:00
|
|
|
|
|
2023-11-03 19:33:26 +00:00
|
|
|
|
// IsDate retourne vrai si la durée est dans une unité de date.
|
|
|
|
|
func (d Duration) IsDate() bool { return d.Unit() > Hour }
|
2023-10-31 10:18:00 +00:00
|
|
|
|
|
2023-11-03 19:33:26 +00:00
|
|
|
|
// Abs retourne la durée en valeur absolue.
|
|
|
|
|
func (d Duration) Abs() Duration { return NewDuration(abs(d.Value()), d.Unit()) }
|
2023-10-31 10:18:00 +00:00
|
|
|
|
|
2023-11-03 19:33:26 +00:00
|
|
|
|
// Neg retourne l’inverse négatif de la durée.
|
|
|
|
|
func (d Duration) Neg() Duration { return NewDuration(-d.Value(), d.Unit()) }
|
2023-10-31 10:18:00 +00:00
|
|
|
|
|
2023-11-03 19:33:26 +00:00
|
|
|
|
// String retourne la représentation textuelle de la durée.
|
|
|
|
|
func (d Duration) String() string {
|
|
|
|
|
if d.IsNil() {
|
|
|
|
|
return "-"
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
v, u := d.Value(), d.Unit()
|
2023-10-31 10:18:00 +00:00
|
|
|
|
|
2023-11-04 10:39:54 +00:00
|
|
|
|
return fmt.Sprintf("%d%s", v, u)
|
2023-10-31 10:18:00 +00:00
|
|
|
|
}
|