gob/datetime/parse.go

96 lines
2.6 KiB
Go
Raw Normal View History

2023-10-31 10:18:00 +00:00
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 nest 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 nest 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 nest 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...)
}