365 lines
11 KiB
Go
365 lines
11 KiB
Go
package datetime
|
||
|
||
import (
|
||
"time"
|
||
)
|
||
|
||
const (
|
||
// Conversions d’unités.
|
||
NanosecondPerMicrosecond = 1000
|
||
MicrosecondPerMillisecond = 1000
|
||
MillisecondPerSecond = 1000
|
||
SecondPerMinute = 60
|
||
MinutePerHour = 60
|
||
HourPerDay = 24
|
||
DayPerWeek = 7
|
||
MonthPerYear = 12
|
||
BeatPerDay = 1000
|
||
|
||
HourPerWeek = HourPerDay * DayPerWeek
|
||
MinutePerDay = MinutePerHour * HourPerDay
|
||
MinutePerWeek = MinutePerHour * HourPerWeek
|
||
SecondPerHour = SecondPerMinute * MinutePerHour
|
||
SecondPerDay = SecondPerMinute * MinutePerDay
|
||
SecondPerWeek = SecondPerMinute * MinutePerWeek
|
||
MillisecondPerMinute = MillisecondPerSecond * SecondPerMinute
|
||
MillisecondPerHour = MillisecondPerSecond * SecondPerHour
|
||
MillisecondPerDay = MillisecondPerSecond * SecondPerDay
|
||
MillisecondPerWeek = MillisecondPerSecond * SecondPerWeek
|
||
MicrosecondPerSecond = MicrosecondPerMillisecond * MillisecondPerSecond
|
||
NanosecondPerMillisecond = NanosecondPerMicrosecond * MicrosecondPerMillisecond
|
||
NanosecondPerSecond = NanosecondPerMicrosecond * MicrosecondPerSecond
|
||
)
|
||
|
||
const (
|
||
// Unités supportées
|
||
NoUnit Unit = iota
|
||
Millisecond
|
||
Second
|
||
Minute
|
||
Hour
|
||
Day
|
||
Week
|
||
Month
|
||
Year
|
||
|
||
// Durée nulle
|
||
DurationNil = Duration(0)
|
||
|
||
bitsUnit = Duration(4)
|
||
bitsValue = 64 - bitsUnit
|
||
|
||
maskUnit = 1<<bitsUnit - 1
|
||
maskValue = ^maskUnit
|
||
)
|
||
|
||
const (
|
||
// Précisions supportées
|
||
NoPrecision Precision = iota
|
||
PrecisionMillisecond
|
||
PrecisionSecond
|
||
PrecisionMinute
|
||
|
||
bitsPrecision = uint32(2)
|
||
maskPrecision = 1<<bitsPrecision - 1
|
||
maskMillisecond = ^maskPrecision
|
||
|
||
minClock = uint(0)
|
||
maxClock = uint(MillisecondPerDay - 1)
|
||
|
||
clockNil = clock(0)
|
||
|
||
bitsDay = 5
|
||
bitsMonth = 4
|
||
|
||
shiftDay = date(0)
|
||
shiftMonth = date(bitsDay)
|
||
shiftYear = date(bitsDay + bitsMonth)
|
||
|
||
maskDay = 1<<bitsDay - 1
|
||
maskMonth = (1<<bitsMonth - 1) << shiftMonth
|
||
maskYear = ^(maskDay | maskMonth)
|
||
|
||
dateNil = date(0)
|
||
)
|
||
|
||
const (
|
||
// Mois
|
||
January = uint(1) + iota
|
||
February
|
||
March
|
||
April
|
||
May
|
||
June
|
||
July
|
||
August
|
||
September
|
||
October
|
||
November
|
||
December
|
||
)
|
||
|
||
const (
|
||
// Jours de la semaine
|
||
Sunday = uint(iota)
|
||
Monday
|
||
Tuesday
|
||
Wednesday
|
||
Thursday
|
||
Friday
|
||
Saturday
|
||
)
|
||
|
||
var (
|
||
// Représentation de l’unité sous forme de caractères
|
||
unitToString = map[Unit]string{
|
||
NoUnit: "",
|
||
Millisecond: "ms",
|
||
Second: "s",
|
||
Minute: "mn",
|
||
Hour: "h",
|
||
Day: "d",
|
||
Week: "w",
|
||
Month: "m",
|
||
Year: "y",
|
||
}
|
||
|
||
maskDate = map[string]date{
|
||
"d": maskDay,
|
||
"m": maskMonth,
|
||
"y": maskYear,
|
||
}
|
||
shiftDate = map[string]date{
|
||
"d": shiftDay,
|
||
"m": shiftMonth,
|
||
"y": shiftYear,
|
||
}
|
||
|
||
beginPrecisionM = map[Precision][]uint{
|
||
PrecisionMillisecond: []uint{0},
|
||
}
|
||
endPrecisionM = map[Precision][]uint{
|
||
PrecisionMillisecond: []uint{999},
|
||
}
|
||
beginPrecisionS = map[Precision][]uint{
|
||
PrecisionSecond: []uint{0},
|
||
PrecisionMillisecond: []uint{0, 0},
|
||
}
|
||
endPrecisionS = map[Precision][]uint{
|
||
PrecisionSecond: []uint{999},
|
||
PrecisionMillisecond: []uint{59, 999},
|
||
}
|
||
|
||
// Layouts de base pour le parsage des dates
|
||
layouts = []string{
|
||
"Mon, Jan 2, 2006 3:04 PM",
|
||
"2006-01-02 15:04:05", "2006-01-02 15:04:05.999", "20060102150405", "20060102150405.999",
|
||
"2006-01-02", "2006-01-02.999", "20060102", "20060102.999",
|
||
// ISO8601
|
||
"2006-01-02T15:04:05-07:00", "2006-01-02T15:04:05.999-07:00",
|
||
// RFC822
|
||
"02 Jan 06 15:04 MST", "02 Jan 06 15:04 -0700",
|
||
// RFC850
|
||
"Monday, 02-Jan-06 15:04:05 MST",
|
||
// RFC1123
|
||
"Mon, 02 Jan 2006 15:04:05 MST", "Mon, 02 Jan 2006 15:04:05 -0700",
|
||
// RFC3339
|
||
"2006-01-02T15:04:05Z07:00", "2006-01-02T15:04:05.999999999Z07:00",
|
||
// RFC1036
|
||
"Mon, 02 Jan 06 15:04:05 -0700",
|
||
// RFC7231
|
||
"Mon, 02 Jan 2006 15:04:05 MST",
|
||
"3:04PM",
|
||
// Cookies
|
||
"Monday, 02-Jan-2006 15:04:05 MST",
|
||
// ANSIC
|
||
"Mon Jan _2 15:04:05 2006",
|
||
// UNIX
|
||
"Mon Jan _2 15:04:05 MST 2006",
|
||
// Ruby
|
||
"Mon Jan 02 15:04:05 -0700 2006",
|
||
|
||
"2006",
|
||
"2006-1", "2006-1-2", "2006-1-2 15", "2006-1-2 15:4", "2006-1-2 15:4:5", "2006-1-2 15:4:5.999",
|
||
"2006.1", "2006.1.2", "2006.1.2 15", "2006.1.2 15:4", "2006.1.2 15:4:5", "2006.1.2 15:4:5.999",
|
||
"2006/1", "2006/1/2", "2006/1/2 15", "2006/1/2 15:4", "2006/1/2 15:4:5", "2006/1/2 15:4:5.999",
|
||
"2006-01", "2006-01-02", "2006-01-02 15", "2006-01-02 15:04", "2006-01-02 15:04:05", "2006-01-02 15:04:05.999",
|
||
"2006.01", "2006.01.02", "2006.01.02 15", "2006.01.02 15:04", "2006.01.02 15:04:05", "2006.01.02 15:04:05.999",
|
||
"2006/01", "2006/01/02", "2006/01/02 15", "2006/01/02 15:04", "2006/01/02 15:04:05", "2006/01/02 15:04:05.999",
|
||
"2006-01-02 15:04:05PM MST", "2006-01-02 15:04:05.999PM MST", "2006-1-2 15:4:5PM MST", "2006-1-2 15:4:5.999PM MST",
|
||
"2006-01-02 15:04:05 PM MST", "2006-01-02 15:04:05.999 PM MST", "2006-1-2 15:4:5 PM MST", "2006-1-2 15:4:5.999 PM MST",
|
||
"2/1/2006", "2/1/2006 15", "2/1/2006 15:4", "2/1/2006 15:4:5", "2/1/2006 15:4:5.999",
|
||
"02/01/2006", "02/01/2006 15", "02/01/2006 15:04", "02/01/2006 15:04:05", "02/01/2006 15:04:05.999",
|
||
"2006-1-2 15:4:5 -0700 MST", "2006-1-2 15:4:5.999 -0700 MST",
|
||
"2006-1-2T15:4:5Z07", "2006-1-2T15:4:5.999Z07",
|
||
"2006-1-2T15:4:5Z07:00", "2006-1-2T15:4:5.999Z07:00",
|
||
"2006-1-2T15:4:5-07:00", "2006-1-2T15:4:5.999-07:00",
|
||
"20060102150405-07:00", "20060102150405.999-07:00",
|
||
"20060102150405Z07", "20060102150405.999Z07",
|
||
"20060102150405Z07:00", "20060102150405.999Z07:00",
|
||
}
|
||
|
||
// Conversion parsage → layout
|
||
parsers = map[rune]string{
|
||
// Jours
|
||
'j': "2", // Jour du mois sans les 0 initiaux (1-31)
|
||
'd': "02", // Jour du mois, sur deux chiffres (avec un 0 initial) (01-31)
|
||
'D': "Mon", // Jour de la semaine, en 3 lettres (Mon-Sun)
|
||
'l': "Monday", // Jour de la semaine, textuel, version longue (Monday-Sunday)
|
||
|
||
// Mois
|
||
'n': "1", // Mois sans les 0 initiaux (1-12)
|
||
'm': "01", // Mois au format numérique, avec 0 initiaux (01-12)
|
||
'M': "Jan", // Mois, en trois lettres (Jan-Dec)
|
||
'F': "January", // Mois, textuel, version longue (January-December)
|
||
|
||
// Année
|
||
'y': "06", // Année sur 2 chiffres (Exemples : 99 ou 03)
|
||
'Y': "2006", // Année sur au moins 4 chiffres, avec - pour les années av. J.-C. (Exemples : -0055, 0787, 1999, 2003, 10191)
|
||
|
||
// Heure
|
||
'a': "pm", // Ante meridiem et Post meridiem en minuscules (am ou pm)
|
||
'A': "PM", // Ante meridiem et Post meridiem en majuscules (AM ou PM)
|
||
'g': "3", // Heure, au format 12h, sans les 0 initiaux (1-12)
|
||
'h': "03", // Heure, au format 12h, avec les 0 initiaux (01-12)
|
||
'H': "15", // Heure, au format 24h, avec les 0 initiaux (00-23)
|
||
'i': "04", // Minutes avec les 0 initiaux (00-59)
|
||
's': "05", // Secondes avec les 0 initiaux (00-59)
|
||
|
||
// Fuseau horaire
|
||
'T': "MST", // Abréviation du fuseau horaire, si connu ; sinon décalage depuis GMT (Exemples : EST, MDT, +05)
|
||
'O': "-0700", // Différence d’heures avec l’heure de Greenwich (GMT), sans deux-points entre les heures et les minutes (Exemple : +0200)
|
||
'P': "-07:00", // Différence d’heures avec l’heure de Greenwich (GMT), avec deux-points entre les heures et les minutes (Exemple : +02:00)
|
||
|
||
// Date et heure complète
|
||
'c': "2006-01-02T15:04:05-07:00", // Date au format ISO 8601 (2004-02-12T15:19:21+00:00)
|
||
'r': "Thu, 21 Dec 2000 16:01:07 +0200", // Date au format RFC 5322 (Thu, 21 Dec 2000 16:01:070200)
|
||
}
|
||
|
||
// Jours de la semaine (format court)
|
||
shortDays = []string{
|
||
"Sun",
|
||
"Mon",
|
||
"Tue",
|
||
"Wed",
|
||
"Thu",
|
||
"Fri",
|
||
"Sat",
|
||
}
|
||
|
||
// Jours de la semaine (format long)
|
||
longDays = []string{
|
||
"Sunday",
|
||
"Monday",
|
||
"Tuesday",
|
||
"Wednesday",
|
||
"Thursday",
|
||
"Friday",
|
||
"Saturday",
|
||
}
|
||
|
||
// Mois (format court)
|
||
shortMonths = []string{
|
||
"Jan",
|
||
"Feb",
|
||
"Mar",
|
||
"Apr",
|
||
"May",
|
||
"Jun",
|
||
"Jul",
|
||
"Aug",
|
||
"Sep",
|
||
"Oct",
|
||
"Nov",
|
||
"Dec",
|
||
}
|
||
|
||
// Mois (format long)
|
||
longMonths = []string{
|
||
"January",
|
||
"February",
|
||
"March",
|
||
"April",
|
||
"May",
|
||
"June",
|
||
"July",
|
||
"August",
|
||
"September",
|
||
"October",
|
||
"November",
|
||
"December",
|
||
}
|
||
|
||
formatters = map[rune]func(time.Time) string{
|
||
// Jour
|
||
'j': format_j, // Jour du mois sans les 0 initiaux (1-31)
|
||
'd': format_d, // Jour du mois, sur deux chiffres (avec un 0 initial) (01-31)
|
||
'N': format_N, // Représentation numérique ISO 8601 du jour de la semaine (1-7)
|
||
'w': format_w, // Jour de la semaine au format numérique (0-6)
|
||
'z': format_z, // Jour de l’année (0-365)
|
||
'D': format_D, // Jour de la semaine, en 3 lettres (Mon-Sun)
|
||
'l': format_l, // Jour de la semaine, textuel, version longue (Monday-Sunday)
|
||
|
||
// Semaine
|
||
'W': format_W, // N° de semaine dans l’année ISO 8601, les semaines commencent le lundi (0-53)
|
||
|
||
// Mois
|
||
'n': format_n, // Mois sans les 0 initiaux (1-12)
|
||
'm': format_m, // Mois au format numérique, avec 0 initiaux (01-12)
|
||
't': format_t, // Nombre de jours dans le mois (28-31)
|
||
'M': format_M, // Mois, en trois lettres (Jan-Dec)
|
||
'F': format_F, // Mois, textuel, version longue (January-December)
|
||
|
||
// Année
|
||
'y': format_y, // Année sur 2 chiffres (Exemples : 99 ou 03)
|
||
'Y': format_Y, // Année sur au moins 4 chiffres, avec - pour les années av. J.-C. (Exemples : -0055, 0787, 1999, 2003, 10191)
|
||
'L': format_L, // Est ce que l’année est bissextile (1 si bissextile, 0 sinon)
|
||
|
||
// Heure
|
||
'a': format_a, // Ante meridiem et Post meridiem en minuscules (am ou pm)
|
||
'A': format_A, // Ante meridiem et Post meridiem en majuscules (AM ou PM)
|
||
'B': format_B, // Heure Internet Swatch (000-999)
|
||
'g': format_g, // Heure, au format 12h, sans les 0 initiaux (1-12)
|
||
'G': format_G, // Heure, au format 24h, sans les 0 initiaux (0-23)
|
||
'h': format_h, // Heure, au format 12h, avec les 0 initiaux (01-12)
|
||
'H': format_H, // Heure, au format 24h, avec les 0 initiaux (00-23)
|
||
'i': format_i, // Minutes avec les 0 initiaux (00-59)
|
||
's': format_s, // Secondes avec les 0 initiaux (00-59)
|
||
'v': format_v, // Nillisecondes avec les 0 initiaux (000-999)
|
||
'u': format_u, // Microsecondes avec les 0 initiaux (000000-999999)
|
||
|
||
// Fuseau horaire
|
||
'T': format_T, // Abréviation du fuseau horaire, si connu ; sinon décalage depuis GMT (Exemples : EST, MDT, +05)
|
||
'e': format_e, // L’identifiant du fuseau horaire (Exemples : UTC, GMT, Atlantic/Azores)
|
||
'I': format_I, // L’heure d’été est activée ou pas (1 si oui, 0 sinon)
|
||
'O': format_O, // Différence d’heures avec l’heure de Greenwich (GMT), sans deux-points entre les heures et les minutes (Exemple : +0200)
|
||
'P': format_P, // Différence d’heures avec l’heure de Greenwich (GMT), avec deux-points entre les heures et les minutes (Exemple : +02:00)
|
||
'p': format_p, // Identique à P, mais retourne Z au lieu de +00:00
|
||
'Z': format_Z, // Décalage horaire en secondes. Le décalage des zones à l’ouest de la zone UTC est négatif, et à l’est, il est positif.(-43200 à 50400)
|
||
|
||
// Date et heure complète
|
||
'c': format_c, // Date au format ISO 8601 (2004-02-12T15:19:21+00:00)
|
||
'r': format_r, // Date au format RFC 5322 (Thu, 21 Dec 2000 16:01:070200)
|
||
'U': format_U, // Secondes depuis l’époque Unix (1er Janvier 1970, 0h00 00s GMT)
|
||
}
|
||
|
||
amPmLow = map[bool]string{
|
||
true: "am",
|
||
false: "pm",
|
||
}
|
||
|
||
amPmUp = map[bool]string{
|
||
true: "AM",
|
||
false: "PM",
|
||
}
|
||
|
||
formatP = map[Precision]string{
|
||
PrecisionMinute: "H:iT",
|
||
PrecisionSecond: "H:i:sT",
|
||
PrecisionMillisecond: "H:i:s.vT",
|
||
}
|
||
|
||
// Fuseau horaire par défaut
|
||
DefaultTZ = time.Local
|
||
)
|