diff --git a/schtasks/task.go b/schtasks/task.go
index aa1d97b9..00f2b06e 100644
--- a/schtasks/task.go
+++ b/schtasks/task.go
@@ -30,9 +30,10 @@ type Task struct {
Principals Principals `xml:"Principals"`
Settings Settings `xml:"Settings"`
Actions Actions `xml:"Actions"`
+ fromNow time.Time `xml:"-"`
}
-func NewTask() Task {
+func NewTask(options ...TaskOption) Task {
var userID string
if currentUser, err := user.Current(); err == nil {
userID = currentUser.Uid
@@ -69,6 +70,11 @@ func NewTask() Task {
Actions: Actions{
Context: author,
},
+ fromNow: time.Now(),
+ }
+
+ for _, option := range options {
+ option.apply(&task)
}
return task
}
@@ -105,9 +111,14 @@ func (t *Task) AddSchedules(schedules []*calendar.Event) {
}
}
+func (t *Task) setFromNow(fromNow time.Time) {
+ t.fromNow = fromNow
+ t.RegistrationInfo.Date = fromNow.Format(dateFormat)
+}
+
func (t *Task) addTimeTrigger(triggerOnce time.Time) {
timeTrigger := TimeTrigger{
- StartBoundary: triggerOnce.Format(dateFormat),
+ StartBoundary: &triggerOnce,
}
if t.Triggers.TimeTrigger == nil {
t.Triggers.TimeTrigger = []TimeTrigger{timeTrigger}
@@ -125,7 +136,7 @@ func (t *Task) addCalendarTrigger(trigger CalendarTrigger) {
}
func (t *Task) addDailyTrigger(schedule *calendar.Event) {
- start := schedule.Next(time.Now())
+ start := schedule.Next(t.fromNow)
// get all recurrences in the same day
recurrences := schedule.GetAllInBetween(start, start.Add(24*time.Hour))
if len(recurrences) == 0 {
@@ -135,7 +146,7 @@ func (t *Task) addDailyTrigger(schedule *calendar.Event) {
// Is it only once a day?
if len(recurrences) == 1 {
t.addCalendarTrigger(CalendarTrigger{
- StartBoundary: recurrences[0].Format(dateFormat),
+ StartBoundary: &recurrences[0],
ScheduleByDay: &ScheduleByDay{
DaysInterval: 1,
},
@@ -149,7 +160,7 @@ func (t *Task) addDailyTrigger(schedule *calendar.Event) {
// case with regular repetition
interval := period.NewOf(compactDifferences[0])
t.addCalendarTrigger(CalendarTrigger{
- StartBoundary: start.Format(dateFormat),
+ StartBoundary: &start,
ScheduleByDay: &ScheduleByDay{
DaysInterval: 1,
},
@@ -168,7 +179,7 @@ func (t *Task) addDailyTrigger(schedule *calendar.Event) {
// install them all
for _, recurrence := range recurrences {
t.addCalendarTrigger(CalendarTrigger{
- StartBoundary: recurrence.Format(dateFormat),
+ StartBoundary: &recurrence,
ScheduleByDay: &ScheduleByDay{
DaysInterval: 1,
},
@@ -177,7 +188,7 @@ func (t *Task) addDailyTrigger(schedule *calendar.Event) {
}
func (t *Task) addWeeklyTrigger(schedule *calendar.Event) {
- start := schedule.Next(time.Now())
+ start := schedule.Next(t.fromNow)
// get all recurrences in the same day
recurrences := schedule.GetAllInBetween(start, start.Add(24*time.Hour))
if len(recurrences) == 0 {
@@ -187,7 +198,7 @@ func (t *Task) addWeeklyTrigger(schedule *calendar.Event) {
// Is it only once per 24h?
if len(recurrences) == 1 {
t.addCalendarTrigger(CalendarTrigger{
- StartBoundary: recurrences[0].Format(dateFormat),
+ StartBoundary: &recurrences[0],
ScheduleByWeek: &ScheduleByWeek{
WeeksInterval: 1,
DaysOfWeek: convertWeekdays(schedule.WeekDay.GetRangeValues()),
@@ -202,7 +213,7 @@ func (t *Task) addWeeklyTrigger(schedule *calendar.Event) {
// case with regular repetition
interval := period.NewOf(compactDifferences[0])
t.addCalendarTrigger(CalendarTrigger{
- StartBoundary: start.Format(dateFormat),
+ StartBoundary: &start,
ScheduleByWeek: &ScheduleByWeek{
WeeksInterval: 1,
DaysOfWeek: convertWeekdays(schedule.WeekDay.GetRangeValues()),
@@ -222,7 +233,7 @@ func (t *Task) addWeeklyTrigger(schedule *calendar.Event) {
// install them all
for _, recurrence := range recurrences {
t.addCalendarTrigger(CalendarTrigger{
- StartBoundary: recurrence.Format(dateFormat),
+ StartBoundary: &recurrence,
ScheduleByWeek: &ScheduleByWeek{
WeeksInterval: 1,
DaysOfWeek: convertWeekdays(schedule.WeekDay.GetRangeValues()),
@@ -232,7 +243,7 @@ func (t *Task) addWeeklyTrigger(schedule *calendar.Event) {
}
func (t *Task) addMonthlyTrigger(schedule *calendar.Event) {
- start := schedule.Next(time.Now())
+ start := schedule.Next(t.fromNow)
// get all recurrences in the same day
recurrences := schedule.GetAllInBetween(start, start.Add(24*time.Hour))
if len(recurrences) == 0 {
@@ -252,7 +263,7 @@ func (t *Task) addMonthlyTrigger(schedule *calendar.Event) {
}
if schedule.WeekDay.HasValue() {
t.addCalendarTrigger(CalendarTrigger{
- StartBoundary: recurrence.Format(dateFormat),
+ StartBoundary: &recurrence,
ScheduleByMonthDayOfWeek: &ScheduleByMonthDayOfWeek{
DaysOfWeek: convertWeekdays(schedule.WeekDay.GetRangeValues()),
Weeks: AllWeeks,
@@ -262,7 +273,7 @@ func (t *Task) addMonthlyTrigger(schedule *calendar.Event) {
continue
}
t.addCalendarTrigger(CalendarTrigger{
- StartBoundary: recurrence.Format(dateFormat),
+ StartBoundary: &recurrence,
ScheduleByMonth: &ScheduleByMonth{
DaysOfMonth: convertDaysOfMonth(schedule.Day.GetRangeValues()),
Months: convertMonths(schedule.Month.GetRangeValues()),
diff --git a/schtasks/task_options.go b/schtasks/task_options.go
new file mode 100644
index 00000000..b9c1905f
--- /dev/null
+++ b/schtasks/task_options.go
@@ -0,0 +1,21 @@
+//go:build windows
+
+package schtasks
+
+import "time"
+
+type TaskOption interface {
+ apply(t *Task)
+}
+
+type WithFromNowOption struct {
+ now time.Time
+}
+
+func WithFromNow(now time.Time) WithFromNowOption {
+ return WithFromNowOption{now: now}
+}
+
+func (w WithFromNowOption) apply(t *Task) {
+ t.setFromNow(w.now)
+}
diff --git a/schtasks/taskscheduler.go b/schtasks/taskscheduler.go
index 7587dbc9..bddedf49 100644
--- a/schtasks/taskscheduler.go
+++ b/schtasks/taskscheduler.go
@@ -28,6 +28,7 @@ import (
"slices"
"strings"
"text/tabwriter"
+ "time"
"github.com/creativeprojects/clog"
"github.com/creativeprojects/resticprofile/calendar"
@@ -53,8 +54,7 @@ func Create(config *Config, schedules []*calendar.Event, permission Permission)
return fmt.Errorf("cannot delete existing task to replace it: %w", err)
}
}
-
- task := createTaskDefinition(config, schedules)
+ task := createTaskDefinition(config, schedules, time.Time{})
task.RegistrationInfo.URI = taskPath
switch config.RunLevel {
@@ -181,8 +181,12 @@ func getTaskPath(profileName, commandName string) string {
return fmt.Sprintf("%s%s %s", tasksPathPrefix, profileName, commandName)
}
-func createTaskDefinition(config *Config, schedules []*calendar.Event) Task {
- task := NewTask()
+func createTaskDefinition(config *Config, schedules []*calendar.Event, from time.Time) Task {
+ options := make([]TaskOption, 0, 1)
+ if !from.IsZero() {
+ options = append(options, WithFromNow(from))
+ }
+ task := NewTask(options...)
task.RegistrationInfo.Description = config.JobDescription
task.AddExecAction(ExecAction{
Command: config.Command,
diff --git a/schtasks/taskscheduler_test.go b/schtasks/taskscheduler_test.go
index 6c4d0359..d751fa85 100644
--- a/schtasks/taskscheduler_test.go
+++ b/schtasks/taskscheduler_test.go
@@ -125,98 +125,131 @@ func TestTaskSchedulerIntegration(t *testing.T) {
fixtures := []struct {
description string
schedules []string
+ fromNow time.Time
}{
{
"only once",
[]string{"2020-01-02 03:04"},
+ time.Time{},
},
// daily
{
"once every day",
[]string{"*-*-* 03:04"},
+ time.Time{},
},
{
"every hour",
[]string{"*-*-* *:04"},
+ time.Time{},
},
{
"every minute",
[]string{"*-*-* *:*"},
+ time.Time{},
},
{
- "every minute at 12",
+ "every minute at 12 (before 12)",
[]string{"*-*-* 12:*"},
+ time.Date(2025, 7, 27, 11, 20, 0, 0, time.UTC),
+ },
+ // this creates 60 triggers
+ // {
+ // "every minute at 12",
+ // []string{"*-*-* 12:*"},
+ // time.Date(2025, 7, 27, 12, 20, 0, 0, time.UTC),
+ // },
+ {
+ "every minute at 12 (after 12)",
+ []string{"*-*-* 12:*"},
+ time.Date(2025, 7, 27, 13, 20, 0, 0, time.UTC),
},
// daily - more than one
{
"three times a day",
[]string{"*-*-* 03..05:04"},
+ time.Time{},
},
{
"twice every hour",
[]string{"*-*-* *:04..05"},
+ time.Time{},
},
// weekly
{
"once weekly",
[]string{"mon *-*-* 03:04"},
+ time.Time{},
},
{
"every hour on mondays",
[]string{strings.ToLower(fixedDay)[:3] + " *-*-* *:04"},
+ time.Time{},
},
{
"every minute on mondays",
[]string{strings.ToLower(fixedDay)[:3] + " *-*-* *:*"},
+ time.Time{},
},
{
"every minute at 12 on mondays",
[]string{"mon *-*-* 12:*"},
+ time.Time{},
},
// more than once weekly
{
"twice weekly",
[]string{"mon *-*-* 03..04:04"},
+ time.Time{},
},
{
"twice mondays and tuesdays",
[]string{"mon,tue *-*-* 03:04..06"},
+ time.Time{},
},
{
"twice on fridays",
[]string{"fri *-*-* *:04..05"},
+ time.Time{},
},
// monthly
{
"once monthly",
[]string{"*-01-* 03:04"},
+ time.Time{},
},
{
"every hour in january",
[]string{"*-01-* *:04"},
+ time.Time{},
},
// monthly with weekdays
{
"mondays in January",
[]string{"mon *-01-* 03:04"},
+ time.Time{},
},
{
"every hour on Mondays in january",
[]string{"mon *-01-* *:04"},
+ time.Time{},
},
// some days every month
{
"one day per month",
[]string{"*-*-0" + dayOfTheMonth + " 03:04"},
+ time.Time{},
},
{
"every hour on the 1st of each month",
[]string{"*-*-0" + dayOfTheMonth + " *:04"},
+ time.Time{},
},
// more than once per month
{
"twice in one day per month",
[]string{"*-*-0" + dayOfTheMonth + " 03..04:04"},
+ time.Time{},
},
}
@@ -247,13 +280,15 @@ func TestTaskSchedulerIntegration(t *testing.T) {
defer file.Close()
taskPath := getTaskPath(config.ProfileName, config.CommandName)
- sourceTask := createTaskDefinition(config, schedules)
+ sourceTask := createTaskDefinition(config, schedules, fixture.fromNow)
sourceTask.RegistrationInfo.URI = taskPath
err = createTaskFile(sourceTask, file)
require.NoError(t, err)
file.Close()
+ t.Logf("task contains %d time triggers and %d calendar triggers", len(sourceTask.Triggers.TimeTrigger), len(sourceTask.Triggers.CalendarTrigger))
+
result, err := createTask(taskPath, file.Name(), "", "")
t.Log(result)
require.NoError(t, err)
@@ -271,6 +306,9 @@ func TestTaskSchedulerIntegration(t *testing.T) {
err = decoder.Decode(&readTask)
require.NoError(t, err)
+ sourceTask.fromNow = time.Time{} // ignore fromNow in the source task
+ taskInUTC(&sourceTask)
+ taskInUTC(readTask)
assert.Equal(t, sourceTask, *readTask)
result, err = deleteTask(taskPath)
@@ -287,3 +325,21 @@ func TestRunLevelOption(t *testing.T) {
// see related: https://github.com/creativeprojects/resticprofile/issues/545
// TODO: implement test when possible
}
+
+func taskInUTC(task *Task) {
+ // Windows Task Scheduler is using the current timezone when loading dates into the XML definition.
+ // This is a workaround to ensure that the tests run consistently.
+ for i := range task.Triggers.TimeTrigger {
+ if task.Triggers.TimeTrigger[i].StartBoundary != nil {
+ *task.Triggers.TimeTrigger[i].StartBoundary = task.Triggers.TimeTrigger[i].StartBoundary.UTC()
+ }
+ }
+ for i := range task.Triggers.CalendarTrigger {
+ if task.Triggers.CalendarTrigger[i].StartBoundary != nil {
+ *task.Triggers.CalendarTrigger[i].StartBoundary = task.Triggers.CalendarTrigger[i].StartBoundary.UTC()
+ }
+ if task.Triggers.CalendarTrigger[i].EndBoundary != nil {
+ *task.Triggers.CalendarTrigger[i].EndBoundary = task.Triggers.CalendarTrigger[i].EndBoundary.UTC()
+ }
+ }
+}
diff --git a/schtasks/trigger.go b/schtasks/trigger.go
index e855f314..d28a4d04 100644
--- a/schtasks/trigger.go
+++ b/schtasks/trigger.go
@@ -3,6 +3,8 @@
package schtasks
import (
+ "time"
+
"github.com/rickb777/period"
)
@@ -13,14 +15,14 @@ type Triggers struct {
type TimeTrigger struct {
Enabled *bool `xml:"Enabled"` // indicates whether the trigger is enabled
- StartBoundary string `xml:"StartBoundary"`
+ StartBoundary *time.Time `xml:"StartBoundary"`
ExecutionTimeLimit *period.Period `xml:"ExecutionTimeLimit"`
RandomDelay *period.Period `xml:"RandomDelay,omitempty"` // a delay time that is randomly added to the start time of the trigger
}
type CalendarTrigger struct {
- StartBoundary string `xml:"StartBoundary,omitempty"` // the date and time when the trigger is activated
- EndBoundary string `xml:"EndBoundary,omitempty"` // the date and time when the trigger is deactivated
+ StartBoundary *time.Time `xml:"StartBoundary,omitempty"` // the date and time when the trigger is activated
+ EndBoundary *time.Time `xml:"EndBoundary,omitempty"` // the date and time when the trigger is deactivated
Repetition *RepetitionPattern `xml:"Repetition"`
ExecutionTimeLimit *period.Period `xml:"ExecutionTimeLimit"` // the maximum amount of time that the task launched by this trigger is allowed to run
Enabled *bool `xml:"Enabled"` // indicates whether the trigger is enabled
diff --git a/schtasks/trigger_test.go b/schtasks/trigger_test.go
index 76acb60f..7ff269c9 100644
--- a/schtasks/trigger_test.go
+++ b/schtasks/trigger_test.go
@@ -32,145 +32,183 @@ func TestTriggerCreationFromXML(t *testing.T) {
fixedDay = "Tuesday"
}
+ timezone := `(Z|[+-]\d{2}:\d{2})`
+
fixtures := []struct {
description string
schedules []string
expected string
expectedMatchCount int
+ from time.Time
}{
{
"only once",
[]string{"2020-01-02 03:04"},
- `\s*2020-01-02T03:04:00\+00:00\s*`,
+ `\s*2020-01-02T03:04:00` + timezone + `\s*`,
1,
+ time.Time{},
},
// daily
{
"once every day",
[]string{"*-*-* 03:04"},
- `\s*\d{4}-\d{2}-\d{2}T03:04:00\+00:00\s*\s*1\s*\s*`,
+ `\s*\d{4}-\d{2}-\d{2}T03:04:00` + timezone + `\s*\s*1\s*\s*`,
1,
+ time.Time{},
},
{
"every hour",
[]string{"*-*-* *:04"},
- `\s*\d{4}-\d{2}-\d{2}T\d{2}:04:00\+00:00\s*\s*PT1H\s*PT23H\s*\s*\s*1\s*\s*`,
+ `\s*\d{4}-\d{2}-\d{2}T\d{2}:04:00` + timezone + `\s*\s*PT1H\s*PT23H\s*\s*\s*1\s*\s*`,
1,
+ time.Time{},
},
{
"every minute",
[]string{"*-*-* *:*"},
- `\s*\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:00\+00:00\s*\s*PT1M\s*P1D\s*\s*\s*1\s*\s*`,
+ `\s*\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:00` + timezone + `\s*\s*PT1M\s*P1D\s*\s*\s*1\s*\s*`,
1,
+ time.Time{},
},
+ // {
+ // "every minute at 12 (before 12)",
+ // []string{"*-*-* 12:*"},
+ // `\s*\d{4}-\d{2}-\d{2}T11:\d{2}:00` + timezone + `\s*\s*PT1M\s*PT59M\s*\s*\s*1\s*\s*`,
+ // 1,
+ // time.Date(2025, 7, 27, 11, 20, 0, 0, time.UTC),
+ // },
+ // {
+ // "every minute at 12",
+ // []string{"*-*-* 12:*"},
+ // `\s*\d{4}-\d{2}-\d{2}T12:\d{2}:00` + timezone + `\s*\s*PT1M\s*PT59M\s*\s*\s*1\s*\s*`,
+ // 1,
+ // time.Date(2025, 7, 27, 12, 20, 0, 0, time.UTC),
+ // },
{
- "every minute at 12",
+ "every minute at 12 (after 12)",
[]string{"*-*-* 12:*"},
- `\s*\d{4}-\d{2}-\d{2}T12:\d{2}:00\+00:00\s*\s*PT1M\s*PT59M\s*\s*\s*1\s*\s*`,
+ `\s*\d{4}-\d{2}-\d{2}T13:\d{2}:00` + timezone + `\s*\s*PT1M\s*PT59M\s*\s*\s*1\s*\s*`,
1,
+ time.Date(2025, 7, 27, 13, 20, 0, 0, time.UTC),
},
// daily - more than one
{
"three times a day",
[]string{"*-*-* 03..05:04"},
- `\s*\d{4}-\d{2}-\d{2}T03:04:00\+00:00\s*\s*PT1H\s*PT2H\s*\s*\s*1\s*\s*`,
+ `\s*\d{4}-\d{2}-\d{2}T03:04:00` + timezone + `\s*\s*PT1H\s*PT2H\s*\s*\s*1\s*\s*`,
1,
+ time.Time{},
},
{
"twice every hour",
[]string{"*-*-* *:04..05"},
- `\s*\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:00\+00:00\s*\s*1\s*\s*`,
+ `\s*\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:00` + timezone + `\s*\s*1\s*\s*`,
48,
+ time.Time{},
},
// weekly
{
"once weekly",
[]string{"mon *-*-* 03:04"},
- `\s*\d{4}-\d{2}-\d{2}T03:04:00\+00:00\s*\s*1\s*\s*\s*\s*\s*`,
+ `\s*\d{4}-\d{2}-\d{2}T03:04:00` + timezone + `\s*\s*1\s*\s*\s*\s*\s*`,
1,
+ time.Time{},
},
{
"every hour on mondays",
[]string{strings.ToLower(fixedDay)[:3] + " *-*-* *:04"},
- `\s*\d{4}-\d{2}-\d{2}T\d{2}:04:00\+00:00\s*\s*PT1H\s*PT23H\s*\s*\s*1\s*\s*<` + fixedDay + `>` + fixedDay + `>\s*\s*\s*`,
+ `\s*\d{4}-\d{2}-\d{2}T\d{2}:04:00` + timezone + `\s*\s*PT1H\s*PT23H\s*\s*\s*1\s*\s*<` + fixedDay + `>` + fixedDay + `>\s*\s*\s*`,
1,
+ time.Time{},
},
{
"every minute on mondays",
[]string{strings.ToLower(fixedDay)[:3] + " *-*-* *:*"},
- `\s*\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:00\+00:00\s*\s*PT1M\s*P1D\s*\s*\s*1\s*\s*<` + fixedDay + `>` + fixedDay + `>\s*\s*\s*`,
+ `\s*\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:00` + timezone + `\s*\s*PT1M\s*P1D\s*\s*\s*1\s*\s*<` + fixedDay + `>` + fixedDay + `>\s*\s*\s*`,
1,
+ time.Time{},
},
{
"every minute at 12 on mondays",
[]string{"mon *-*-* 12:*"},
- `\s*\d{4}-\d{2}-\d{2}T12:\d{2}:00\+00:00\s*\s*PT1M\s*PT59M\s*\s*\s*1\s*\s*\s*\s*\s*`,
+ `\s*\d{4}-\d{2}-\d{2}T12:\d{2}:00` + timezone + `\s*\s*PT1M\s*PT59M\s*\s*\s*1\s*\s*\s*\s*\s*`,
1,
+ time.Time{},
},
// more than once weekly
{
"twice weekly",
[]string{"mon *-*-* 03..04:04"},
- `\s*\d{4}-\d{2}-\d{2}T03:04:00\+00:00\s*\s*PT1H\s*PT1H\s*\s*\s*1\s*\s*\s*\s*\s*`,
+ `\s*\d{4}-\d{2}-\d{2}T03:04:00` + timezone + `\s*\s*PT1H\s*PT1H\s*\s*\s*1\s*\s*\s*\s*\s*`,
1,
+ time.Time{},
},
{
"twice mondays and tuesdays",
[]string{"mon,tue *-*-* 03:04..06"},
- `\s*\d{4}-\d{2}-\d{2}T03:04:00\+00:00\s*\s*PT1M\s*PT2M\s*\s*\s*1\s*\s*\s*\s*\s*\s*`,
+ `\s*\d{4}-\d{2}-\d{2}T03:04:00` + timezone + `\s*\s*PT1M\s*PT2M\s*\s*\s*1\s*\s*\s*\s*\s*\s*`,
1,
+ time.Time{},
},
{
"twice on fixed day",
[]string{strings.ToLower(fixedDay)[:3] + " *-*-* *:04..05"},
- `\s*\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:00\+00:00\s*\s*1\s*\s*<` + fixedDay + `>` + fixedDay + `>\s*\s*\s*`,
+ `\s*\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:00` + timezone + `\s*\s*1\s*\s*<` + fixedDay + `>` + fixedDay + `>\s*\s*\s*`,
48,
+ time.Time{},
},
// monthly
{
"once monthly",
[]string{"*-01-* 03:04"},
- `\s*\d{4}-01-\d{2}T03:04:00\+00:00\s*\s*\s*\s*\s*\s*` + generateEveryDayString() + `\s*\s*`,
+ `\s*\d{4}-01-\d{2}T03:04:00` + timezone + `\s*\s*\s*\s*\s*\s*` + generateEveryDayString() + `\s*\s*`,
1,
+ time.Time{},
},
{
"every hour in january",
[]string{"*-01-* *:04"},
- `\s*\d{4}-01-\d{2}T\d{2}:04:00\+00:00\s*\s*\s*\s*\s*\s*` + generateEveryDayString() + `\s*\s*`,
+ `\s*\d{4}-01-\d{2}T\d{2}:04:00` + timezone + `\s*\s*\s*\s*\s*\s*` + generateEveryDayString() + `\s*\s*`,
24,
+ time.Time{},
},
// monthly with weekdays
{
"mondays in January",
[]string{"mon *-01-* 03:04"},
- `\s*\d{4}-01-\d{2}T03:04:00\+00:00\s*\s*\s*\s*\s*\s*1\s*2\s*3\s*4\s*Last\s*\s*\s*\s*\s*\s*`,
+ `\s*\d{4}-01-\d{2}T03:04:00` + timezone + `\s*\s*\s*\s*\s*\s*1\s*2\s*3\s*4\s*Last\s*\s*\s*\s*\s*\s*`,
1,
+ time.Time{},
},
{
"every hour on Mondays in january",
[]string{"mon *-01-* *:04"},
- `\s*\d{4}-01-\d{2}T\d{2}:04:00\+00:00\s*\s*\s*\s*\s*\s*1\s*2\s*3\s*4\s*Last\s*\s*\s*\s*\s*\s*`,
+ `\s*\d{4}-01-\d{2}T\d{2}:04:00` + timezone + `\s*\s*\s*\s*\s*\s*1\s*2\s*3\s*4\s*Last\s*\s*\s*\s*\s*\s*`,
24,
+ time.Time{},
},
// // some days every month
{
"one day per month",
[]string{"*-*-0" + dayOfTheMonth + " 03:04"},
- `\s*\d{4}-\d{2}-0` + dayOfTheMonth + `T03:04:00\+00:00\s*\s*\s*` + generateEveryMonthString() + `\s*\s*` + dayOfTheMonth + `\s*\s*\s*`,
+ `\s*\d{4}-\d{2}-0` + dayOfTheMonth + `T03:04:00` + timezone + `\s*\s*\s*` + generateEveryMonthString() + `\s*\s*` + dayOfTheMonth + `\s*\s*\s*`,
1,
+ time.Time{},
},
{
"every hour on the 1st of each month",
[]string{"*-*-0" + dayOfTheMonth + " *:04"},
- `\s*\d{4}-\d{2}-0` + dayOfTheMonth + `T\d{2}:04:00\+00:00\s*\s*\s*` + generateEveryMonthString() + `\s*\s*` + dayOfTheMonth + `\s*\s*\s*`,
+ `\s*\d{4}-\d{2}-0` + dayOfTheMonth + `T\d{2}:04:00` + timezone + `\s*\s*\s*` + generateEveryMonthString() + `\s*\s*` + dayOfTheMonth + `\s*\s*\s*`,
24, // 1 per hour
+ time.Time{},
},
// // more than once per month
{
"twice in one day per month",
[]string{"*-*-0" + dayOfTheMonth + " 03..04:04"},
- `\s*\d{4}-\d{2}-0` + dayOfTheMonth + `T\d{2}:04:00\+00:00\s*\s*\s*` + generateEveryMonthString() + `\s*\s*` + dayOfTheMonth + `\s*\s*\s*`,
+ `\s*\d{4}-\d{2}-0` + dayOfTheMonth + `T\d{2}:04:00` + timezone + `\s*\s*\s*` + generateEveryMonthString() + `\s*\s*` + dayOfTheMonth + `\s*\s*\s*`,
2,
+ time.Time{},
},
}
@@ -196,7 +234,8 @@ func TestTriggerCreationFromXML(t *testing.T) {
schedules[index] = event
}
buffer := &bytes.Buffer{}
- task := createTaskDefinition(scheduleConfig, schedules)
+ task := createTaskDefinition(scheduleConfig, schedules, fixture.from)
+ taskInLocal(&task)
err = createTaskFile(task, buffer)
require.NoError(t, err)
@@ -226,3 +265,19 @@ func generateEveryMonthString() string {
}
return everyMonth
}
+
+func taskInLocal(task *Task) {
+ for i := range task.Triggers.TimeTrigger {
+ if task.Triggers.TimeTrigger[i].StartBoundary != nil {
+ *task.Triggers.TimeTrigger[i].StartBoundary = task.Triggers.TimeTrigger[i].StartBoundary.Local()
+ }
+ }
+ for i := range task.Triggers.CalendarTrigger {
+ if task.Triggers.CalendarTrigger[i].StartBoundary != nil {
+ *task.Triggers.CalendarTrigger[i].StartBoundary = task.Triggers.CalendarTrigger[i].StartBoundary.Local()
+ }
+ if task.Triggers.CalendarTrigger[i].EndBoundary != nil {
+ *task.Triggers.CalendarTrigger[i].EndBoundary = task.Triggers.CalendarTrigger[i].EndBoundary.Local()
+ }
+ }
+}