gob/datetime/format.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()
}