mirror of
https://github.com/rclone/rclone.git
synced 2024-11-22 12:36:38 +08:00
fs: allow --min-age/--max-age to take a date as well as a duration
Fixes #4211
This commit is contained in:
parent
8ddb3fbb2e
commit
e91b509578
|
@ -429,6 +429,13 @@ seconds or with a suffix of:
|
|||
For example `--max-age 2d` means no files older than 2 days will be
|
||||
transferred.
|
||||
|
||||
This can also be an absolute time in one of these formats
|
||||
|
||||
- RFC3339 - eg "2006-01-02T15:04:05Z07:00"
|
||||
- ISO8601 Date and time, local timezone - "2006-01-02T15:04:05"
|
||||
- ISO8601 Date and time, local timezone - "2006-01-02 15:04:05"
|
||||
- ISO8601 Date - "2006-01-02" (YYYY-MM-DD)
|
||||
|
||||
### `--min-age` - Don't transfer any file younger than this ###
|
||||
|
||||
This option controls the minimum age of files to transfer. Give in
|
||||
|
|
|
@ -48,20 +48,10 @@ var ageSuffixes = []struct {
|
|||
{Suffix: "", Multiplier: time.Second},
|
||||
}
|
||||
|
||||
// ParseDuration parses a duration string. Accept ms|s|m|h|d|w|M|y suffixes. Defaults to second if not provided
|
||||
func ParseDuration(age string) (time.Duration, error) {
|
||||
// parse the age as suffixed ages
|
||||
func parseDurationSuffixes(age string) (time.Duration, error) {
|
||||
var period float64
|
||||
|
||||
if age == "off" {
|
||||
return time.Duration(DurationOff), nil
|
||||
}
|
||||
|
||||
// Attempt to parse as a time.Duration first
|
||||
d, err := time.ParseDuration(age)
|
||||
if err == nil {
|
||||
return d, nil
|
||||
}
|
||||
|
||||
for _, ageSuffix := range ageSuffixes {
|
||||
if strings.HasSuffix(age, ageSuffix.Suffix) {
|
||||
numberString := age[:len(age)-len(ageSuffix.Suffix)]
|
||||
|
@ -78,6 +68,51 @@ func ParseDuration(age string) (time.Duration, error) {
|
|||
return time.Duration(period), nil
|
||||
}
|
||||
|
||||
// time formats to try parsing ages as - in order
|
||||
var timeFormats = []string{
|
||||
time.RFC3339,
|
||||
"2006-01-02T15:04:05",
|
||||
"2006-01-02 15:04:05",
|
||||
"2006-01-02",
|
||||
}
|
||||
|
||||
// parse the age as time before the epoch in various date formats
|
||||
func parseDurationDates(age string, epoch time.Time) (t time.Duration, err error) {
|
||||
var instant time.Time
|
||||
for _, timeFormat := range timeFormats {
|
||||
instant, err = time.Parse(timeFormat, age)
|
||||
if err == nil {
|
||||
return epoch.Sub(instant), nil
|
||||
}
|
||||
}
|
||||
return t, err
|
||||
}
|
||||
|
||||
// ParseDuration parses a duration string. Accept ms|s|m|h|d|w|M|y suffixes. Defaults to second if not provided
|
||||
func ParseDuration(age string) (d time.Duration, err error) {
|
||||
if age == "off" {
|
||||
return time.Duration(DurationOff), nil
|
||||
}
|
||||
|
||||
// Attempt to parse as a time.Duration first
|
||||
d, err = time.ParseDuration(age)
|
||||
if err == nil {
|
||||
return d, nil
|
||||
}
|
||||
|
||||
d, err = parseDurationSuffixes(age)
|
||||
if err == nil {
|
||||
return d, nil
|
||||
}
|
||||
|
||||
d, err = parseDurationDates(age, time.Now())
|
||||
if err == nil {
|
||||
return d, nil
|
||||
}
|
||||
|
||||
return d, err
|
||||
}
|
||||
|
||||
// ReadableString parses d into a human readable duration.
|
||||
// Based on https://github.com/hako/durafmt
|
||||
func (d Duration) ReadableString() string {
|
||||
|
|
|
@ -2,6 +2,7 @@ package fs
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
|
@ -36,6 +37,10 @@ func TestParseDuration(t *testing.T) {
|
|||
{"1x", 0, true},
|
||||
{"off", time.Duration(DurationOff), false},
|
||||
{"1h2m3s", time.Hour + 2*time.Minute + 3*time.Second, false},
|
||||
{"2001-02-03", time.Since(time.Date(2001, 2, 3, 0, 0, 0, 0, time.Local)), false},
|
||||
{"2001-02-03 10:11:12", time.Since(time.Date(2001, 2, 3, 10, 11, 12, 0, time.Local)), false},
|
||||
{"2001-02-03T10:11:12", time.Since(time.Date(2001, 2, 3, 10, 11, 12, 0, time.Local)), false},
|
||||
{"2001-02-03T10:11:12.123Z", time.Since(time.Date(2001, 2, 3, 10, 11, 12, 123, time.UTC)), false},
|
||||
} {
|
||||
duration, err := ParseDuration(test.in)
|
||||
if test.err {
|
||||
|
@ -43,7 +48,12 @@ func TestParseDuration(t *testing.T) {
|
|||
} else {
|
||||
require.NoError(t, err)
|
||||
}
|
||||
assert.Equal(t, test.want, duration)
|
||||
if strings.HasPrefix(test.in, "2001-") {
|
||||
ok := duration > test.want-time.Second && duration < test.want+time.Second
|
||||
assert.True(t, ok, test.in)
|
||||
} else {
|
||||
assert.Equal(t, test.want, duration)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user