mirror of
https://github.com/rclone/rclone.git
synced 2024-11-23 01:35:39 +08:00
16039b350d
Before this fix, the parsing code gave an error like this parsing "2022-08-02 07:00:00" as fs.Time failed: expected newline This was due to the Scan call failing to read all the data. This patch fixes that, and redoes the tests
92 lines
1.6 KiB
Go
92 lines
1.6 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)
|
|
}
|
|
|
|
// 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))
|
|
}
|