/timex-interval

A date/time interval library for Elixir projects, based on Timex.

Primary LanguageElixirApache License 2.0Apache-2.0

Timex Interval

NOTE: This project has been merged into Timex, as Timex.Interval, as of 1.0.0-pre. If you are on that version of Timex or higher, it is recommended you use that instead. However for prior releases of Timex, this project is still actively maintained :)

hex.pm version travis.ci build status

Timex Interval is an extension of Timex that deals with date/time intervals.

Intervals are enumerable, making them useful to iterate over time intervals, for instance every day between two dates.

Constructors

The DateTimeInterval module provides a helper function to make new intervals.

Valid keywords:

  • from: the date the interval starts at (defaults to Date.now())
  • until: either the date the interval ends at, or a time shift that will be applied to the "from" date (defaults to [days: 7])
  • left_open: whether the interval is left open, defaults to #{@default_left_open}
  • right_open: whether the interval is right open, defaults to #{@default_right_open}
  • step: the iteration step for enumerations, defaults to [days: 1]

Time shifts should be keyword lists valid for use with Timex.Date.shift.

use Timex
alias TimexInterval.DateTimeInterval, as: Interval

Interval.new(from: Date.from({2014, 9, 22}), until: Date.from({2014, 9, 29}))
|> Interval.format!("%Y-%m-%d")
#=> "[2014-09-22, 2014-09-29)"

Interval.new(from: Date.from({2014, 9, 22}), until: [months: 5])
|> Interval.format!("%Y-%m-%d")
#=> "[2014-09-22, 2015-02-22)"

Interval.new(from: Date.from({{2014, 9, 22}, {15, 30, 0}}), until: [mins: 20], right_open: false)
|> Interval.format!("%H:%M")
#=> "[15:30, 15:50]"

Note that by default intervals are right open.

Iterators

DateTimeInterval implements the Enumerable protocol.

use Timex
alias TimexInterval.DateTimeInterval, as: Interval

Interval.new(from: Date.from({2014, 9, 22}), until: [days: 3])
|> Enum.map(fn(dt) -> DateFormat.format!(dt, "%Y-%m-%d", :strftime) end)
#=> ["2014-09-22", "2014-09-23", "2014-09-24"]

You can easily specify whether to exclude the first and last dates:

Interval.new(from: Date.from({2014, 9, 22}), until: [days: 3], right_open: false)
|> Enum.map(fn(dt) -> DateFormat.format!(dt, "%Y-%m-%d", :strftime) end)
#=> ["2014-09-22", "2014-09-23", "2014-09-24", "2014-09-25"]

You can of course iterate over anything else, for instance by chunks of 10 minutes:

Interval.new(from: Date.from({{2014, 9, 22}, {15, 0, 0}}), until: [hours: 1])
|> Interval.with_step(mins: 10)
|> Enum.map(fn(dt) -> DateFormat.format!(dt, "%H:%M", :strftime) end)
#=> ["15:00", "15:10", "15:20", "15:30", "15:40", "15:50"]

Duration

You can query an interval to know its duration, given a time unit.

When the unit is one of :secs, :mins, :hours, :days, :weeks, :months, :years, the result is an integer.

When the unit is :timestamp, the result is a tuple representing a valid Timex.Time.

use Timex
alias TimexInterval.DateTimeInterval, as: Interval

Interval.new(from: Date.from({2014, 9, 22}), until: [months: 5])
|> Interval.duration(:months)
#=> 5

Interval.new(from: Date.from({{2014, 9, 22}, {15, 30, 0}}), until: [mins: 20])
|> Interval.duration(:timestamp)
#=> {0, 0, 1200}