Màj du README + commentaires datetime plus précis + ajout de la méthode String() à Range & Duration + Parsage d’une durée + gestion des périodes avec borne infinie à droite et/ou à gauche
This commit is contained in:
parent
41e37d8398
commit
976ac750b1
|
@ -37,6 +37,15 @@ Le paquet **convert** fournit le nécessaire pour convertir des variables typée
|
||||||
|
|
||||||
Tous ces types sont convertibles entre eux.
|
Tous ces types sont convertibles entre eux.
|
||||||
|
|
||||||
|
### datetime
|
||||||
|
|
||||||
|
Le paquet **datetime** implémente des structures pour gérer des temps :
|
||||||
|
|
||||||
|
- datetime.Clock : pour gérer une heure dans la journée,
|
||||||
|
- datetime.Date : pour gérer une date, sans indication de l’heure,
|
||||||
|
- datetime.DateTime : pour gérer une date avec indication de l’heure.
|
||||||
|
- Range : pour gérer une période entre deux temps.
|
||||||
|
|
||||||
### format
|
### format
|
||||||
|
|
||||||
Le paquet **format** fournit le nécessaire pour formater la sortie terminal :
|
Le paquet **format** fournit le nécessaire pour formater la sortie terminal :
|
||||||
|
|
|
@ -7,6 +7,14 @@ import (
|
||||||
type clock uint
|
type clock uint
|
||||||
|
|
||||||
// Precision représente la précision d’une horloge.
|
// Precision représente la précision d’une horloge.
|
||||||
|
// Par exemple :
|
||||||
|
// - 15:06 est une horloge précise à la minute,
|
||||||
|
// - 15:06:02 est précise à la seconde,
|
||||||
|
// - 15:06:02.257 est précise à la milliseconde.
|
||||||
|
//
|
||||||
|
// La précision est utilisée dans Clock pour les comparaisons :
|
||||||
|
// les comparaisons entre deux horloges se font à la précision
|
||||||
|
// le l’horloge la moins précise.
|
||||||
type Precision uint
|
type Precision uint
|
||||||
|
|
||||||
func newC0(h, i uint, e ...uint) clock {
|
func newC0(h, i uint, e ...uint) clock {
|
||||||
|
@ -213,11 +221,13 @@ func setClock(v uint, p Precision, l *time.Location) Clock {
|
||||||
return newClock(newC(v, p), l)
|
return newClock(newC(v, p), l)
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClock retourne une horloge dans le fuseau horaire par défaut.
|
// NewClock retourne une horloge à l’heure h et la minute i dans le fuseau horaire par défaut.
|
||||||
// La précision est calculée automatiquement suivant que la seconde et la milliseconde sont indiquées.
|
// La précision est calculée automatiquement suivant que la seconde et la milliseconde sont également
|
||||||
|
// présentes dans args.
|
||||||
func NewClock(h uint, i uint, args ...uint) Clock { return newClock(newC0(h, i, args...), DefaultTZ) }
|
func NewClock(h uint, i uint, args ...uint) Clock { return newClock(newC0(h, i, args...), DefaultTZ) }
|
||||||
|
|
||||||
// NewClockTZ agit comme NewClock mais dans le fuseau horaire tz.
|
// NewClockTZ agit comme NewClock mais dans le fuseau horaire tz.
|
||||||
|
// tz peut être mis sous la forme "Europe/Paris", "CET", "Local", etc.
|
||||||
func NewClockTZ(tz string, h uint, i uint, args ...uint) Clock {
|
func NewClockTZ(tz string, h uint, i uint, args ...uint) Clock {
|
||||||
c := NewClock(h, i, args...)
|
c := NewClock(h, i, args...)
|
||||||
if c.valid() {
|
if c.valid() {
|
||||||
|
@ -227,7 +237,8 @@ func NewClockTZ(tz string, h uint, i uint, args ...uint) Clock {
|
||||||
return c
|
return c
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewClockFromTime retourne l’heure à partir d’une date Go.
|
// NewClockFromTime retourne l’heure à partir d’une date Go t.
|
||||||
|
// Si la précision p n’est pas définie, c’est une précision à la ms.
|
||||||
func NewClockFromTime(t time.Time, p ...Precision) Clock {
|
func NewClockFromTime(t time.Time, p ...Precision) Clock {
|
||||||
var (
|
var (
|
||||||
pp = PrecisionMillisecond
|
pp = PrecisionMillisecond
|
||||||
|
@ -243,15 +254,16 @@ func NewClockFromTime(t time.Time, p ...Precision) Clock {
|
||||||
return setClock(ms(uint(h), uint(i), uint(s), uint(v)), pp, l)
|
return setClock(ms(uint(h), uint(i), uint(s), uint(v)), pp, l)
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClockNow retourne l’heure actuelle. Si tz est renseignée,
|
// ClockNow retourne l’heure actuelle avec une précision p. Si tz est renseignée,
|
||||||
// l’heure est placée dans le fuseau horaire indiqué.
|
// l’heure est placée dans le fuseau horaire indiqué.
|
||||||
func ClockNow(p Precision, tz ...string) Clock {
|
func ClockNow(p Precision, tz ...string) Clock {
|
||||||
return NewClockFromTime(now(tz...), p)
|
return NewClockFromTime(now(tz...), p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now retourne l’heure actuelle avec la même précision et le même fuseau horaire que c.
|
||||||
func (c Clock) Now() Clock { return ClockNow(c.p(), c.location.String()) }
|
func (c Clock) Now() Clock { return ClockNow(c.p(), c.location.String()) }
|
||||||
|
|
||||||
// ClockGuess retourne l’heure à partir de e en essayant de deviner le format.
|
// ClockGuess retourne l’heure à partir de e et à la précision p en essayant de deviner le format.
|
||||||
func ClockGuess(p Precision, e string, tz ...string) Clock {
|
func ClockGuess(p Precision, e string, tz ...string) Clock {
|
||||||
if t, ok := guess(e, tz...).Get(); ok {
|
if t, ok := guess(e, tz...).Get(); ok {
|
||||||
return NewClockFromTime(t, p)
|
return NewClockFromTime(t, p)
|
||||||
|
@ -260,7 +272,7 @@ func ClockGuess(p Precision, e string, tz ...string) Clock {
|
||||||
return ClockNil()
|
return ClockNil()
|
||||||
}
|
}
|
||||||
|
|
||||||
// ClockParse retourne l’heure à partir de e en spécifiant le format f.
|
// ClockParse retourne l’heure à partir de e et à la précision p en spécifiant le format f.
|
||||||
func ClockParse(p Precision, e, f string, tz ...string) Clock {
|
func ClockParse(p Precision, e, f string, tz ...string) Clock {
|
||||||
if t, ok := parse(e, f).Get(); ok {
|
if t, ok := parse(e, f).Get(); ok {
|
||||||
return NewClockFromTime(t, p)
|
return NewClockFromTime(t, p)
|
||||||
|
@ -299,19 +311,19 @@ func (c Clock) Hour() uint { return c.h() }
|
||||||
// Clock retourne l’heure, la minute, la seconde et la milliseconde.
|
// Clock retourne l’heure, la minute, la seconde et la milliseconde.
|
||||||
func (c Clock) Clock() (h, i, s, v uint) { return c.h(), c.i(), c.s(), c.v() }
|
func (c Clock) Clock() (h, i, s, v uint) { return c.h(), c.i(), c.s(), c.v() }
|
||||||
|
|
||||||
// SetMilli modifie la milliseconde.
|
// SetMilli modifie la milliseconde de la seconde.
|
||||||
func (c Clock) SetMilli(v uint) Clock { return newClock(c.setV(v), c.location) }
|
func (c Clock) SetMilli(v uint) Clock { return newClock(c.setV(v), c.location) }
|
||||||
|
|
||||||
// SetSecond modifie la seconde.
|
// SetSecond modifie la seconde de la minute, et la milliseconde, si v est renseignée.
|
||||||
func (c Clock) SetSecond(s uint, v ...uint) Clock { return newClock(c.setS(s, v...), c.location) }
|
func (c Clock) SetSecond(s uint, v ...uint) Clock { return newClock(c.setS(s, v...), c.location) }
|
||||||
|
|
||||||
// SetMinute modifie la minute.
|
// SetMinute modifie la minute de l’heure, ainsi que la seconde et la millisecondes si elles sont renseignées.
|
||||||
func (c Clock) SetMinute(i uint, args ...uint) Clock { return newClock(c.setI(i, args...), c.location) }
|
func (c Clock) SetMinute(i uint, args ...uint) Clock { return newClock(c.setI(i, args...), c.location) }
|
||||||
|
|
||||||
// SetHour modifie l’heure.
|
// SetHour modifie l’heure et, facultativement, la minute, la seconde et la milliseconde.
|
||||||
func (c Clock) SetHour(h uint, args ...uint) Clock { return newClock(c.setH(h, args...), c.location) }
|
func (c Clock) SetHour(h uint, args ...uint) Clock { return newClock(c.setH(h, args...), c.location) }
|
||||||
|
|
||||||
// SetPrecision modifie la précision.
|
// SetPrecision retourne l’horloge avec la précision p.
|
||||||
func (c Clock) SetPrecision(p Precision) Clock { return newClock(c.setP(p), c.location) }
|
func (c Clock) SetPrecision(p Precision) Clock { return newClock(c.setP(p), c.location) }
|
||||||
|
|
||||||
// Add ajoute un nombre d’heures et de minutes, et, facultativement,
|
// Add ajoute un nombre d’heures et de minutes, et, facultativement,
|
||||||
|
@ -327,7 +339,7 @@ func (c Clock) AddMinute(i int) Clock { return newClock(c.addI(i), c.location) }
|
||||||
// AddSecond ajoute une durée en secondes.
|
// AddSecond ajoute une durée en secondes.
|
||||||
func (c Clock) AddSecond(s int) Clock { return newClock(c.addS(s), c.location) }
|
func (c Clock) AddSecond(s int) Clock { return newClock(c.addS(s), c.location) }
|
||||||
|
|
||||||
// AddMilli ajoute une durée en ms.
|
// AddMilli ajoute une durée en millisecondes.
|
||||||
func (c Clock) AddMilli(v int) Clock { return newClock(c.addV(v), c.location) }
|
func (c Clock) AddMilli(v int) Clock { return newClock(c.addV(v), c.location) }
|
||||||
|
|
||||||
// AddDuration ajoute une durée.
|
// AddDuration ajoute une durée.
|
||||||
|
@ -369,11 +381,12 @@ func (c Clock) In(l *time.Location) Clock {
|
||||||
return NewClockFromTime(c.ToTime().In(l))
|
return NewClockFromTime(c.ToTime().In(l))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToTimezone retourne l’heure dans le fuseau horaire indiqué.
|
// InTZ agit comme In mais en fournissant le fuseau horaire sous forme
|
||||||
func (c Clock) ToTimezone(tz string) Clock { return c.In(timezone(tz)) }
|
// de chaîne de caractères.
|
||||||
|
func (c Clock) inTZ(tz string) Clock { return c.In(timezone(tz)) }
|
||||||
|
|
||||||
// Location retourne le fuseau horaire.
|
// TZ retourne le fuseau horaire.
|
||||||
func (c Clock) Location() *time.Location { return c.location }
|
func (c Clock) TZ() *time.Location { return c.location }
|
||||||
|
|
||||||
// IsDST retourne vrai si le fuseau horaire est à l’heure d’été.
|
// IsDST retourne vrai si le fuseau horaire est à l’heure d’été.
|
||||||
func (c Clock) IsDST() bool { return c.dst(c.location) }
|
func (c Clock) IsDST() bool { return c.dst(c.location) }
|
||||||
|
@ -398,13 +411,25 @@ func (c1 Clock) Ge(c2 Clock) bool { return c1.Compare(c2) >= 0 }
|
||||||
func (c1 Clock) Lt(c2 Clock) bool { return c1.Compare(c2) < 0 }
|
func (c1 Clock) Lt(c2 Clock) bool { return c1.Compare(c2) < 0 }
|
||||||
func (c1 Clock) Le(c2 Clock) bool { return c1.Compare(c2) <= 0 }
|
func (c1 Clock) Le(c2 Clock) bool { return c1.Compare(c2) <= 0 }
|
||||||
|
|
||||||
|
// IsNow retourne vrai si l’horloge est à l’heure actuelle.
|
||||||
func (c Clock) IsNow() bool { return c.Eq(c.Now()) }
|
func (c Clock) IsNow() bool { return c.Eq(c.Now()) }
|
||||||
|
|
||||||
|
// IsPast retourne vrai si l’horloge est située dans le passé.
|
||||||
func (c Clock) IsPast() bool { return c.Lt(c.Now()) }
|
func (c Clock) IsPast() bool { return c.Lt(c.Now()) }
|
||||||
|
|
||||||
|
// IsFuture retourne vrai si l’horloge est située dans le futur.
|
||||||
func (c Clock) IsFuture() bool { return c.Gt(c.Now()) }
|
func (c Clock) IsFuture() bool { return c.Gt(c.Now()) }
|
||||||
|
|
||||||
|
// DiffInMillis retourne c1 - c2 en millisecondes.
|
||||||
func (c1 Clock) DiffInMillis(c2 Clock) int { return c1.subV(c2.clock) }
|
func (c1 Clock) DiffInMillis(c2 Clock) int { return c1.subV(c2.clock) }
|
||||||
|
|
||||||
|
// DiffInSeconds retourne c1 - c2 en secondes.
|
||||||
func (c1 Clock) DiffInSeconds(c2 Clock) int { return c1.subS(c2.clock) }
|
func (c1 Clock) DiffInSeconds(c2 Clock) int { return c1.subS(c2.clock) }
|
||||||
|
|
||||||
|
// DiffInMinutes retourne c1 - c2 en minutes.
|
||||||
func (c1 Clock) DiffInMinutes(c2 Clock) int { return c1.subI(c2.clock) }
|
func (c1 Clock) DiffInMinutes(c2 Clock) int { return c1.subI(c2.clock) }
|
||||||
|
|
||||||
|
// DiffInHours retourne c1 - c2 en heures.
|
||||||
func (c1 Clock) DiffInHours(c2 Clock) int { return c1.subH(c2.clock) }
|
func (c1 Clock) DiffInHours(c2 Clock) int { return c1.subH(c2.clock) }
|
||||||
|
|
||||||
// Format retourne une représentation de l’heure au format spécifié.
|
// Format retourne une représentation de l’heure au format spécifié.
|
||||||
|
|
|
@ -103,17 +103,17 @@ const (
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
// représentation de l’unité sous forme de caractère
|
// Représentation de l’unité sous forme de caractères
|
||||||
unitToByte = map[Unit]byte{
|
unitToString = map[Unit]string{
|
||||||
NoUnit: 0,
|
NoUnit: "",
|
||||||
Millisecond: 'N',
|
Millisecond: "ms",
|
||||||
Second: 'S',
|
Second: "s",
|
||||||
Minute: 'M',
|
Minute: "m",
|
||||||
Hour: 'H',
|
Hour: "h",
|
||||||
Day: 'd',
|
Day: "J",
|
||||||
Week: 'w',
|
Week: "S",
|
||||||
Month: 'm',
|
Month: "M",
|
||||||
Year: 'y',
|
Year: "A",
|
||||||
}
|
}
|
||||||
|
|
||||||
maskDate = map[string]date{
|
maskDate = map[string]date{
|
||||||
|
|
|
@ -205,12 +205,14 @@ func newDate(t date, l *time.Location) Date {
|
||||||
return DateNil()
|
return DateNil()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDate retourne la date dans le fuseau horaire demandé.
|
// NewDate retourne la date à partir de l’année, du mois et du jour.
|
||||||
|
// Si le fuseau horaire tz est renseigné, c’est le fuseau utilisé,
|
||||||
|
// sinon, c’est le fuseau par défaut.
|
||||||
func NewDate(y int, m, d uint, tz ...string) Date {
|
func NewDate(y int, m, d uint, tz ...string) Date {
|
||||||
return newDate(newD(y, m, d), timezone(tz...))
|
return newDate(newD(y, m, d), timezone(tz...))
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDateFromTime retourne la date à partir d’une date Go.
|
// NewDateFromTime retourne la date à partir d’une date Go t.
|
||||||
func NewDateFromTime(t time.Time) Date {
|
func NewDateFromTime(t time.Time) Date {
|
||||||
y, m, d := t.Date()
|
y, m, d := t.Date()
|
||||||
l := t.Location()
|
l := t.Location()
|
||||||
|
@ -222,6 +224,7 @@ func NewDateFromTime(t time.Time) Date {
|
||||||
// la date est placée dans le fuseau horaire indiqué.
|
// la date est placée dans le fuseau horaire indiqué.
|
||||||
func DateNow(tz ...string) Date { return NewDateFromTime(now(tz...)) }
|
func DateNow(tz ...string) Date { return NewDateFromTime(now(tz...)) }
|
||||||
|
|
||||||
|
// Now retourne la date actuelle dans le même fuseau horaire que t.
|
||||||
func (t Date) Now() Date { return DateNow(t.location.String()) }
|
func (t Date) Now() Date { return DateNow(t.location.String()) }
|
||||||
|
|
||||||
// DateGuess retourne la date à partir de e en essayant de deviner le format.
|
// DateGuess retourne la date à partir de e en essayant de deviner le format.
|
||||||
|
@ -233,7 +236,7 @@ func DateGuess(e string, tz ...string) Date {
|
||||||
return DateNil()
|
return DateNil()
|
||||||
}
|
}
|
||||||
|
|
||||||
// DateParse retourne la date à partir de v en spécifiant le format f.
|
// DateParse retourne la date à partir de e en spécifiant le format f.
|
||||||
func DateParse(e, f string, tz ...string) Date {
|
func DateParse(e, f string, tz ...string) Date {
|
||||||
if t, ok := parse(e, f).Get(); ok {
|
if t, ok := parse(e, f).Get(); ok {
|
||||||
return NewDateFromTime(t)
|
return NewDateFromTime(t)
|
||||||
|
@ -263,7 +266,7 @@ func (t Date) YearDay() uint { return t.yd() }
|
||||||
// WeekDay retourne le jour de la semaine (de 0 à 6 en commençant par dimanche).
|
// WeekDay retourne le jour de la semaine (de 0 à 6 en commençant par dimanche).
|
||||||
func (t Date) WeekDay() uint { return t.wd(t.location) }
|
func (t Date) WeekDay() uint { return t.wd(t.location) }
|
||||||
|
|
||||||
// IsBissextil retourn vrai si la date est dans une année bissextile.
|
// IsBissextil retourne vrai si la date est dans une année bissextile.
|
||||||
func (t Date) IsBissextil() bool { return t.b() }
|
func (t Date) IsBissextil() bool { return t.b() }
|
||||||
|
|
||||||
// DaysInYear retourne le nombre de jours dans l’année.
|
// DaysInYear retourne le nombre de jours dans l’année.
|
||||||
|
@ -290,7 +293,7 @@ func (t Date) AddYear(y int) Date { return newDate(t.addY(y), t.location) }
|
||||||
// AddMonth incrémente le mois.
|
// AddMonth incrémente le mois.
|
||||||
func (t Date) AddMonth(m int) Date { return newDate(t.addM(m), t.location) }
|
func (t Date) AddMonth(m int) Date { return newDate(t.addM(m), t.location) }
|
||||||
|
|
||||||
// AddWeek incrémente la date de week semaines.
|
// AddWeek incrémente la date de w semaines.
|
||||||
func (t Date) AddWeek(w int) Date { return newDate(t.addW(w), t.location) }
|
func (t Date) AddWeek(w int) Date { return newDate(t.addW(w), t.location) }
|
||||||
|
|
||||||
// AddDay incrémente le jour.
|
// AddDay incrémente le jour.
|
||||||
|
@ -314,7 +317,7 @@ func (t Date) EndOfMonth() Date { return newDate(t.eM(), t.location) }
|
||||||
// BeginOfWeek retourne la date du premier jour de la semaine (ie. lundi).
|
// BeginOfWeek retourne la date du premier jour de la semaine (ie. lundi).
|
||||||
func (t Date) BeginOfWeek() Date { return newDate(t.bW(t.location), t.location) }
|
func (t Date) BeginOfWeek() Date { return newDate(t.bW(t.location), t.location) }
|
||||||
|
|
||||||
// EndOfWeek retourne la date du dernier jour de la semaine.
|
// EndOfWeek retourne la date du dernier jour de la semaine (e. dimanche).
|
||||||
func (t Date) EndOfWeek() Date { return newDate(t.eW(t.location), t.location) }
|
func (t Date) EndOfWeek() Date { return newDate(t.eW(t.location), t.location) }
|
||||||
|
|
||||||
// ToTime convertit la date en date de type time.Time.
|
// ToTime convertit la date en date de type time.Time.
|
||||||
|
@ -329,11 +332,12 @@ func (t Date) In(l *time.Location) Date {
|
||||||
return NewDateFromTime(t.t(t.location).In(l))
|
return NewDateFromTime(t.t(t.location).In(l))
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToTimezone retourne la date dans le fuseau horaire indiqué.
|
// InTZ agit comme In mais en fournissant le fuseau horaire sous forme
|
||||||
|
// de chaîne de caractères.
|
||||||
func (t Date) ToTimezone(tz string) Date { return t.In(timezone(tz)) }
|
func (t Date) ToTimezone(tz string) Date { return t.In(timezone(tz)) }
|
||||||
|
|
||||||
// Location retourne le fuseau horaire.
|
// TZ retourne le fuseau horaire.
|
||||||
func (t Date) Location() *time.Location { return t.location }
|
func (t Date) TZ() *time.Location { return t.location }
|
||||||
|
|
||||||
// IsDST retourne vrai si le fuseau horaire est à l’heure d’été.
|
// IsDST retourne vrai si le fuseau horaire est à l’heure d’été.
|
||||||
func (t Date) IsDST() bool { return t.dst(t.location) }
|
func (t Date) IsDST() bool { return t.dst(t.location) }
|
||||||
|
@ -341,10 +345,11 @@ func (t Date) IsDST() bool { return t.dst(t.location) }
|
||||||
// Timestamp retourne le timestamp en secondes.
|
// Timestamp retourne le timestamp en secondes.
|
||||||
func (t Date) Timestamp() int64 { return t.ts(t.location) }
|
func (t Date) Timestamp() int64 { return t.ts(t.location) }
|
||||||
|
|
||||||
// TimestampMilli retourne le timestamp en secondes.
|
// TimestampMilli retourne le timestamp en millisecondes.
|
||||||
func (t Date) TimestampMilli() int64 { return t.tv(t.location) }
|
func (t Date) TimestampMilli() int64 { return t.tv(t.location) }
|
||||||
|
|
||||||
// Compare compare 2 dates.
|
// Compare compare 2 dates.
|
||||||
|
// La comparaison s’effectue après normalisation, ie. dans le même fuseau horaire.
|
||||||
func (t1 Date) Compare(t2 Date) int { return t1.cmp(t2.In(t1.location).date) }
|
func (t1 Date) Compare(t2 Date) int { return t1.cmp(t2.In(t1.location).date) }
|
||||||
|
|
||||||
func (t1 Date) Eq(t2 Date) bool { return t1.Compare(t2) == 0 }
|
func (t1 Date) Eq(t2 Date) bool { return t1.Compare(t2) == 0 }
|
||||||
|
@ -354,21 +359,33 @@ func (t1 Date) Ge(t2 Date) bool { return t1.Compare(t2) >= 0 }
|
||||||
func (t1 Date) Lt(t2 Date) bool { return t1.Compare(t2) < 0 }
|
func (t1 Date) Lt(t2 Date) bool { return t1.Compare(t2) < 0 }
|
||||||
func (t1 Date) Le(t2 Date) bool { return t1.Compare(t2) <= 0 }
|
func (t1 Date) Le(t2 Date) bool { return t1.Compare(t2) <= 0 }
|
||||||
|
|
||||||
|
// IsNow retourne vrai si la date est située aujourd’hui.
|
||||||
func (t Date) IsNow() bool { return t.Eq(t.Now()) }
|
func (t Date) IsNow() bool { return t.Eq(t.Now()) }
|
||||||
|
|
||||||
|
// IsPast retourne vrai si la date est situé dans le passé.
|
||||||
func (t Date) IsPast() bool { return t.Lt(t.Now()) }
|
func (t Date) IsPast() bool { return t.Lt(t.Now()) }
|
||||||
|
|
||||||
|
// IsFuture retourne vrai si la date est situé dans le futur.
|
||||||
func (t Date) IsFuture() bool { return t.Gt(t.Now()) }
|
func (t Date) IsFuture() bool { return t.Gt(t.Now()) }
|
||||||
|
|
||||||
func (t1 Date) diff(t2 Date) (dy, dm, dd int) {
|
func (t1 Date) diff(t2 Date) (dy, dm, dd int) {
|
||||||
return t1.y() - t2.y(), int(t1.m()) - int(t2.m()), int(t1.d()) - int(t2.d())
|
return t1.y() - t2.y(), int(t1.m()) - int(t2.m()), int(t1.d()) - int(t2.d())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DiffInDays retourne t1 - t2 en jours.
|
||||||
func (t1 Date) DiffInDays(t2 Date) int { return t1.subD(t2.date, t1.location, t2.location) }
|
func (t1 Date) DiffInDays(t2 Date) int { return t1.subD(t2.date, t1.location, t2.location) }
|
||||||
|
|
||||||
|
// DiffInWeeks retourne t1 - t2 en semaines.
|
||||||
func (t1 Date) DiffInWeeks(t2 Date) int { return t1.subW(t2.date, t1.location, t2.location) }
|
func (t1 Date) DiffInWeeks(t2 Date) int { return t1.subW(t2.date, t1.location, t2.location) }
|
||||||
|
|
||||||
|
// DiffInMonths retourne t1 - t2 en mois.
|
||||||
func (t1 Date) DiffInMonths(t2 Date) int { return t1.subM(t2.date) }
|
func (t1 Date) DiffInMonths(t2 Date) int { return t1.subM(t2.date) }
|
||||||
|
|
||||||
|
// DiffInYears retourne t1 - t2 en années.
|
||||||
func (t1 Date) DiffInYears(t2 Date) int { return t1.subY(t2.date) }
|
func (t1 Date) DiffInYears(t2 Date) int { return t1.subY(t2.date) }
|
||||||
|
|
||||||
// Format retourne une représentation de la date au format spécifié.
|
// Format retourne une représentation de la date au format spécifié.
|
||||||
func (t Date) Format(format string) string { return t.f(format, t.location) }
|
func (t Date) Format(f string) string { return t.f(f, t.location) }
|
||||||
|
|
||||||
// String retourne la date au format Y-m-d.
|
// String retourne la date au format Y-m-d.
|
||||||
func (t Date) String() string { return t.str(t.location) }
|
func (t Date) String() string { return t.str(t.location) }
|
||||||
|
|
|
@ -176,7 +176,7 @@ func (dt datetime) f(f string, l *time.Location) string {
|
||||||
}
|
}
|
||||||
func (dt datetime) str(l *time.Location) string { return dt.f("Y-m-d", l) }
|
func (dt datetime) str(l *time.Location) string { return dt.f("Y-m-d", l) }
|
||||||
|
|
||||||
// DateTime représente une indication de temps.
|
// DateTime représente une indication de temps (date + heure).
|
||||||
type DateTime struct {
|
type DateTime struct {
|
||||||
datetime
|
datetime
|
||||||
location *time.Location
|
location *time.Location
|
||||||
|
@ -193,7 +193,10 @@ func initDT(dt datetime, l *time.Location) DateTime {
|
||||||
return DateTime{dt, l}
|
return DateTime{dt, l}
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDateTime retourne un temps dans le fuseau horaire par défaut.
|
// NewDateTime retourne un temps dans le fuseau horaire par défaut avec :
|
||||||
|
// - y, m, d : année, mois, jour
|
||||||
|
// - h, i : heure, minute,
|
||||||
|
// - args : seconde, puis milliseconde.
|
||||||
// La précision est calculée automatiquement suivant que la seconde et la milliseconde sont indiquées.
|
// La précision est calculée automatiquement suivant que la seconde et la milliseconde sont indiquées.
|
||||||
func NewDateTime(y int, m, d, h, i uint, args ...uint) DateTime {
|
func NewDateTime(y int, m, d, h, i uint, args ...uint) DateTime {
|
||||||
return initDT0(newD(y, m, d), newC0(h, i, args...), DefaultTZ)
|
return initDT0(newD(y, m, d), newC0(h, i, args...), DefaultTZ)
|
||||||
|
@ -209,7 +212,9 @@ func NewDateTimeTZ(tz string, y int, m, d, h, i uint, args ...uint) DateTime {
|
||||||
return dt
|
return dt
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewDateTimeFromTime retourne le temps à partir d’une date Go.
|
// NewDateTimeFromTime retourne le temps à partir d’une date Go t.
|
||||||
|
// Si la précision p est fournie, c’est la précision utilisée,
|
||||||
|
// sinon, c’est la précision à la milliseconde.
|
||||||
func NewDateTimeFromTime(t time.Time, p ...Precision) DateTime {
|
func NewDateTimeFromTime(t time.Time, p ...Precision) DateTime {
|
||||||
var (
|
var (
|
||||||
pp = PrecisionMillisecond
|
pp = PrecisionMillisecond
|
||||||
|
@ -226,15 +231,16 @@ func NewDateTimeFromTime(t time.Time, p ...Precision) DateTime {
|
||||||
return initDT0(newD(y, uint(m+1), uint(d)), newC(ms(uint(h), uint(i), uint(s), uint(v)), pp), l)
|
return initDT0(newD(y, uint(m+1), uint(d)), newC(ms(uint(h), uint(i), uint(s), uint(v)), pp), l)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DateTimeNow retourne la date actuelle. Si tz est renseignée,
|
// DateTimeNow retourne le temps à la précision p. Si tz est renseignée,
|
||||||
// la date est placée dans le fuseau horaire indiqué.
|
// la date est placée dans le fuseau horaire indiqué.
|
||||||
func DateTimeNow(p Precision, tz ...string) DateTime {
|
func DateTimeNow(p Precision, tz ...string) DateTime {
|
||||||
return NewDateTimeFromTime(now(tz...), p)
|
return NewDateTimeFromTime(now(tz...), p)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now retourne le temps actuel avec la précision et le fuseau horaire de dt.
|
||||||
func (dt DateTime) Now() DateTime { return DateTimeNow(dt.p(), dt.location.String()) }
|
func (dt DateTime) Now() DateTime { return DateTimeNow(dt.p(), dt.location.String()) }
|
||||||
|
|
||||||
// DateTimeGuess retourne la date à partir de e en essayant de deviner le format.
|
// DateTimeGuess retourne le temps à partir de e en essayant de deviner le format.
|
||||||
func DateTimeGuess(p Precision, e string, tz ...string) DateTime {
|
func DateTimeGuess(p Precision, e string, tz ...string) DateTime {
|
||||||
if t, ok := guess(e, tz...).Get(); ok {
|
if t, ok := guess(e, tz...).Get(); ok {
|
||||||
return NewDateTimeFromTime(t, p)
|
return NewDateTimeFromTime(t, p)
|
||||||
|
@ -243,7 +249,7 @@ func DateTimeGuess(p Precision, e string, tz ...string) DateTime {
|
||||||
return DateTimeNil()
|
return DateTimeNil()
|
||||||
}
|
}
|
||||||
|
|
||||||
// DateTimeParse retourne la date à partir de e en spécifiant le format f.
|
// DateTimeParse retourne le temps à partir de e en spécifiant le format f.
|
||||||
func DateTimeParse(p Precision, e, f string, tz ...string) DateTime {
|
func DateTimeParse(p Precision, e, f string, tz ...string) DateTime {
|
||||||
if t, ok := parse(e, f, tz...).Get(); ok {
|
if t, ok := parse(e, f, tz...).Get(); ok {
|
||||||
return NewDateTimeFromTime(t, p)
|
return NewDateTimeFromTime(t, p)
|
||||||
|
@ -255,7 +261,7 @@ func DateTimeParse(p Precision, e, f string, tz ...string) DateTime {
|
||||||
// Precision retourne la précision de l’heure.
|
// Precision retourne la précision de l’heure.
|
||||||
func (dt DateTime) Precision() Precision { return dt.p() }
|
func (dt DateTime) Precision() Precision { return dt.p() }
|
||||||
|
|
||||||
// IsNil retourne vrai si la date est nulle.
|
// IsNil retourne vrai si le temps est nul.
|
||||||
func (dt DateTime) IsNil() bool { return !dt.valid() }
|
func (dt DateTime) IsNil() bool { return !dt.valid() }
|
||||||
|
|
||||||
// Year retourne l’année.
|
// Year retourne l’année.
|
||||||
|
@ -264,7 +270,7 @@ func (dt DateTime) Year() int { return dt.y() }
|
||||||
// Month retourne le mois.
|
// Month retourne le mois.
|
||||||
func (dt DateTime) Month() uint { return dt.m() }
|
func (dt DateTime) Month() uint { return dt.m() }
|
||||||
|
|
||||||
// Day retourne le .
|
// Day retourne le jour.
|
||||||
func (dt DateTime) Day() uint { return dt.d() }
|
func (dt DateTime) Day() uint { return dt.d() }
|
||||||
|
|
||||||
// Hour retourne l’heure.
|
// Hour retourne l’heure.
|
||||||
|
@ -318,32 +324,32 @@ func (dt DateTime) ToClock() Clock { return newClock(dt.clock, dt.location) }
|
||||||
// ToDateClock sépare la partie date et la partie heure.
|
// ToDateClock sépare la partie date et la partie heure.
|
||||||
func (dt DateTime) ToDateClock() (Date, Clock) { return dt.ToDate(), dt.ToClock() }
|
func (dt DateTime) ToDateClock() (Date, Clock) { return dt.ToDate(), dt.ToClock() }
|
||||||
|
|
||||||
// SetYear modifie l’année.
|
// SetYear modifie l’année, et facultativement, le mois, le jour, etc.
|
||||||
func (dt DateTime) SetYear(y int, args ...uint) DateTime {
|
func (dt DateTime) SetYear(y int, args ...uint) DateTime {
|
||||||
return initDT(dt.setY(y, args...), dt.location)
|
return initDT(dt.setY(y, args...), dt.location)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMonth modifie le mois.
|
// SetMonth modifie le mois et facultativement le jour, l’heure, etc.
|
||||||
func (dt DateTime) SetMonth(m uint, args ...uint) DateTime {
|
func (dt DateTime) SetMonth(m uint, args ...uint) DateTime {
|
||||||
return initDT(dt.setM(m, args...), dt.location)
|
return initDT(dt.setM(m, args...), dt.location)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetDay modifie le jour.
|
// SetDay modifie le jour et facultativement l’heure, la minute, etc..
|
||||||
func (dt DateTime) SetDay(d uint, args ...uint) DateTime {
|
func (dt DateTime) SetDay(d uint, args ...uint) DateTime {
|
||||||
return initDT(dt.setD(d, args...), dt.location)
|
return initDT(dt.setD(d, args...), dt.location)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetHour modifie l’heure.
|
// SetHour modifie l’heure et facultativement la minute, la seconde, etc.
|
||||||
func (dt DateTime) SetHour(h uint, args ...uint) DateTime {
|
func (dt DateTime) SetHour(h uint, args ...uint) DateTime {
|
||||||
return initDT(dt.setH(h, args...), dt.location)
|
return initDT(dt.setH(h, args...), dt.location)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetMinute modifie la minute.
|
// SetMinute modifie la minute et facultativement la seconde et la milliseconde.
|
||||||
func (dt DateTime) SetMinute(i uint, args ...uint) DateTime {
|
func (dt DateTime) SetMinute(i uint, args ...uint) DateTime {
|
||||||
return initDT(dt.setI(i, args...), dt.location)
|
return initDT(dt.setI(i, args...), dt.location)
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetSecond modifie la seconde.
|
// SetSecond modifie la seconde et facultativement la milliseconde.
|
||||||
func (dt DateTime) SetSecond(s uint, args ...uint) DateTime {
|
func (dt DateTime) SetSecond(s uint, args ...uint) DateTime {
|
||||||
return initDT(dt.setS(s, args...), dt.location)
|
return initDT(dt.setS(s, args...), dt.location)
|
||||||
}
|
}
|
||||||
|
@ -395,52 +401,52 @@ func (dt DateTime) AddMilli(v int) DateTime { return initDT(dt.addV(v), dt.locat
|
||||||
// AddDuration incrémente une durée.
|
// AddDuration incrémente une durée.
|
||||||
func (dt DateTime) AddDuration(dd Duration) DateTime { return initDT(dt.addDD(dd), dt.location) }
|
func (dt DateTime) AddDuration(dd Duration) DateTime { return initDT(dt.addDD(dd), dt.location) }
|
||||||
|
|
||||||
// BeginOfYear retourne la date en début d’année.
|
// BeginOfYear retourne le temps en début d’année au début du jour.
|
||||||
func (dt DateTime) BeginOfYear() DateTime { return initDT(dt.bY(), dt.location) }
|
func (dt DateTime) BeginOfYear() DateTime { return initDT(dt.bY(), dt.location) }
|
||||||
|
|
||||||
// EndOfYear retourne la date en fin d’année.
|
// EndOfYear retourne le temps en fin d’année à la fin du jour.
|
||||||
func (dt DateTime) EndOfYear() DateTime { return initDT(dt.eY(), dt.location) }
|
func (dt DateTime) EndOfYear() DateTime { return initDT(dt.eY(), dt.location) }
|
||||||
|
|
||||||
// BeginOfMonth retourne la date en début de mois.
|
// BeginOfMonth retourne le temps en début de mois au début du jour.
|
||||||
func (dt DateTime) BeginOfMonth() DateTime { return initDT(dt.bM(), dt.location) }
|
func (dt DateTime) BeginOfMonth() DateTime { return initDT(dt.bM(), dt.location) }
|
||||||
|
|
||||||
// EndOfMonth retourne la date en fin de mois.
|
// EndOfMonth retourne le temps en fin de mois à la fin du jour.
|
||||||
func (dt DateTime) EndOfMonth() DateTime { return initDT(dt.eM(), dt.location) }
|
func (dt DateTime) EndOfMonth() DateTime { return initDT(dt.eM(), dt.location) }
|
||||||
|
|
||||||
// BeginOfWeek retourne la date en début de semaine.
|
// BeginOfWeek retourne le temps en début de semaine au début du jour.
|
||||||
func (dt DateTime) BeginOfWeek() DateTime { return initDT(dt.bW(dt.location), dt.location) }
|
func (dt DateTime) BeginOfWeek() DateTime { return initDT(dt.bW(dt.location), dt.location) }
|
||||||
|
|
||||||
// EndOfWeek retourne la date en fin de semaine.
|
// EndOfWeek retourne le temps en fin de semaine à la fin du jour.
|
||||||
func (dt DateTime) EndOfWeek() DateTime { return initDT(dt.eW(dt.location), dt.location) }
|
func (dt DateTime) EndOfWeek() DateTime { return initDT(dt.eW(dt.location), dt.location) }
|
||||||
|
|
||||||
// BeginOfDay retourne la date en début de jour.
|
// BeginOfDay retourne le temps en début de jour.
|
||||||
func (dt DateTime) BeginOfDay() DateTime { return initDT(dt.bD(), dt.location) }
|
func (dt DateTime) BeginOfDay() DateTime { return initDT(dt.bD(), dt.location) }
|
||||||
|
|
||||||
// EndOfDay retourne la date en fin de jour.
|
// EndOfDay retourne le temps en fin de jour.
|
||||||
func (dt DateTime) EndOfDay() DateTime { return initDT(dt.eD(), dt.location) }
|
func (dt DateTime) EndOfDay() DateTime { return initDT(dt.eD(), dt.location) }
|
||||||
|
|
||||||
// BeginOfHour retourne la date en début d’heure.
|
// BeginOfHour retourne le temps en début d’heure.
|
||||||
func (dt DateTime) BeginOfHour() DateTime { return initDT(dt.bH(), dt.location) }
|
func (dt DateTime) BeginOfHour() DateTime { return initDT(dt.bH(), dt.location) }
|
||||||
|
|
||||||
// EndOfHour retourne la date en fin d’heure.
|
// EndOfHour retourne le temps en fin d’heure.
|
||||||
func (dt DateTime) EndOfHour() DateTime { return initDT(dt.eH(), dt.location) }
|
func (dt DateTime) EndOfHour() DateTime { return initDT(dt.eH(), dt.location) }
|
||||||
|
|
||||||
// BeginOfMinute retourne la date en début de minute.
|
// BeginOfMinute retourne le temps en début de minute.
|
||||||
func (dt DateTime) BeginOfMinute() DateTime { return initDT(dt.bI(), dt.location) }
|
func (dt DateTime) BeginOfMinute() DateTime { return initDT(dt.bI(), dt.location) }
|
||||||
|
|
||||||
// EndOfMinute retourne la date en fin de minute.
|
// EndOfMinute retourne le temps en fin de minute.
|
||||||
func (dt DateTime) EndOfMinute() DateTime { return initDT(dt.eI(), dt.location) }
|
func (dt DateTime) EndOfMinute() DateTime { return initDT(dt.eI(), dt.location) }
|
||||||
|
|
||||||
// BeginOfSecond retourne la date en début de seconde.
|
// BeginOfSecond retourne le temps en début de seconde.
|
||||||
func (dt DateTime) BeginOfSecond() DateTime { return initDT(dt.bS(), dt.location) }
|
func (dt DateTime) BeginOfSecond() DateTime { return initDT(dt.bS(), dt.location) }
|
||||||
|
|
||||||
// EndOfSecond retourne la date en fin de seconde.
|
// EndOfSecond retourne le temps en fin de seconde.
|
||||||
func (dt DateTime) EndOfSecond() DateTime { return initDT(dt.eS(), dt.location) }
|
func (dt DateTime) EndOfSecond() DateTime { return initDT(dt.eS(), dt.location) }
|
||||||
|
|
||||||
// ToTime retourne la date dans le fuseau horaire indiqué.
|
// ToTime retourne le temps dans le fuseau horaire indiqué.
|
||||||
func (dt DateTime) ToTime() time.Time { return dt.t(dt.location) }
|
func (dt DateTime) ToTime() time.Time { return dt.t(dt.location) }
|
||||||
|
|
||||||
// In retourne la date dans le fuseau horaire indiqué.
|
// In retourne le temps dans le fuseau horaire indiqué.
|
||||||
func (dt DateTime) In(l *time.Location) DateTime {
|
func (dt DateTime) In(l *time.Location) DateTime {
|
||||||
if dt.IsNil() {
|
if dt.IsNil() {
|
||||||
return DateTimeNil()
|
return DateTimeNil()
|
||||||
|
@ -449,11 +455,12 @@ func (dt DateTime) In(l *time.Location) DateTime {
|
||||||
return NewDateTimeFromTime(dt.ToTime().In(l), dt.p())
|
return NewDateTimeFromTime(dt.ToTime().In(l), dt.p())
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToTimezone retourne la date dans le fuseau horaire indiqué.
|
// InTZ agit comme In mais en fournissant le fuseau horaire sous forme
|
||||||
func (dt DateTime) ToTimezone(tz string) DateTime { return dt.In(timezone(tz)) }
|
// de chaîne de caractères.
|
||||||
|
func (dt DateTime) InTZ(tz string) DateTime { return dt.In(timezone(tz)) }
|
||||||
|
|
||||||
// Location retourne le fuseau horaire.
|
// TZ retourne le fuseau horaire.
|
||||||
func (dt DateTime) Location() *time.Location { return dt.location }
|
func (dt DateTime) TZ() *time.Location { return dt.location }
|
||||||
|
|
||||||
// IsDST retourne vrai si le fuseau horaire est à l’heure d’été.
|
// IsDST retourne vrai si le fuseau horaire est à l’heure d’été.
|
||||||
func (dt DateTime) IsDST() bool { return dt.dst(dt.location) }
|
func (dt DateTime) IsDST() bool { return dt.dst(dt.location) }
|
||||||
|
@ -464,7 +471,7 @@ func (dt DateTime) TimeStamp() int64 { return dt.ts(dt.location) }
|
||||||
// TimestampMilli retourne le timestamp en millisecondes.
|
// TimestampMilli retourne le timestamp en millisecondes.
|
||||||
func (dt DateTime) TimeStampMilli() int64 { return dt.tv(dt.location) }
|
func (dt DateTime) TimeStampMilli() int64 { return dt.tv(dt.location) }
|
||||||
|
|
||||||
// Compare compare 2 dates.
|
// Compare compare 2 temps après normalisation du fuseau horaire et de la précision.
|
||||||
func (dt1 DateTime) Compare(dt2 DateTime) int { return dt1.cmp(dt2.datetime) }
|
func (dt1 DateTime) Compare(dt2 DateTime) int { return dt1.cmp(dt2.datetime) }
|
||||||
|
|
||||||
func (dt1 DateTime) Eq(dt2 DateTime) bool { return dt1.Compare(dt2) == 0 }
|
func (dt1 DateTime) Eq(dt2 DateTime) bool { return dt1.Compare(dt2) == 0 }
|
||||||
|
@ -474,11 +481,16 @@ func (dt1 DateTime) Ge(dt2 DateTime) bool { return dt1.Compare(dt2) >= 0 }
|
||||||
func (dt1 DateTime) Lt(dt2 DateTime) bool { return dt1.Compare(dt2) < 0 }
|
func (dt1 DateTime) Lt(dt2 DateTime) bool { return dt1.Compare(dt2) < 0 }
|
||||||
func (dt1 DateTime) Le(dt2 DateTime) bool { return dt1.Compare(dt2) <= 0 }
|
func (dt1 DateTime) Le(dt2 DateTime) bool { return dt1.Compare(dt2) <= 0 }
|
||||||
|
|
||||||
|
// IsNow retourne vrai si le temps est le temps actuel.
|
||||||
func (dt DateTime) IsNow() bool { return dt.Eq(dt.Now()) }
|
func (dt DateTime) IsNow() bool { return dt.Eq(dt.Now()) }
|
||||||
|
|
||||||
|
// IsPast retourne vrai si le temps est situé dans le passé.
|
||||||
func (dt DateTime) IsPast() bool { return dt.Lt(dt.Now()) }
|
func (dt DateTime) IsPast() bool { return dt.Lt(dt.Now()) }
|
||||||
|
|
||||||
|
// IsPast retourne vrai si le temps est situé dans le futur.
|
||||||
func (dt DateTime) IsFuture() bool { return dt.Gt(dt.Now()) }
|
func (dt DateTime) IsFuture() bool { return dt.Gt(dt.Now()) }
|
||||||
|
|
||||||
// DiffInMills retourne dt1-dt2 en millisecondes.
|
// DiffInMills retourne dt1 - dt2 en millisecondes.
|
||||||
func (dt1 DateTime) DiffInMillis(dt2 DateTime) int {
|
func (dt1 DateTime) DiffInMillis(dt2 DateTime) int {
|
||||||
return dt1.subV(dt2.datetime, dt1.location, dt2.location)
|
return dt1.subV(dt2.datetime, dt1.location, dt2.location)
|
||||||
}
|
}
|
||||||
|
@ -514,9 +526,9 @@ func (dt1 DateTime) DiffInMonths(dt2 DateTime) int { return dt1.subM(dt2.datetim
|
||||||
// DiffInYears retourn dt1 - dt2 en années.
|
// DiffInYears retourn dt1 - dt2 en années.
|
||||||
func (dt1 DateTime) DiffInYears(dt2 DateTime) int { return dt1.subY(dt2.datetime) }
|
func (dt1 DateTime) DiffInYears(dt2 DateTime) int { return dt1.subY(dt2.datetime) }
|
||||||
|
|
||||||
// Format retourne une représentation de la date au format spécifié.
|
// Format retourne une représentation du temps au format spécifié.
|
||||||
func (dt DateTime) Format(f string) string { return dt.f(f, dt.location) }
|
func (dt DateTime) Format(f string) string { return dt.f(f, dt.location) }
|
||||||
|
|
||||||
// String retourne une représentation de la date au format 'Y-m-d H:iT',
|
// String retourne une représentation du temps au format 'Y-m-d H:iT',
|
||||||
// 'Y-m-d H:i:sT' ou 'Y-m-d H:i:s.vT' suivant la précision.
|
// 'Y-m-d H:i:sT' ou 'Y-m-d H:i:s.vT' suivant la précision.
|
||||||
func (dt DateTime) String() string { return dt.str(dt.location) }
|
func (dt DateTime) String() string { return dt.str(dt.location) }
|
||||||
|
|
|
@ -2,11 +2,15 @@ package datetime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
|
"strconv"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Unit est une unité de durée.
|
// Unit est une unité de durée.
|
||||||
type Unit uint
|
type Unit uint
|
||||||
|
|
||||||
|
func (u Unit) String() string { return unitToString[u] }
|
||||||
|
|
||||||
// Duration est une durée entre deux repères de temps.
|
// Duration est une durée entre deux repères de temps.
|
||||||
type Duration int
|
type Duration int
|
||||||
|
|
||||||
|
@ -19,6 +23,26 @@ func NewDuration(value int, unit Unit) Duration {
|
||||||
return (Duration(value) << bitsUnit) | Duration(unit)
|
return (Duration(value) << bitsUnit) | Duration(unit)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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)
|
||||||
|
}
|
||||||
|
|
||||||
// Value retourne la valeur de la durée, sans l’unité.
|
// Value retourne la valeur de la durée, sans l’unité.
|
||||||
func (d Duration) Value() int { return int(d >> bitsUnit) }
|
func (d Duration) Value() int { return int(d >> bitsUnit) }
|
||||||
|
|
||||||
|
@ -51,5 +75,5 @@ func (d Duration) String() string {
|
||||||
|
|
||||||
v, u := d.Value(), d.Unit()
|
v, u := d.Value(), d.Unit()
|
||||||
|
|
||||||
return fmt.Sprintf("%d%c", v, unitToByte[u])
|
return fmt.Sprintf("%d%s", v, u)
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,7 +54,7 @@ func format_B(t time.Time) string {
|
||||||
h, m, s := t.Clock()
|
h, m, s := t.Clock()
|
||||||
n := t.Nanosecond() / NanosecondPerMillisecond
|
n := t.Nanosecond() / NanosecondPerMillisecond
|
||||||
|
|
||||||
return fmt.Sprintf("%03d", sit(uint(h), uint(m), uint(s), uint(n)))
|
return fmt.Sprintf("%03d", uint(sit(uint(h), uint(m), uint(s), uint(n))))
|
||||||
}
|
}
|
||||||
func format_g(t time.Time) string {
|
func format_g(t time.Time) string {
|
||||||
h := t.Hour() % 12
|
h := t.Hour() % 12
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package datetime
|
package datetime
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
|
|
||||||
. "gitea.zaclys.com/bvaudour/gob/option"
|
. "gitea.zaclys.com/bvaudour/gob/option"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -16,6 +18,8 @@ type TimeComparator[E any] interface {
|
||||||
IsPast() bool
|
IsPast() bool
|
||||||
IsFuture() bool
|
IsFuture() bool
|
||||||
Now() E
|
Now() E
|
||||||
|
String() string
|
||||||
|
IsNil() bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// Min retourne le temps le plus petit.
|
// Min retourne le temps le plus petit.
|
||||||
|
@ -40,21 +44,74 @@ func Max[C TimeComparator[C]](e C, args ...C) C {
|
||||||
return out
|
return out
|
||||||
}
|
}
|
||||||
|
|
||||||
// Range représente une période entre deux bornes temporelles.
|
func minB[C TimeComparator[C]](e1, e2 C) C {
|
||||||
|
if e1.IsNil() {
|
||||||
|
return e1
|
||||||
|
} else if e2.IsNil() {
|
||||||
|
return e2
|
||||||
|
}
|
||||||
|
return Min(e1, e2)
|
||||||
|
}
|
||||||
|
func maxB[C TimeComparator[C]](e1, e2 C) C {
|
||||||
|
if e1.IsNil() {
|
||||||
|
return e2
|
||||||
|
} else if e2.IsNil() {
|
||||||
|
return e1
|
||||||
|
}
|
||||||
|
return Max(e1, e2)
|
||||||
|
}
|
||||||
|
func minE[C TimeComparator[C]](e1, e2 C) C {
|
||||||
|
if e1.IsNil() {
|
||||||
|
return e2
|
||||||
|
} else if e2.IsNil() {
|
||||||
|
return e1
|
||||||
|
}
|
||||||
|
return Min(e1, e2)
|
||||||
|
}
|
||||||
|
func maxE[C TimeComparator[C]](e1, e2 C) C {
|
||||||
|
if e1.IsNil() {
|
||||||
|
return e1
|
||||||
|
} else if e2.IsNil() {
|
||||||
|
return e2
|
||||||
|
}
|
||||||
|
return Max(e1, e2)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Range représente une période entre deux bornes temporelles begin et end.
|
||||||
|
// Si begin est nul, cela représente ]-∞ ; end].
|
||||||
|
// Se end est nul, cela représent [begin; +∞[.
|
||||||
type Range[C TimeComparator[C]] struct {
|
type Range[C TimeComparator[C]] struct {
|
||||||
begin, end C
|
begin, end C
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewRange retourne une période entre begin et end.
|
// NewRange retourne une période entre begin et end.
|
||||||
// Si begin < end, les bornes sont inversées.
|
// Si begin < end, le programme panique.
|
||||||
func NewRange[C TimeComparator[C]](begin, end C) Range[C] {
|
func NewRange[C TimeComparator[C]](begin, end C) Range[C] {
|
||||||
if begin.Gt(end) {
|
if !begin.IsNil() && !end.IsNil() && begin.Gt(end) {
|
||||||
begin, end = end, begin
|
panic("begin should be located in past of end.")
|
||||||
}
|
}
|
||||||
|
|
||||||
return Range[C]{begin, end}
|
return Range[C]{begin, end}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func gt[C TimeComparator[C]](e C, strict ...bool) func(C) bool {
|
||||||
|
if len(strict) == 0 || !strict[0] {
|
||||||
|
return e.Ge
|
||||||
|
}
|
||||||
|
return e.Ge
|
||||||
|
}
|
||||||
|
func lt[C TimeComparator[C]](e C, strict ...bool) func(C) bool {
|
||||||
|
if len(strict) == 0 || !strict[0] {
|
||||||
|
return e.Le
|
||||||
|
}
|
||||||
|
return e.Le
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r Range[C]) bE(e C, strict ...bool) bool { return r.end.IsNil() || lt(e, strict...)(r.end) }
|
||||||
|
func (r Range[C]) aE(e C, strict ...bool) bool { return !r.end.IsNil() && gt(e, strict...)(r.end) }
|
||||||
|
func (r Range[C]) bB(e C, strict ...bool) bool { return !r.begin.IsNil() || lt(e, strict...)(r.begin) }
|
||||||
|
func (r Range[C]) aB(e C, strict ...bool) bool { return r.begin.IsNil() || gt(e, strict...)(r.begin) }
|
||||||
|
|
||||||
// Begin retourne le début de la période.
|
// Begin retourne le début de la période.
|
||||||
func (r Range[C]) Begin() C { return r.begin }
|
func (r Range[C]) Begin() C { return r.begin }
|
||||||
|
|
||||||
|
@ -62,22 +119,22 @@ func (r Range[C]) Begin() C { return r.begin }
|
||||||
func (r Range[C]) End() C { return r.end }
|
func (r Range[C]) End() C { return r.end }
|
||||||
|
|
||||||
// Before retourne vrai si e est située avant la période.
|
// Before retourne vrai si e est située avant la période.
|
||||||
func (r Range[C]) Before(e C) bool { return e.Lt(r.begin) }
|
func (r Range[C]) Before(e C) bool { return r.bB(e, true) }
|
||||||
|
|
||||||
// After retourne vrai si e est située après la période.
|
// After retourne vrai si e est située après la période.
|
||||||
func (r Range[C]) After(e C) bool { return e.Gt(r.end) }
|
func (r Range[C]) After(e C) bool { return r.aE(e, true) }
|
||||||
|
|
||||||
// Contains retourne vrai si e ∈ [begin;end].
|
// Contains retourne vrai si e ∈ [begin;end].
|
||||||
func (r Range[C]) Contains(e C) bool { return e.Ge(r.begin) && e.Le(r.end) }
|
func (r Range[C]) Contains(e C) bool { return r.aB(e) && r.bE(e) }
|
||||||
|
|
||||||
// ContainsStrictLeft retourne vrai si e ∈ ]begin;end].
|
// ContainsStrictLeft retourne vrai si e ∈ ]begin;end].
|
||||||
func (r Range[C]) ContainsStrictLeft(e C) bool { return e.Gt(r.begin) && e.Le(r.end) }
|
func (r Range[C]) ContainsStrictLeft(e C) bool { return r.aB(e, true) && r.bE(e) }
|
||||||
|
|
||||||
// ContainsStrictRight retourne vrai si e ∈ [begin;end[.
|
// ContainsStrictRight retourne vrai si e ∈ [begin;end[.
|
||||||
func (r Range[C]) ContainsStrictRight(e C) bool { return e.Ge(r.begin) && e.Lt(r.end) }
|
func (r Range[C]) ContainsStrictRight(e C) bool { return r.aB(e) && r.bE(e, true) }
|
||||||
|
|
||||||
// ContainsStrict retourne vrai si e ∈ ]begin;end[.
|
// ContainsStrict retourne vrai si e ∈ ]begin;end[.
|
||||||
func (r Range[C]) ContainsStrict(e C) bool { return e.Gt(r.begin) && e.Lt(r.end) }
|
func (r Range[C]) ContainsStrict(e C) bool { return r.aB(e, true) && r.bE(e, true) }
|
||||||
|
|
||||||
// IsNow retourne vrai si la période est en cours.
|
// IsNow retourne vrai si la période est en cours.
|
||||||
func (r Range[C]) IsNow() bool { return r.Contains(r.begin.Now()) }
|
func (r Range[C]) IsNow() bool { return r.Contains(r.begin.Now()) }
|
||||||
|
@ -89,14 +146,14 @@ func (r Range[C]) IsPast() bool { return r.Before(r.begin.Now()) }
|
||||||
func (r Range[C]) IsFuture() bool { return r.After(r.begin.Now()) }
|
func (r Range[C]) IsFuture() bool { return r.After(r.begin.Now()) }
|
||||||
|
|
||||||
// BeforeRange retourne vrai si r1 est terminée avant que r2 commence.
|
// BeforeRange retourne vrai si r1 est terminée avant que r2 commence.
|
||||||
func (r1 Range[C]) BeforeRange(r2 Range[C]) bool { return r1.end.Le(r2.begin) }
|
func (r1 Range[C]) BeforeRange(r2 Range[C]) bool { return !r1.end.IsNil() && r2.bB(r1.end) }
|
||||||
|
|
||||||
// AfterRange retourne vrai si r2 est terminée avec que r1 commence.
|
// AfterRange retourne vrai si r2 est terminée avec que r1 commence.
|
||||||
func (r1 Range[C]) AfterRange(r2 Range[C]) bool { return r2.BeforeRange(r1) }
|
func (r1 Range[C]) AfterRange(r2 Range[C]) bool { return !r1.begin.IsNil() && r2.aE(r1.begin) }
|
||||||
|
|
||||||
// ContainsRange retourne vrai si r2 est intégralement comprise dans r1.
|
// ContainsRange retourne vrai si r2 est intégralement comprise dans r1.
|
||||||
func (r1 Range[C]) ContainsRange(r2 Range[C]) bool {
|
func (r1 Range[C]) ContainsRange(r2 Range[C]) bool {
|
||||||
return r1.begin.Le(r2.begin) && r1.end.Ge(r2.end)
|
return ((r2.begin.IsNil() && r1.begin.IsNil()) || r1.aB(r2.begin)) && ((r2.end.IsNil() && r1.end.IsNil()) || r1.bE(r2.end))
|
||||||
}
|
}
|
||||||
|
|
||||||
// InRange retourne vrai si r2 comprend intégralement r1.
|
// InRange retourne vrai si r2 comprend intégralement r1.
|
||||||
|
@ -104,18 +161,18 @@ func (r1 Range[C]) InRange(r2 Range[C]) bool { return r2.ContainsRange(r1) }
|
||||||
|
|
||||||
// Excludes retourne vrai si r1 et r2 ne se chevauchent pas.
|
// Excludes retourne vrai si r1 et r2 ne se chevauchent pas.
|
||||||
func (r1 Range[C]) Excludes(r2 Range[C]) bool {
|
func (r1 Range[C]) Excludes(r2 Range[C]) bool {
|
||||||
return r1.end.Le(r2.begin) || r1.begin.Ge(r2.end)
|
return (!r1.end.IsNil() && r2.bB(r1.end)) || (!r1.begin.IsNil() && r2.aE(r1.begin))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Overlaps retourne vrai si r1 et r2 se chevauchent.
|
// Overlaps retourne vrai si r1 et r2 se chevauchent.
|
||||||
func (r1 Range[C]) Overlaps(r2 Range[C]) bool {
|
func (r1 Range[C]) Overlaps(r2 Range[C]) bool {
|
||||||
return r1.begin.Lt(r2.end) && r1.end.Gt(r2.begin)
|
return (r1.begin.IsNil() || r2.bE(r1.begin, true)) && (r1.end.IsNil() || r2.aB(r1.end, true))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Intersection retourne la période commune entre deux périodes.
|
// Intersection retourne la période commune entre deux périodes.
|
||||||
func (r1 Range[C]) Intersection(r2 Range[C]) (result Option[Range[C]]) {
|
func (r1 Range[C]) Intersection(r2 Range[C]) (result Option[Range[C]]) {
|
||||||
if r1.Overlaps(r2) {
|
if r1.Overlaps(r2) {
|
||||||
result = Some(NewRange(Max(r1.begin, r2.begin), Min(r1.end, r2.end)))
|
result = Some(NewRange(maxB(r1.begin, r2.begin), minE(r1.end, r2.end)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -123,8 +180,8 @@ func (r1 Range[C]) Intersection(r2 Range[C]) (result Option[Range[C]]) {
|
||||||
|
|
||||||
// Joins retourne la plus grande période contiguë formée par deux périodes.
|
// Joins retourne la plus grande période contiguë formée par deux périodes.
|
||||||
func (r1 Range[C]) Joins(r2 Range[C]) (result Option[Range[C]]) {
|
func (r1 Range[C]) Joins(r2 Range[C]) (result Option[Range[C]]) {
|
||||||
if r1.begin.Le(r2.end) && r1.end.Ge(r2.begin) {
|
if (r1.begin.IsNil() || r2.bE(r1.begin)) && (r1.end.IsNil() || r2.aB(r1.end)) {
|
||||||
result = Some(NewRange(Min(r1.begin, r2.begin), Max(r1.end, r2.end)))
|
result = Some(NewRange(minB(r1.begin, r2.begin), maxE(r1.end, r2.end)))
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
|
@ -132,27 +189,37 @@ func (r1 Range[C]) Joins(r2 Range[C]) (result Option[Range[C]]) {
|
||||||
|
|
||||||
// Diff retourne la liste des périodes qui ne se chevauchent pas.
|
// Diff retourne la liste des périodes qui ne se chevauchent pas.
|
||||||
func (r1 Range[C]) Diff(r2 Range[C]) (result []Range[C]) {
|
func (r1 Range[C]) Diff(r2 Range[C]) (result []Range[C]) {
|
||||||
if r1.begin.Ne(r2.begin) {
|
b1, b2 := minB(r1.begin, r2.begin), maxB(r1.begin, r2.begin)
|
||||||
begin := Min(r1.begin, r2.begin)
|
e1, e2 := minE(r1.end, r2.end), maxE(r1.end, r2.end)
|
||||||
var end C
|
|
||||||
if begin.Eq(r1.begin) {
|
if b1.Ne(b2) {
|
||||||
end = Min(r1.end, r2.begin)
|
e := b2
|
||||||
} else {
|
if !e1.IsNil() {
|
||||||
end = Min(r2.end, r1.begin)
|
e = Min(b2, e1)
|
||||||
}
|
}
|
||||||
result = append(result, NewRange(begin, end))
|
result = append(result, NewRange(b1, e))
|
||||||
}
|
}
|
||||||
|
|
||||||
if r1.end.Ne(r2.end) {
|
if e1.Ne(e2) {
|
||||||
end := Max(r1.end, r2.end)
|
b := e1
|
||||||
var begin C
|
if !b2.IsNil() {
|
||||||
if end.Eq(r1.end) {
|
b = Max(b2, e1)
|
||||||
begin = Max(r1.begin, r2.end)
|
|
||||||
} else {
|
|
||||||
begin = Max(r2.begin, r1.end)
|
|
||||||
}
|
}
|
||||||
result = append(result, NewRange(begin, end))
|
result = append(result, NewRange(b, e2))
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// String retourne la représentation textuelle de la période.
|
||||||
|
func (r Range[C]) String() string {
|
||||||
|
b, e := r.begin.String(), r.end.String()
|
||||||
|
if r.begin.IsNil() {
|
||||||
|
b = "-∞"
|
||||||
|
}
|
||||||
|
if r.end.IsNil() {
|
||||||
|
e = "+∞"
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("[%s ; %s]", b, e)
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue