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