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 :)
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.
The DateTimeInterval
module provides a helper function to make new intervals.
Valid keywords:
from
: the date the interval starts at (defaults toDate.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.
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"]
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}