mirror of
https://github.com/rclone/rclone.git
synced 2025-08-19 01:46:31 +02:00
fs: Implement fs.Time
Similar to fs.Duration but parses into a timestamp instead Supports parsing from: * Any of the date formats in parseTimeDates * A time.Duration offset from now * parseDurationSuffixes offset from now
This commit is contained in:
91
fs/parsetime.go
Normal file
91
fs/parsetime.go
Normal file
@@ -0,0 +1,91 @@
|
||||
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, nil)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return t.Set(string(token))
|
||||
}
|
Reference in New Issue
Block a user