Skip to content

Latest commit

 

History

History
97 lines (83 loc) · 2.2 KB

README.md

File metadata and controls

97 lines (83 loc) · 2.2 KB

te

Package te implements temporal expressions.

An expression is an implementation of the Expression interface. Two methods must be implemented: IsActive which returns true if the expression is active at the given time, and Next which returns the next active time.

A handful of expressions are included. They compute the next time within the location of the given time. Daylight savings is respected.

To find the first day of the month:

expr := te.Day(1)
next := time.Now()
for i := 0; i < 4; i++ {
  next = expr.Next(next)
  fmt.Println(next)
}
// 2020-09-01 00:00:00 -0400 EDT
// 2020-10-01 00:00:00 -0400 EDT
// 2020-11-01 00:00:00 -0400 EDT
// 2020-12-01 00:00:00 -0500 EST

To find every day at 4am:

expr := te.Hour(4)
next := time.Now()
for i := 0; i < 4; i++ {
  next = expr.Next(next)
  fmt.Println(next)
}
// 2020-09-01 04:00:00 -0400 EDT
// 2020-09-02 04:00:00 -0400 EDT
// 2020-09-03 04:00:00 -0400 EDT
// 2020-09-04 04:00:00 -0400 EDT

Complex expressions can be composed from more primitive expressions. For example, one can continuously generate time.Times for every 3rd or 5th of the month that falls on a Thursday or Friday except in February and December.

expr := te.Intersect(
  te.Union(
    te.Day(3),
    te.Day(5),
  ),
  te.Union(
    te.Weekday(time.Thursday),
    te.Weekday(time.Friday),
  ),
  te.Except(
    te.Union(
      te.Month(time.February),
      te.Month(time.December),
    ),
  ),
)
next := time.Now()
for i := 0; i < 4; i++ {
  next = expr.Next(next)
  fmt.Println(next)
}
// 2020-09-03 00:00:00 -0400 EDT
// 2020-11-05 00:00:00 -0500 EST
// 2021-03-05 00:00:00 -0500 EST
// 2021-06-03 00:00:00 -0400 EDT

Limited expression parsing is supported:

expr, err := te.Parse("Tue/Thu at 4am", time.Local)
if err != nil {
  log.Fatal(err)
}
next := time.Now()
for i := 0; i < 4; i++ {
  next = expr.Next(next)
  fmt.Println(next)
}
// 2020-09-01 04:00:00 -0400 EDT
// 2020-09-03 04:00:00 -0400 EDT
// 2020-09-08 04:00:00 -0400 EDT
// 2020-09-10 04:00:00 -0400 EDT

See parser_test.go for more examples.

Inspiration

This package is inspired by a paper on Recurring Events for Calendars written by Martin Fowler. https://martinfowler.com/apsupp/recurring.pdf