Files
rclone/fs/parsetime.go
kevin dee8b7e285 fs: accept multi-unit relative times like 1d12h in Time options
The docs say Time options take the same relative forms as Duration
options, with "1d12h" as an example, but ParseTime only tried
time.ParseDuration and single-suffix values, so --max-age style
Time options such as --s3-version-at 1d12h were rejected.
2026-10-31 12:24:46 +00:00

91 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 duration offset from now
d, err := ParseDuration(date)
if err != nil {
return t, err
}
return now.Add(-d), nil
}
// 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))
}