96 lines
2.6 KiB
Go
96 lines
2.6 KiB
Go
|
package datetime
|
|||
|
|
|||
|
import (
|
|||
|
"fmt"
|
|||
|
"strings"
|
|||
|
"time"
|
|||
|
|
|||
|
. "gitea.zaclys.com/bvaudour/gob/option"
|
|||
|
)
|
|||
|
|
|||
|
func format2layout(f string) string {
|
|||
|
var buffer strings.Builder
|
|||
|
|
|||
|
runes := []rune(f)
|
|||
|
for i := 0; i < len(runes); i++ {
|
|||
|
if layout, ok := parsers[runes[i]]; ok {
|
|||
|
buffer.WriteString(layout)
|
|||
|
} else {
|
|||
|
switch runes[i] {
|
|||
|
case '\\': // raw output, no parse
|
|||
|
buffer.WriteRune(runes[i+1])
|
|||
|
i++
|
|||
|
continue
|
|||
|
default:
|
|||
|
buffer.WriteRune(runes[i])
|
|||
|
}
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return buffer.String()
|
|||
|
}
|
|||
|
|
|||
|
func parseInLocation(value, layout string, tz ...string) Result[time.Time] {
|
|||
|
location := DefaultTZ
|
|||
|
if len(tz) > 0 {
|
|||
|
var err error
|
|||
|
if location, err = time.LoadLocation(tz[0]); err != nil {
|
|||
|
return Err[time.Time](fmt.Errorf(errInvalidTZ, tz[0]))
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
t, err := time.ParseInLocation(layout, value, location)
|
|||
|
if err == nil {
|
|||
|
return Ok(t)
|
|||
|
}
|
|||
|
return Err[time.Time](fmt.Errorf(errInvalidValue, value))
|
|||
|
}
|
|||
|
|
|||
|
// Guess tente de parser la chaîne de caractères en date en essayant de deviner le format.
|
|||
|
// Si le fuseau horaire n’est pas précisé dans la chaîne, le fuseau utilisé est tz (si fourni) ou le fuseau horaire par défaut.
|
|||
|
func Guess(value string, tz ...string) Result[time.Time] {
|
|||
|
if value == "" || value == "0" || value == "0000-00-00 00:00:00" || value == "0000-00-00" || value == "00:00:00" {
|
|||
|
return Zero(tz...)
|
|||
|
}
|
|||
|
|
|||
|
switch value {
|
|||
|
case "now":
|
|||
|
return Now(tz...)
|
|||
|
case "yesterday":
|
|||
|
return Yesterday(tz...)
|
|||
|
case "tomorrow":
|
|||
|
return Tomorrow(tz...)
|
|||
|
}
|
|||
|
|
|||
|
if len(tz) > 0 {
|
|||
|
if _, err := time.LoadLocation(tz[0]); err != nil {
|
|||
|
return Err[time.Time](fmt.Errorf(errInvalidTZ, tz[0]))
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
for _, layout := range layouts {
|
|||
|
t := parseInLocation(layout, value, tz...)
|
|||
|
if t.IsOk() {
|
|||
|
return t
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
return Err[time.Time](fmt.Errorf(errInvalidValue, value))
|
|||
|
}
|
|||
|
|
|||
|
// ParseFromLayout parse la chaîne de caractères en date à partir du layout (façon Go) fourni.
|
|||
|
// Si le fuseau horaire n’est pas précisé dans la chaîne, le fuseau utilisé est tz (si fourni) ou le fuseau horaire par défaut.
|
|||
|
func ParseFromLayout(value, layout string, tz ...string) Result[time.Time] {
|
|||
|
if value == "" || value == "0" || value == "0000-00-00 00:00:00" || value == "0000-00-00" || value == "00:00:00" {
|
|||
|
return Zero(tz...)
|
|||
|
}
|
|||
|
|
|||
|
return parseInLocation(value, layout, tz...)
|
|||
|
}
|
|||
|
|
|||
|
// Parse parse la chaîne de caractères en date à partir du format (dans le style PHP) fourni.
|
|||
|
// Si le fuseau horaire n’est pas précisé dans la chaîne, le fuseau utilisé est tz (si fourni) ou le fuseau horaire par défaut.
|
|||
|
func Parse(value, format string, tz ...string) Result[time.Time] {
|
|||
|
return ParseFromLayout(value, format2layout(format), tz...)
|
|||
|
}
|