rclone/fs/parsetime.go

97 lines
1.7 KiB
Go

package fs
import (
"encoding/json"
"fmt"
"time"
)
// Time is a time.Time with some more parsing options
type Time time.Time
// For overriding in unittests.
var (
timeNowFunc = time.Now
)
// Turn Time into a string
func (t Time) String() string {
if !t.IsSet() {
return "off"
}
return time.Time(t).Format(time.RFC3339Nano)
}
// IsSet returns if the time is not zero
func (t Time) IsSet() bool {
return !time.Time(t).IsZero()
}
// ParseTime parses a time or duration string as a Time.
func ParseTime(date string) (t time.Time, err error) {
if date == "off" {
return time.Time{}, nil
}
now := timeNowFunc()
// Attempt to parse as a text time
t, err = parseTimeDates(date)
if err == nil {
return t, nil
}
// Attempt to parse as a time.Duration offset from now
d, err := time.ParseDuration(date)
if err == nil {
return now.Add(-d), nil
}
d, err = parseDurationSuffixes(date)
if err == nil {
return now.Add(-d), nil
}
return t, err
}
// Set a Time
func (t *Time) Set(s string) error {
parsedTime, err := ParseTime(s)
if err != nil {
return err
}
*t = Time(parsedTime)
return nil
}
// Type of the value
func (t Time) Type() string {
return "Time"
}
// UnmarshalJSON makes sure the value can be parsed as a string in JSON
func (t *Time) UnmarshalJSON(in []byte) error {
var s string
err := json.Unmarshal(in, &s)
if err != nil {
return err
}
return t.Set(s)
}
// MarshalJSON marshals as a time.Time value
func (t Time) MarshalJSON() ([]byte, error) {
return json.Marshal(time.Time(t))
}
// Scan implements the fmt.Scanner interface
func (t *Time) Scan(s fmt.ScanState, ch rune) error {
token, err := s.Token(true, func(rune) bool { return true })
if err != nil {
return err
}
return t.Set(string(token))
}