207 lines
5.4 KiB
Go
207 lines
5.4 KiB
Go
|
package datetime
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"strings"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
func abs[N ~int | ~int64](e N) N {
|
||
|
if e < 0 {
|
||
|
return -e
|
||
|
}
|
||
|
return e
|
||
|
}
|
||
|
|
||
|
func isYearBissextil(year int) bool { return year%4 == 0 && !(year%100 == 0 && year%400 != 0) }
|
||
|
|
||
|
func daysInMonth(year int, month time.Month) int {
|
||
|
switch month {
|
||
|
case time.February:
|
||
|
if isYearBissextil(year) {
|
||
|
return 29
|
||
|
}
|
||
|
return 28
|
||
|
case time.April, time.June, time.September, time.November:
|
||
|
return 30
|
||
|
default:
|
||
|
return 31
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func internetHour(t time.Time) int {
|
||
|
t, _ = ToTimezone(t, "CET").Ok()
|
||
|
h, m, s := t.Clock()
|
||
|
n := t.Nanosecond()
|
||
|
d := time.Duration(n)*Nanosecond + time.Duration(s)*Second + time.Duration(m)*Minute + time.Duration(h)*Hour
|
||
|
i := d * 1000 / Day
|
||
|
return int(i)
|
||
|
}
|
||
|
|
||
|
func gmtDiff(t time.Time) time.Duration {
|
||
|
d0 := t.Day()
|
||
|
h0, m0, _ := t.Clock()
|
||
|
g, _ := ToTimezone(t, "GMT").Ok()
|
||
|
d1 := g.Day()
|
||
|
h1, m1, _ := t.Clock()
|
||
|
|
||
|
return time.Duration(d0-d1)*Day + time.Duration(h0-h1)*Hour + time.Duration(m0-m1)*Minute
|
||
|
}
|
||
|
|
||
|
// Jour
|
||
|
func format_j(t time.Time) string { return fmt.Sprintf("%d", t.Day()) }
|
||
|
func format_d(t time.Time) string { return fmt.Sprintf("%02d", t.Day()) }
|
||
|
func format_N(t time.Time) string { return fmt.Sprintf("%d", t.Weekday()+1) }
|
||
|
func format_w(t time.Time) string { return fmt.Sprintf("%d", t.Weekday()) }
|
||
|
func format_D(t time.Time) string { return shortDays[t.Weekday()] }
|
||
|
func format_l(t time.Time) string { return longDays[t.Weekday()] }
|
||
|
func format_z(t time.Time) string { return fmt.Sprintf("%d", t.YearDay()) }
|
||
|
|
||
|
// Semaine
|
||
|
func format_W(t time.Time) string {
|
||
|
_, w := t.ISOWeek()
|
||
|
return fmt.Sprintf("%d", w)
|
||
|
}
|
||
|
|
||
|
// Mois
|
||
|
func format_n(t time.Time) string { return fmt.Sprintf("%d", t.Month()+1) }
|
||
|
func format_m(t time.Time) string { return fmt.Sprintf("%02d", t.Month()+1) }
|
||
|
func format_M(t time.Time) string { return shortMonths[t.Month()] }
|
||
|
func format_F(t time.Time) string { return longMonths[t.Month()] }
|
||
|
func format_t(t time.Time) string { return fmt.Sprintf("%d", daysInMonth(t.Year(), t.Month())) }
|
||
|
|
||
|
// Année
|
||
|
func format_y(t time.Time) string { return fmt.Sprintf("%02d", t.Year()%100) }
|
||
|
func format_Y(t time.Time) string { return fmt.Sprintf("%d", t.Year()) }
|
||
|
func format_L(t time.Time) string {
|
||
|
if isYearBissextil(t.Year()) {
|
||
|
return "1"
|
||
|
}
|
||
|
return "0"
|
||
|
}
|
||
|
|
||
|
// Heure
|
||
|
func format_a(t time.Time) string {
|
||
|
if t.Hour() < 12 {
|
||
|
return "am"
|
||
|
}
|
||
|
return "pm"
|
||
|
}
|
||
|
func format_A(t time.Time) string {
|
||
|
if t.Hour() < 12 {
|
||
|
return "AM"
|
||
|
}
|
||
|
return "PM"
|
||
|
}
|
||
|
func format_B(t time.Time) string { return fmt.Sprintf("%03d", internetHour(t)) }
|
||
|
func format_g(t time.Time) string {
|
||
|
h := t.Hour() % 12
|
||
|
if h == 0 {
|
||
|
h = 12
|
||
|
}
|
||
|
return fmt.Sprintf("%d", h)
|
||
|
}
|
||
|
func format_G(t time.Time) string { return fmt.Sprintf("%d", t.Hour()) }
|
||
|
func format_h(t time.Time) string {
|
||
|
h := t.Hour() % 12
|
||
|
if h == 0 {
|
||
|
h = 12
|
||
|
}
|
||
|
return fmt.Sprintf("%02d", h)
|
||
|
}
|
||
|
func format_H(t time.Time) string { return fmt.Sprintf("%02d", t.Hour()) }
|
||
|
func format_i(t time.Time) string { return fmt.Sprintf("%02d", t.Minute()) }
|
||
|
func format_s(t time.Time) string { return fmt.Sprintf("%02d", t.Second()) }
|
||
|
func format_v(t time.Time) string { return fmt.Sprintf("%03d", t.Nanosecond()/1000000) }
|
||
|
func format_u(t time.Time) string { return fmt.Sprintf("%06d", t.Nanosecond()/1000) }
|
||
|
|
||
|
// Fuseau horaire
|
||
|
func format_T(t time.Time) string {
|
||
|
name := t.Location().String()
|
||
|
if !strings.Contains(name, "/") {
|
||
|
return name
|
||
|
}
|
||
|
diff := gmtDiff(t)
|
||
|
h, m := diff/Hour, (diff%Hour)/Minute
|
||
|
s := "+"
|
||
|
if h < 0 {
|
||
|
s = "-"
|
||
|
}
|
||
|
if m == 0 {
|
||
|
return fmt.Sprintf("%s%02d", s, abs(h))
|
||
|
}
|
||
|
return fmt.Sprintf("%s%02d:%02d", s, abs(h), abs(m))
|
||
|
}
|
||
|
func format_e(t time.Time) string { return fmt.Sprintf("%s", t.Location()) }
|
||
|
func format_I(t time.Time) string {
|
||
|
if t.IsDST() {
|
||
|
return "1"
|
||
|
}
|
||
|
return "0"
|
||
|
}
|
||
|
func format_O(t time.Time) string {
|
||
|
diff := gmtDiff(t)
|
||
|
h, m := diff/Hour, (diff%Hour)/Minute
|
||
|
s := "+"
|
||
|
if h < 0 {
|
||
|
s = "-"
|
||
|
}
|
||
|
return fmt.Sprintf("%s%02d%02d", s, abs(h), abs(m))
|
||
|
}
|
||
|
func format_P(t time.Time) string {
|
||
|
diff := gmtDiff(t)
|
||
|
h, m := diff/Hour, (diff%Hour)/Minute
|
||
|
s := "+"
|
||
|
if h < 0 {
|
||
|
s = "-"
|
||
|
}
|
||
|
return fmt.Sprintf("%s%02d:%02d", s, abs(h), abs(m))
|
||
|
}
|
||
|
func format_p(t time.Time) string {
|
||
|
diff := gmtDiff(t)
|
||
|
if diff == 0 {
|
||
|
return "Z"
|
||
|
}
|
||
|
return format_P(t)
|
||
|
}
|
||
|
func format_Z(t time.Time) string {
|
||
|
diff := gmtDiff(t)
|
||
|
return fmt.Sprintf("%d", diff/Second)
|
||
|
}
|
||
|
|
||
|
// Date et heure complète
|
||
|
func format_c(t time.Time) string {
|
||
|
// Équivalent à "Y-m-d\TH:i:sP"
|
||
|
return fmt.Sprintf("%s-%s-%sT%s:%s:%s%s", format_Y(t), format_m(t), format_d(t), format_H(t), format_i(t), format_s(t), format_P(t))
|
||
|
}
|
||
|
func format_r(t time.Time) string {
|
||
|
// Équivalent à "D, j M Y H:i:sO"
|
||
|
return fmt.Sprintf("%s, %s %s %s %s:%s:%s%s", format_D(t), format_j(t), format_M(t), format_Y(t), format_H(t), format_i(t), format_s(t), format_P(t))
|
||
|
}
|
||
|
func format_U(t time.Time) string { return fmt.Sprintf("%d", t.Unix()) }
|
||
|
|
||
|
// Format retourne la représentation de la date dans le format indiqué.
|
||
|
// Pour connaître toutes les options possibles pour le format, veullez consulter
|
||
|
// https://www.php.net/manual/fr/datetime.format.php
|
||
|
// (ou le fichier const.go).
|
||
|
func Format(t time.Time, format string) string {
|
||
|
var buffer strings.Builder
|
||
|
|
||
|
runes := []rune(format)
|
||
|
for i := 0; i < len(runes); i++ {
|
||
|
if f, ok := formatters[runes[i]]; ok {
|
||
|
buffer.WriteString(f(t))
|
||
|
} else {
|
||
|
switch runes[i] {
|
||
|
case '\\': // raw output, no parse
|
||
|
buffer.WriteRune(runes[i+1])
|
||
|
i++
|
||
|
default:
|
||
|
buffer.WriteRune(runes[i])
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return buffer.String()
|
||
|
}
|