mirror of https://github.com/hay-kot/homebox.git
109 lines
2.2 KiB
Go
109 lines
2.2 KiB
Go
// Package types provides custom types for the application.
|
|
package types
|
|
|
|
import (
|
|
"errors"
|
|
"strings"
|
|
"time"
|
|
)
|
|
|
|
// Date is a custom type that implements the MarshalJSON interface
|
|
// that applies date only formatting to the time.Time fields in order
|
|
// to avoid common time and timezone pitfalls when working with Times.
|
|
//
|
|
// Examples:
|
|
//
|
|
// "2019-01-01" -> time.Time{2019-01-01 00:00:00 +0000 UTC}
|
|
// "2019-01-01T21:10:30Z" -> time.Time{2019-01-01 00:00:00 +0000 UTC}
|
|
// "2019-01-01T21:10:30+01:00" -> time.Time{2019-01-01 00:00:00 +0000 UTC}
|
|
type Date time.Time
|
|
|
|
func (d Date) Time() time.Time {
|
|
return time.Time(d)
|
|
}
|
|
|
|
// DateFromTime returns a Date type from a time.Time type by stripping
|
|
// the time and timezone information.
|
|
func DateFromTime(t time.Time) Date {
|
|
dateOnlyTime := time.Date(t.Year(), t.Month(), t.Day(), 0, 0, 0, 0, time.UTC)
|
|
return Date(dateOnlyTime)
|
|
}
|
|
|
|
// DateFromString returns a Date type from a string by parsing the
|
|
// string into a time.Time type and then stripping the time and
|
|
// timezone information.
|
|
//
|
|
// Errors are ignored and an empty Date is returned.
|
|
func DateFromString(s string) Date {
|
|
if s == "" {
|
|
return Date{}
|
|
}
|
|
|
|
try := [...]string{
|
|
"2006-01-02",
|
|
"01/02/2006",
|
|
"2006/01/02",
|
|
time.RFC3339,
|
|
}
|
|
|
|
for _, format := range try {
|
|
t, err := time.Parse(format, s)
|
|
if err == nil {
|
|
return DateFromTime(t)
|
|
}
|
|
}
|
|
|
|
return Date{}
|
|
}
|
|
|
|
func (d Date) String() string {
|
|
if time.Time(d).IsZero() {
|
|
return ""
|
|
}
|
|
|
|
return time.Time(d).Format("2006-01-02")
|
|
}
|
|
|
|
func (d Date) MarshalJSON() ([]byte, error) {
|
|
if time.Time(d).IsZero() {
|
|
return []byte(`""`), nil
|
|
}
|
|
|
|
return []byte(`"` + d.String() + `"`), nil
|
|
}
|
|
|
|
func (d *Date) UnmarshalJSON(data []byte) (err error) {
|
|
// unescape the string if necessary `\"` -> `"`
|
|
str := strings.Trim(string(data), "\"")
|
|
if str == "" || str == "null" || str == `""` {
|
|
*d = Date{}
|
|
return nil
|
|
}
|
|
|
|
try := [...]string{
|
|
"2006-01-02",
|
|
"01/02/2006",
|
|
time.RFC3339,
|
|
}
|
|
|
|
set := false
|
|
var t time.Time
|
|
|
|
for _, format := range try {
|
|
t, err = time.Parse(format, str)
|
|
if err == nil {
|
|
set = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !set {
|
|
return errors.New("invalid date format")
|
|
}
|
|
|
|
// strip the time and timezone information
|
|
*d = DateFromTime(t)
|
|
|
|
return nil
|
|
}
|