View Source Timex (timex v3.7.8)

timex

Timex

Master Hex.pm Version Coverage Status

Timex is a rich, comprehensive Date/Time library for Elixir projects, with full timezone support via the :tzdata package. If you need to manipulate dates, times, datetimes, timestamps, etc., then Timex is for you! It is very easy to use Timex types in place of default Erlang types, as well as Ecto types via the timex_ecto package.

The complete documentation for Timex is located here.

migrating-to-timex-3-x

Migrating to Timex 3.x

If you are coming from an earlier version of Timex, it is recommended that you evaluate whether or not the functionality provided by the standard library Calendar API is sufficient for your needs, as you may be able to avoid the dependency entirely.

For those that require Timex for one reason or another, Timex now delegates to the standard library where possible, and provides backward compatibility to Elixir 1.8 for APIs which are used. This is to avoid duplicating effort, and to ease the maintenance of this library in the future. Take a look at the documentation to see what APIs are available and how to use them. Many of them may have changed, been removed/renamed, or have had their semantics improved since early versions of the library, so if you are coming from an earlier version, you will need to review how you are using various APIs. The CHANGELOG is a helpful document to sort through what has changed in general.

Timex is primarily oriented around the Olson timezone database, and so you are encouraged to use those timezones in favor of alternatives. Timex does provide compatibility with the POSIX-TZ standard, which allows specification of custom timezones, see this document for more information. Timex does not provide support for timezones which do not adhere to one of those two standards. While Timex attempted to support timezone abbreviations without context in prior versions, this was broken, and has been removed.

getting-started

Getting Started

There are some brief examples on usage below, but I highly recommend you review the API docs here, there are many examples, and some extra pages with richer documentation on specific subjects such as custom formatters/parsers, etc.

quickfast-introduction

Quickfast introduction

To use Timex, I recommend you add use Timex to the top of the module where you will be working with Timex modules, all it does is alias common types so you can work with them more comfortably. If you want to see the specific aliases added, check the top of the Timex module, in the __using__/1 macro definition.

Here's a few simple examples:

> use Timex
> Timex.today()
~D[2016-02-29]

> datetime = Timex.now()
#<DateTime(2016-02-29T12:30:30.120+00:00Z Etc/UTC)

> Timex.now("America/Chicago")
#<DateTime(2016-02-29T06:30:30.120-06:00 America/Chicago)

> Duration.now()
#<Duration(P46Y6M24DT21H57M33.977711S)>

> {:ok, default_str} = Timex.format(datetime, "{ISO:Extended}")
{:ok, "2016-02-29T12:30:30.120+00:00"}

> {:ok, relative_str} = Timex.shift(datetime, minutes: -3) |> Timex.format("{relative}", :relative)
{:ok, "3 minutes ago"}

> strftime_str = Timex.format!(datetime, "%FT%T%:z", :strftime)
"2016-02-29T12:30:30+00:00"

> Timex.parse(strftime_str, "{ISO:Extended}")
{:ok, #<DateTime(2016-02-29T12:30:30.120+00:00 Etc/Utc)}

> Timex.parse!(strftime_str, "%FT%T%:z", :strftime)
#<DateTime(2016-02-29T12:30:30.120+00:00 Etc/Utc)

> Duration.diff(Duration.now(), Duration.zero(), :days)
16850

> Timex.shift(date, days: 3)
~D[2016-03-03]

> Timex.shift(datetime, hours: 2, minutes: 13)
#<DateTime(2016-02-29T14:43:30.120Z Etc/UTC)>

> timezone = Timezone.get("America/Chicago", Timex.now())
#<TimezoneInfo(America/Chicago - CDT (-06:00:00))>

> Timezone.convert(datetime, timezone)
#<DateTime(2016-02-29T06:30:30.120-06:00 America/Chicago)>

> Timex.before?(Timex.today(), Timex.shift(Timex.today, days: 1))
true

> Timex.before?(Timex.shift(Timex.today(), days: 1), Timex.today())
false

> interval = Timex.Interval.new(from: ~D[2016-03-03], until: [days: 3])
%Timex.Interval{from: ~N[2016-03-03 00:00:00], left_open: false,
 right_open: true, step: [days: 1], until: ~N[2016-03-06 00:00:00]}

> ~D[2016-03-04] in interval
true

> ~N[2016-03-04 00:00:00] in interval
true

> ~N[2016-03-02 00:00:00] in interval
false

> Timex.Interval.overlaps?(Timex.Interval.new(from: ~D[2016-03-04], until: [days: 1]), interval)
true

> Timex.Interval.overlaps?(Timex.Interval.new(from: ~D[2016-03-07], until: [days: 1]), interval)
false

There are a ton of other functions, all of which work with Erlang datetime tuples, Date, NaiveDateTime, and DateTime. The Duration module contains functions for working with Durations, including Erlang timestamps (such as those returned from :timer.tc)

extensibility

Extensibility

Timex exposes a number of extension points for you, in order to accommodate different use cases:

Timex itself defines its core operations on the Date, DateTime, and NaiveDateTime types using the Timex.Protocol protocol. From there, all other Timex functionality is derived. If you have custom date/datetime types you want to use with Timex, this is the protocol you would need to implement.

Timex also defines a Timex.Comparable protocol, which you can extend to add comparisons to custom date/datetime types.

You can provide your own formatter/parser for datetime strings by implementing the Timex.Format.DateTime.Formatter and/or Timex.Parse.DateTime.Parser behaviours, depending on your needs.

timex-with-escript

Timex with escript

If you need to use Timex from within an escript, add {:tzdata, "~> 0.1.8", override: true} to your deps, more recent versions of :tzdata are unable to work in an escript because of the need to load ETS table files from priv, and due to the way ETS loads these files, it's not possible to do so.

If your build still throws an error after this, try removing the _build and deps folder. Then execute mix deps.unlock tzdata and mix deps.get.

automatic-time-zone-updates

Automatic time zone updates

Timex includes the Tzdata library for time zone data. Tzdata has an automatic update capability that fetches updates from IANA and which is enabled by default; if you want to disable it, check the Tzdata documentation for details.

license

License

This software is licensed under the MIT license.

Link to this section Summary

Functions

Add time to a date using a Duration Same as shift(date, Duration.from_minutes(5), :duration).

Returns a boolean indicating whether the first Timex.Comparable occurs after the second

Returns a boolean indicating whether the first Timex.Comparable occurs before the second

Returns a DateTime representing the beginning of the day

Given a date returns a date at the beginning of the month.

Same as beginning_of_month/1, except takes year and month as distinct arguments

Given a date returns a date at the beginning of the quarter.

Shifts the date to the beginning of the week

Given a date or a number create a date at the beginning of that year

Returns a boolean indicating whether the first Timex.Comparable occurs between the second and third.

Gets the current century

Given a date, get the century this date is in.

See docs for compare/3

Compare two Timex.Comparable values, returning one of the following values

Returns the ordinal day number of the date.

Get the name of the day corresponding to the provided number

Get the short name of the day corresponding to the provided number

Get the day of the week corresponding to the given name.

Return the number of days in the month which the date falls on.

Same as days_in_month/2, except takes year and month as distinct arguments

Number of days to the beginning of the week

Number of days to the end of the week.

See docs for diff/3

Calculate time interval between two dates. The result will be a signed integer, negative if the first date/time comes before the second, and positive if the first date/time comes after the second.

Returns a DateTime representing the end of the day

Given a date returns a date at the end of the month.

Same as end_of_month/1, except takes year and month as distinct arguments

Given a date or a year and month returns a date at the end of the quarter.

Same as end_of_quarter/1, except takes year and month as distinct arguments

Returns a Date or a DateTime representing the end of the week, depending on the input, i.e. if you pass a date/time value which represents just a date, you will get back a Date, if both a date and time are present, you will get back a DateTime

Given a date or a number create a date at the end of that year

Returns a Date representing the start of the UNIX epoch

Returns a boolean indicating whether the two Timex.Comparable values are equivalent.

Same as format/2, except it returns only the value (not a tuple) and raises on error.

Same as format/3, except it returns only the value (not a tuple) and raises on error.

Formats a date/time value using the given format string (and optional formatter).

Same as format/2, except using a custom formatter

Formats an Erlang timestamp using the ISO-8601 duration format, or optionally, with a custom formatter of your choosing.

Same as format_duration/1, except it also accepts a formatter

Convert an iso ordinal day number to the day it represents in the current year.

Same as from_iso_day/1, except you can expect the following based on the second parameter

Given an ISO triplet {year, week number, weekday}, convert it to a Date struct.

Formats a DateTime using a fuzzy relative duration, from now.

Formats a DateTime using a fuzzy relative duration, translated using given locale

Formats a DateTime using a fuzzy relative duration, with a reference datetime other than now, translated using the given locale

Return a boolean indicating whether the given year is a leap year. You may pass a date or a year number.

Returns a boolean indicating whether the provided term represents a valid time, valid times are one of

Returns a boolean indicating whether the provided term represents a valid timezone, valid timezones are one of

Return a boolean indicating whether the given date is valid.

Return a 3-tuple {year, week number, weekday} for the given Date/DateTime.

Return a pair {year, week number} (as defined by ISO 8601) that the given Date/DateTime value falls on.

Same as iso_week/1, except this takes a year, month, and day as distinct arguments.

Same as lformat/3, except local_format! raises on error.

Same as lformat/4, except local_format! raises on error.

Same as format/2, except takes a locale name to translate text to.

Same as lformat/3, except takes a formatter as it's last argument.

Same as format_duration/1, except takes a locale for use in translation

Same as lformat_duration/2, except takes a formatter as an argument

Returns a DateTime representing the current moment in time in the local timezone.

Returns a DateTime representing the given date/time in the local timezone

Get the name of the month corresponding to the provided number

Get the short name of the month corresponding to the provided number

Get the number of the month corresponding to the given name.

Given a unit to normalize, and the value to normalize, produces a valid value for that unit, clamped to whatever boundaries are defined for that unit.

Returns a DateTime representing the current moment in time in UTC

Returns a DateTime representing the current moment in time in the provided timezone.

Same as parse/2 and parse/3, except parse! raises on error.

Parses a datetime string into a DateTime struct, using the provided format string (and optional tokenizer).

Returns what quarter of the year the given date/time falls in.

Return a new date/time value with the specified fields replaced by new values.

A single function for adjusting the date using various units: duration, microseconds, seconds, minutes, hours, days, weeks, months, years.

Subtract time from a date using a Duration Same as shift(date, Duration.from_minutes(5) |> Duration.invert, :timestamp).

Get a TimezoneInfo object for the specified offset or name.

Returns a list of all valid timezone names in the Olson database

Convert a date/time value to a Date struct.

Convert a date/time value and timezone name to a DateTime struct.

Convert a date/time value to it's Erlang representation

Convert a date/time value to gregorian microseconds (microseconds since start of year zero)

Convert a date/time value to gregorian seconds (seconds since start of year zero)

Convert a date/time value to a Julian calendar date number

Convert a date/time value to a NaiveDateTime struct.

Convert a date/time value to seconds since the UNIX epoch

Returns a Date representing the current day in UTC

Returns a Date representing the current day in the provided timezone.

Given a format string, validates that the format string is valid for the Default formatter.

Returns the week number of the date provided, starting at 1.

Same as week_of_month/1, except takes year, month, and day as distinct arguments

Provides a version of weekday/1 and weekday/2 that raises on error.

Return weekday number (as defined by ISO 8601) of the specified date.

Like weekday/1, but accepts a valid starting weekday value.

Returns a Date representing the start of the Gregorian epoch

Link to this section Types

@type between_options() :: [{:inclusive, boolean() | :start | :end}]
@type set_options() :: [
  validate: boolean(),
  datetime: Timex.Types.datetime(),
  date: Timex.Types.valid_date(),
  time: Timex.Types.valid_time(),
  year: Timex.Types.year(),
  month: Timex.Types.month(),
  day: Timex.Types.day(),
  hour: Timex.Types.hour(),
  minute: Timex.Types.minute(),
  second: Timex.Types.second(),
  microsecond: Timex.Types.microsecond(),
  timezone: Timex.Types.valid_timezone()
]
@type shift_options() :: [
  microseconds: integer(),
  milliseconds: integer(),
  seconds: integer(),
  minutes: integer(),
  hours: integer(),
  days: integer(),
  weeks: integer(),
  months: integer(),
  years: integer(),
  duration: Timex.Duration.t()
]

Link to this section Functions

Add time to a date using a Duration Same as shift(date, Duration.from_minutes(5), :duration).

Returns a boolean indicating whether the first Timex.Comparable occurs after the second

Returns a boolean indicating whether the first Timex.Comparable occurs before the second

Link to this function

beginning_of_day(datetime)

View Source
@spec beginning_of_day(Timex.Types.valid_datetime()) ::
  Timex.Types.valid_datetime() | {:error, term()}

Returns a DateTime representing the beginning of the day

examples

Examples

iex> date = Timex.to_datetime({{2015, 1, 1}, {13, 14, 15}}, "Etc/UTC")
iex> Timex.beginning_of_day(date)
Timex.to_datetime({{2015, 1, 1}, {0, 0, 0}}, "Etc/UTC")

iex> date = ~D[2015-01-01]
...> Timex.beginning_of_day(date)
~D[2015-01-01]
Link to this function

beginning_of_month(datetime)

View Source
@spec beginning_of_month(Timex.Types.valid_datetime()) ::
  Timex.Types.valid_datetime() | {:error, term()}

Given a date returns a date at the beginning of the month.

iex> date = Timex.to_datetime({{2015, 6, 15}, {12,30,0}}, "Europe/Paris")
iex> Timex.beginning_of_month(date)
Timex.to_datetime({{2015, 6, 1}, {0, 0, 0}}, "Europe/Paris")
Link to this function

beginning_of_month(year, month)

View Source
@spec beginning_of_month(Timex.Types.year(), Timex.Types.month()) ::
  Date.t() | {:error, term()}

Same as beginning_of_month/1, except takes year and month as distinct arguments

Link to this function

beginning_of_quarter(datetime)

View Source
@spec beginning_of_quarter(Timex.Types.valid_datetime()) ::
  Timex.Types.valid_datetime() | {:error, term()}

Given a date returns a date at the beginning of the quarter.

iex> date = Timex.to_datetime({{2015, 6, 15}, {12,30,0}}, "America/Chicago")
iex> Timex.beginning_of_quarter(date)
Timex.to_datetime({{2015, 4, 1}, {0, 0, 0}}, "America/Chicago")
Link to this function

beginning_of_week(date, weekstart \\ :mon)

View Source
@spec beginning_of_week(Timex.Types.valid_datetime(), Timex.Types.weekstart()) ::
  Timex.Types.valid_datetime() | {:error, term()}

Shifts the date to the beginning of the week

The weekstart can between 1..7, an atom e.g. :mon, or a string e.g. "Monday"

examples

Examples

iex> date = ~N[2015-11-30T13:30:30] # Monday 30th November
iex> Timex.beginning_of_week(date)
~N[2015-11-30T00:00:00]

iex> date = ~D[2015-11-30] # Monday 30th November
iex> Timex.beginning_of_week(date, :sun)
~D[2015-11-29]
@spec beginning_of_year(Timex.Types.year() | Timex.Types.valid_datetime()) ::
  Timex.Types.valid_datetime() | {:error, term()}

Given a date or a number create a date at the beginning of that year

Examples

iex> date = ~N[2015-06-15T00:00:00]
iex> Timex.beginning_of_year(date)
~N[2015-01-01T00:00:00]

iex> Timex.beginning_of_year(2015)
~D[2015-01-01]
Link to this function

between?(a, start, ending, options \\ [])

View Source

Returns a boolean indicating whether the first Timex.Comparable occurs between the second and third.

If an error occurs, an error tuple will be returned.

By default, the start and end bounds are exclusive. You can opt for inclusive bounds with the inclusive: true option. To set just one of the bounds as inclusive, use the inclusive: :start or inclusive: :end option.

@spec century() :: non_neg_integer() | {:error, term()}

Gets the current century

examples

Examples

iex> Timex.century
21
@spec century(Timex.Types.year() | Timex.Types.valid_datetime()) ::
  non_neg_integer() | {:error, term()}

Given a date, get the century this date is in.

examples

Examples

iex> Timex.today |> Timex.century
21
iex> Timex.now |> Timex.century
21
iex> Timex.century(2016)
21

See docs for compare/3

Link to this function

compare(a, b, granularity)

View Source

Compare two Timex.Comparable values, returning one of the following values:

  • -1 -- the first date comes before the second one
  • 0 -- both arguments represent the same date when coalesced to the same timezone.
  • 1 -- the first date comes after the second one

You can provide a few reference constants for the second argument:

  • :epoch will compare the first parameter against the Date/DateTime of the first moment of the UNIX epoch
  • :zero will compare the first parameter against the Date/DateTime of the first moment of year zero
  • :distant_past will compare the first parameter against a date/time infinitely in the past (i.e. it will always return 1)
  • :distant_future will compare the first parameter against a date/time infinitely in the future (i.e. it will always return -1)

You can optionally specify a comparison granularity from the list below.

  • :year
  • :years
  • :month
  • :months
  • :week (an alias for 7 days)
  • :weeks
  • :calendar_week (weeks of the calendar as opposed to actual weeks in terms of days)
  • :calendar_weeks
  • :day (an alias for 24 hours)
  • :days
  • :hour
  • :hours
  • :minute
  • :minutes
  • :second
  • :seconds
  • :millisecond
  • :milliseconds
  • :microsecond (default)
  • :microseconds
  • :duration

examples

Examples

iex> date1 = ~D[2014-03-04]
iex> date2 = ~D[2015-03-04]
iex> Timex.compare(date1, date2, :year)
-1
iex> Timex.compare(date2, date1, :year)
1
iex> Timex.compare(date1, date1)
0
@spec day(Timex.Types.valid_datetime()) :: Timex.Types.daynum() | {:error, term()}

Returns the ordinal day number of the date.

examples

Examples

iex> Timex.day(~D[2015-06-26])
177
@spec day_name(Timex.Types.weekday()) ::
  String.t() | {:error, :invalid_weekday_number}

Get the name of the day corresponding to the provided number

examples

Examples

iex> Timex.day_name(1)
"Monday"
iex> Timex.day_name(0)
{:error, :invalid_weekday_number}
@spec day_shortname(Timex.Types.weekday()) ::
  String.t() | {:error, :invalid_weekday_number}

Get the short name of the day corresponding to the provided number

examples

Examples

iex> Timex.day_shortname(1)
"Mon"
iex> Timex.day_shortname(0)
{:error, :invalid_weekday_number}
@spec day_to_num(binary() | atom()) ::
  Timex.Types.weekday() | {:error, :invalid_day_name}

Get the day of the week corresponding to the given name.

The name can be given as a string of the weekday name or its first three characters (lowercase or capitalized) or as a corresponding atom (lowercase only).

examples

Examples

iex> Timex.day_to_num("Monday")
1
iex> Timex.day_to_num("monday")
1
iex> Timex.day_to_num("Mon")
1
iex> Timex.day_to_num("mon")
1
iex> Timex.day_to_num(:mon)
1
iex> Timex.day_to_num(:sunday)
7
@spec days_in_month(Timex.Types.valid_datetime()) ::
  Timex.Types.num_of_days() | {:error, term()}

Return the number of days in the month which the date falls on.

examples

Examples

iex> Timex.days_in_month(~D[1970-01-01])
31
Link to this function

days_in_month(year, month)

View Source
@spec days_in_month(Timex.Types.year(), Timex.Types.month()) ::
  Timex.Types.num_of_days() | {:error, term()}

Same as days_in_month/2, except takes year and month as distinct arguments

Link to this function

days_to_beginning_of_week(date, weekstart \\ 1)

View Source
@spec days_to_beginning_of_week(Timex.Types.valid_datetime(), Timex.Types.weekstart()) ::
  integer() | {:error, term()}

Number of days to the beginning of the week

The weekstart determines which is the first day of the week, defaults to monday. It can be a number between 1..7 (1 is monday, 7 is sunday), or any value accepted by day_to_num/1.

examples

Examples

iex> date = ~D[2015-11-30] # Monday 30th November
iex> Timex.days_to_beginning_of_week(date)
0

iex> date = ~D[2015-11-30] # Monday 30th November
iex> Timex.days_to_beginning_of_week(date, :sun)
1
Link to this function

days_to_end_of_week(date, weekstart \\ :mon)

View Source
@spec days_to_end_of_week(Timex.Types.valid_datetime(), Timex.Types.weekstart()) ::
  integer() | {:error, term()}

Number of days to the end of the week.

The weekstart can between 1..7, an atom e.g. :mon, or a string e.g. "Monday"

examples

Examples

Week starting Monday
iex> date = ~D[2015-11-30] # Monday 30th November
iex> Timex.days_to_end_of_week(date)
6

Week starting Sunday
iex> date = ~D[2015-11-30] # Monday 30th November
iex> Timex.days_to_end_of_week(date, :sun)
5

See docs for diff/3

Calculate time interval between two dates. The result will be a signed integer, negative if the first date/time comes before the second, and positive if the first date/time comes after the second.

You must specify one of the following units:

  • :year
  • :years
  • :month
  • :months
  • :week
  • :weeks
  • :calendar_week (weeks of the calendar as opposed to actual weeks in terms of days)
  • :calendar_weeks
  • :day
  • :days
  • :hour
  • :hours
  • :minute
  • :minutes
  • :second
  • :seconds
  • :millisecond
  • :milliseconds
  • :microsecond (default)
  • :microseconds
  • :duration

and the result will be an integer value of those units or a Duration.

@spec end_of_day(Timex.Types.valid_datetime()) ::
  Timex.Types.valid_datetime() | {:error, term()}

Returns a DateTime representing the end of the day

examples

Examples

iex> date = ~N[2015-01-01T13:14:15]
...> Timex.end_of_day(date)
~N[2015-01-01T23:59:59]
@spec end_of_month(Timex.Types.valid_datetime()) ::
  Timex.Types.valid_datetime() | {:error, term()}

Given a date returns a date at the end of the month.

iex> date = ~N[2015-06-15T12:30:00Z]
iex> Timex.end_of_month(date)
~N[2015-06-30T23:59:59Z]
Link to this function

end_of_month(year, month)

View Source
@spec end_of_month(Timex.Types.year(), Timex.Types.month()) :: Date.t()

Same as end_of_month/1, except takes year and month as distinct arguments

examples

Examples

iex> Timex.end_of_month(2016, 2)
~D[2016-02-29]
Link to this function

end_of_quarter(datetime)

View Source
@spec end_of_quarter(Timex.Types.valid_datetime()) ::
  Timex.Types.valid_datetime() | {:error, term()}

Given a date or a year and month returns a date at the end of the quarter.

iex> date = ~N[2015-06-15T12:30:00]
...> Timex.end_of_quarter(date)
~N[2015-06-30T23:59:59]

iex> Timex.end_of_quarter(2015, 4)
~D[2015-06-30]
Link to this function

end_of_quarter(year, month)

View Source
@spec end_of_quarter(Timex.Types.year(), Timex.Types.month()) ::
  Date.t() | {:error, term()}

Same as end_of_quarter/1, except takes year and month as distinct arguments

Link to this function

end_of_week(datetime, weekstart \\ 1)

View Source

Returns a Date or a DateTime representing the end of the week, depending on the input, i.e. if you pass a date/time value which represents just a date, you will get back a Date, if both a date and time are present, you will get back a DateTime

The weekstart can between 1..7, an atom e.g. :mon, or a string e.g. "Monday"

examples

Examples

iex> date = ~N[2015-11-30T13:30:30] # Monday 30th November
...> Timex.end_of_week(date)
~N[2015-12-06T23:59:59]

iex> date = ~D[2015-11-30] # Monday 30th November
...> Timex.end_of_week(date, :sun)
~D[2015-12-05]
@spec end_of_year(Timex.Types.year() | Timex.Types.valid_datetime()) ::
  Timex.Types.valid_datetime() | {:error, term()}

Given a date or a number create a date at the end of that year

Examples

iex> date = ~N[2015-06-15T00:00:00]
iex> Timex.end_of_year(date)
~N[2015-12-31T23:59:59]

iex> Timex.end_of_year(2015)
~D[2015-12-31]
@spec epoch() :: Date.t()

Returns a Date representing the start of the UNIX epoch

Link to this function

equal?(a, a, granularity \\ :seconds)

View Source

Returns a boolean indicating whether the two Timex.Comparable values are equivalent.

Equality here implies that the two Comparables represent the same moment in time (with the given granularity), not equality of the data structure.

The options for granularity is the same as for compare/3, defaults to :seconds.

examples

Examples

iex> date1 = ~D[2014-03-01]
...> date2 = ~D[2014-03-01]
...> Timex.equal?(date1, date2)
true

iex> date1 = ~D[2014-03-01]
...> date2 = Timex.to_datetime({2014, 3, 1}, "Etc/UTC")
...> Timex.equal?(date1, date2)
true
Link to this function

format!(datetime, format_string)

View Source
@spec format!(Timex.Types.valid_datetime(), format :: String.t()) ::
  String.t() | no_return()

Same as format/2, except it returns only the value (not a tuple) and raises on error.

examples

Examples

iex> date = ~D[2016-02-29]
...> Timex.format!(date, "{YYYY}-{0M}-{D}")
"2016-02-29"
Link to this function

format!(datetime, format_string, formatter)

View Source
@spec format!(Timex.Types.valid_datetime(), format :: String.t(), formatter :: atom()) ::
  String.t() | no_return()

Same as format/3, except it returns only the value (not a tuple) and raises on error.

examples

Examples

iex> use Timex
...> datetime = Timex.to_datetime({{2016,2,29},{22,25,0}}, "America/Chicago")
iex> Timex.format!(datetime, "%FT%T%:z", :strftime)
"2016-02-29T22:25:00-06:00"
Link to this function

format(datetime, format_string)

View Source
@spec format(Timex.Types.valid_datetime(), format :: String.t()) ::
  {:ok, String.t()} | {:error, term()}

Formats a date/time value using the given format string (and optional formatter).

See Timex.Format.DateTime.Formatters.Default or Timex.Format.DateTime.Formatters.Strftime for documentation on the syntax supported by those formatters.

To use the Default formatter, simply call format/2. To use the Strftime formatter, you can either alias and pass Strftime by module name, or as a shortcut, you can pass :strftime instead.

Formatting will convert other dates than Elixir date types (Date, DateTime, NaiveDateTime) to a NaiveDateTime using to_naive_datetime/1 before formatting.

examples

Examples

iex> date = ~D[2016-02-29]
...> Timex.format(date, "{YYYY}-{0M}-{D}")
{:ok, "2016-02-29"}

iex> datetime = Timex.to_datetime({{2016,2,29},{22,25,0}}, "Etc/UTC")
...> Timex.format(datetime, "{ISO:Extended}")
{:ok, "2016-02-29T22:25:00+00:00"}
Link to this function

format(datetime, format_string, formatter)

View Source
@spec format(Timex.Types.valid_datetime(), format :: String.t(), formatter :: atom()) ::
  {:ok, String.t()} | {:error, term()}

Same as format/2, except using a custom formatter

examples

Examples

iex> use Timex
...> datetime = Timex.to_datetime({{2016,2,29},{22,25,0}}, "America/Chicago")
iex> Timex.format(datetime, "%FT%T%:z", :strftime)
{:ok, "2016-02-29T22:25:00-06:00"}
Link to this function

format_duration(timestamp)

View Source
@spec format_duration(Timex.Duration.t()) :: String.t() | {:error, term()}

Formats an Erlang timestamp using the ISO-8601 duration format, or optionally, with a custom formatter of your choosing.

See Timex.Format.Duration.Formatters.Default or Timex.Format.Duration.Formatters.Humanized for documentation on the specific formatter behaviour.

To use the Default formatter, simply call format_duration/2. To use the Humanized formatter, you can either alias and pass Humanized by module name, or as a shortcut, you can pass :humanized instead.

examples

Examples

iex> use Timex
...> duration = Duration.from_seconds(Timex.to_unix({2016, 2, 29}))
...> Timex.format_duration(duration)
"P46Y2M10D"

iex> use Timex
...> duration = Duration.from_seconds(Timex.to_unix({2016, 2, 29}))
...> Timex.format_duration(duration, :humanized)
"46 years, 2 months, 1 week, 3 days"

iex> use Timex
...> datetime = Duration.from_seconds(Timex.to_unix(~N[2016-02-29T22:25:00]))
...> Timex.format_duration(datetime, :humanized)
"46 years, 2 months, 1 week, 3 days, 22 hours, 25 minutes"
Link to this function

format_duration(timestamp, formatter)

View Source
@spec format_duration(Timex.Duration.t(), atom()) :: String.t() | {:error, term()}

Same as format_duration/1, except it also accepts a formatter

@spec from_iso_day(non_neg_integer()) :: Date.t() | {:error, term()}

Convert an iso ordinal day number to the day it represents in the current year.

## Examples

iex> %Date{:year => year} = Timex.from_iso_day(180)
...> %Date{:year => todays_year} = Timex.today()
...> year == todays_year
true

Same as from_iso_day/1, except you can expect the following based on the second parameter:

  • If an integer year is given, the result will be a Date struct
  • For any date/time value, the result will be in the same format (i.e. Date -> Date)

In all cases, the resulting value will be the date representation of the provided ISO day in that year

examples

Examples

creating-a-date-from-the-given-day

Creating a Date from the given day

iex> use Timex
...> expected = ~D[2015-06-29]
...> (expected === Timex.from_iso_day(180, 2015))
true

creating-a-date-datetime-from-the-given-day

Creating a Date/DateTime from the given day

iex> use Timex
...> expected = Timex.to_datetime({{2015, 6, 29}, {0,0,0}}, "Etc/UTC")
...> beginning = Timex.to_datetime({{2015,1,1}, {0,0,0}}, "Etc/UTC")
...> (expected === Timex.from_iso_day(180, beginning))
true

shifting-a-date-datetime-to-the-given-day

Shifting a Date/DateTime to the given day

iex> use Timex
...> date = Timex.to_datetime({{2015,6,26}, {12,0,0}}, "Etc/UTC")
...> expected = Timex.to_datetime({{2015, 6, 29}, {12,0,0}}, "Etc/UTC")
...> (Timex.from_iso_day(180, date) === expected)
true
@spec from_iso_triplet(Timex.Types.iso_triplet()) :: Date.t() | {:error, term()}

Given an ISO triplet {year, week number, weekday}, convert it to a Date struct.

examples

Examples

iex> expected = Timex.to_date({2014, 1, 28})
iex> Timex.from_iso_triplet({2014, 5, 2}) === expected
true
@spec from_now(Timex.Types.valid_datetime()) :: String.t() | {:error, term()}

Formats a DateTime using a fuzzy relative duration, from now.

examples

Examples

iex> use Timex
...> Timex.from_now(Timex.shift(DateTime.utc_now(), days: 2, hours: 1))
"in 2 days"

iex> use Timex
...> Timex.from_now(Timex.shift(DateTime.utc_now(), days: -2))
"2 days ago"
Link to this function

from_now(datetime, locale)

View Source
@spec from_now(Timex.Types.valid_datetime(), String.t()) ::
  String.t() | {:error, term()}
@spec from_now(Timex.Types.valid_datetime(), Timex.Types.valid_datetime()) ::
  String.t() | {:error, term()}

Formats a DateTime using a fuzzy relative duration, translated using given locale

examples

Examples

iex> use Timex
...> Timex.from_now(Timex.shift(DateTime.utc_now(), days: 2, hours: 1), "ru")
"через 2 дня"

iex> use Timex
...> Timex.from_now(Timex.shift(DateTime.utc_now(), days: -2), "ru")
"2 дня назад"
Link to this function

from_now(datetime, reference_date, locale)

View Source
@spec from_now(Timex.Types.valid_datetime(), Timex.Types.valid_datetime(), String.t()) ::
  String.t() | {:error, term()}

Formats a DateTime using a fuzzy relative duration, with a reference datetime other than now, translated using the given locale

Link to this function

from_unix(secs, unit \\ :second)

View Source
@spec from_unix(secs :: non_neg_integer(), :native | Timex.Types.second_time_units()) ::
  DateTime.t() | no_return()

Delegates to DateTime.from_unix!/2. To recap the docs:

Converts the given Unix time to DateTime.

The integer can be given in different units according to System.convert_time_unit/3 and it will be converted to microseconds internally. Defaults to :second.

Unix times are always in UTC and therefore the DateTime will be returned in UTC.

@spec is_leap?(Timex.Types.valid_datetime() | Timex.Types.year()) ::
  boolean() | {:error, term()}

Return a boolean indicating whether the given year is a leap year. You may pass a date or a year number.

examples

Examples

iex> Timex.epoch() |> Timex.is_leap?
false
iex> Timex.is_leap?(2012)
true
@spec is_valid_time?(term()) :: boolean()

Returns a boolean indicating whether the provided term represents a valid time, valid times are one of:

  • {hour, min, sec}
  • {hour, min, sec, ms}
Link to this function

is_valid_timezone?(timezone)

View Source
@spec is_valid_timezone?(term()) :: boolean()

Returns a boolean indicating whether the provided term represents a valid timezone, valid timezones are one of:

  • TimezoneInfo struct
  • A timezone name as a string
  • :utc as a shortcut for the UTC timezone
  • :local as a shortcut for the local timezone
  • A number representing an offset from UTC
@spec is_valid?(Timex.Types.valid_datetime()) :: boolean()

Return a boolean indicating whether the given date is valid.

examples

Examples

iex> use Timex
...> Timex.is_valid?(~N[0001-01-01T01:01:01])
true

iex> use Timex
...> %Date{year: 1, day: 1, month: 13} |> Timex.is_valid?
false

Return a 3-tuple {year, week number, weekday} for the given Date/DateTime.

examples

Examples

iex> Timex.iso_triplet(Timex.epoch)
{1970, 1, 4}
@spec iso_week(Timex.Types.valid_datetime()) ::
  {Timex.Types.year(), Timex.Types.weeknum()} | {:error, term()}

Return a pair {year, week number} (as defined by ISO 8601) that the given Date/DateTime value falls on.

examples

Examples

iex> Timex.iso_week({1970, 1, 1})
{1970,1}
Link to this function

iso_week(year, month, day)

View Source

Same as iso_week/1, except this takes a year, month, and day as distinct arguments.

examples

Examples

iex> Timex.iso_week(1970, 1, 1)
{1970,1}
Link to this function

lformat!(datetime, format_string, locale)

View Source
@spec lformat!(
  Timex.Types.valid_datetime(),
  format :: String.t(),
  locale :: String.t()
) ::
  String.t() | no_return()

Same as lformat/3, except local_format! raises on error.

See lformat/3 docs for usage examples.

Link to this function

lformat!(datetime, format_string, locale, formatter)

View Source
@spec lformat!(
  Timex.Types.valid_datetime(),
  format :: String.t(),
  locale :: String.t(),
  formatter :: atom()
) :: String.t() | no_return()

Same as lformat/4, except local_format! raises on error.

See lformat/4 docs for usage examples

Link to this function

lformat(datetime, format_string, locale)

View Source
@spec lformat(
  Timex.Types.valid_datetime(),
  format :: String.t(),
  locale :: String.t()
) ::
  {:ok, String.t()} | {:error, term()}

Same as format/2, except takes a locale name to translate text to.

Translations only apply to units, relative time phrases, and only for the locales in the list of supported locales in the Timex documentation.

Link to this function

lformat(datetime, format_string, locale, formatter)

View Source
@spec lformat(
  Timex.Types.valid_datetime(),
  format :: String.t(),
  locale :: String.t(),
  formatter :: atom()
) :: {:ok, String.t()} | {:error, term()}

Same as lformat/3, except takes a formatter as it's last argument.

Translations only apply to units, relative time phrases, and only for the locales in the list of supported locales in the Timex documentation.

Link to this function

lformat_duration(timestamp, locale)

View Source
@spec lformat_duration(Timex.Duration.t(), locale :: String.t()) ::
  String.t() | {:error, term()}

Same as format_duration/1, except takes a locale for use in translation

Link to this function

lformat_duration(timestamp, locale, formatter)

View Source
@spec lformat_duration(Timex.Duration.t(), locale :: String.t(), atom()) ::
  String.t() | {:error, term()}

Same as lformat_duration/2, except takes a formatter as an argument

@spec local() :: DateTime.t() | {:error, term()}

Returns a DateTime representing the current moment in time in the local timezone.

example

Example

iex> %DateTime{time_zone: tz} = Timex.local();
...> tz != nil
true

Returns a DateTime representing the given date/time in the local timezone

example

Example

iex> %DateTime{time_zone: tz} = Timex.local(DateTime.utc_now());
...> tz != nil
true
@spec month_name(Timex.Types.month()) :: String.t() | {:error, :invalid_month_number}

Get the name of the month corresponding to the provided number

examples

Examples

iex> Timex.month_name(1)
"January"
iex> Timex.month_name(0)
{:error, :invalid_month_number}
@spec month_shortname(Timex.Types.month()) ::
  String.t() | {:error, :invalid_month_number}

Get the short name of the month corresponding to the provided number

examples

Examples

iex> Timex.month_shortname(1)
"Jan"
iex> Timex.month_shortname(0)
{:error, :invalid_month_number}
@spec month_to_num(binary()) :: integer() | {:error, :invalid_month_name}

Get the number of the month corresponding to the given name.

examples

Examples

iex> Timex.month_to_num("January")
1
iex> Timex.month_to_num("january")
1
iex> Timex.month_to_num("Jan")
1
iex> Timex.month_to_num("jan")
1
iex> Timex.month_to_num(:jan)
1
@spec normalize(:date, {integer(), integer(), integer()}) :: Timex.Types.date()
@spec normalize(
  :time,
  {integer(), integer(), integer()}
  | {integer(), integer(), integer(), integer()}
) ::
  Timex.Types.time()
@spec normalize(:day, {integer(), integer(), integer()}) :: non_neg_integer()
@spec normalize(
  :year
  | :month
  | :day
  | :hour
  | :minute
  | :second
  | :millisecond
  | :microsecond,
  integer()
) :: non_neg_integer()

Given a unit to normalize, and the value to normalize, produces a valid value for that unit, clamped to whatever boundaries are defined for that unit.

example

Example

iex> Timex.normalize(:hour, 26)
23
@spec now() :: DateTime.t()

Returns a DateTime representing the current moment in time in UTC

Returns a DateTime representing the current moment in time in the provided timezone.

Link to this function

parse!(datetime_string, format_string)

View Source

Same as parse/2 and parse/3, except parse! raises on error.

See parse/2 or parse/3 docs for usage examples.

Link to this function

parse!(datetime_string, format_string, tokenizer)

View Source

See Timex.Parse.DateTime.Parser.parse!/3.

Link to this function

parse(datetime_string, format_string)

View Source
@spec parse(String.t(), String.t()) ::
  {:ok, DateTime.t() | NaiveDateTime.t() | Timex.AmbiguousDateTime.t()}
  | {:error, term()}

Parses a datetime string into a DateTime struct, using the provided format string (and optional tokenizer).

See Timex.Format.DateTime.Formatters.Default or Timex.Format.DateTime.Formatters.Strftime for documentation on the syntax supported in format strings by their respective tokenizers.

To use the Default tokenizer, simply call parse/2. To use the Strftime tokenizer, you can either alias and pass Timex.Parse.DateTime.Tokenizer.Strftime by module name, or as a shortcut, you can pass :strftime instead.

examples

Examples

iex> use Timex
...> {:ok, result} = Timex.parse("2016-02-29", "{YYYY}-{0M}-{D}")
...> result
~N[2016-02-29T00:00:00]

iex> use Timex
...> expected = Timex.to_datetime({{2016, 2, 29}, {22, 25, 0}}, "America/Chicago")
...> {:ok, result} = Timex.parse("2016-02-29T22:25:00-06:00", "{ISO:Extended}")
...> Timex.equal?(expected, result)
true

iex> use Timex
...> expected = Timex.to_datetime({{2016, 2, 29}, {22, 25, 0}}, "America/Chicago")
...> {:ok, result} = Timex.parse("2016-02-29T22:25:00-06:00", "%FT%T%:z", :strftime)
...> Timex.equal?(expected, result)
true
Link to this function

parse(datetime_string, format_string, tokenizer)

View Source
@spec parse(String.t(), String.t(), atom()) ::
  {:ok, DateTime.t() | NaiveDateTime.t() | Timex.AmbiguousDateTime.t()}
  | {:error, term()}

See Timex.Parse.DateTime.Parser.parse/3.

@spec quarter(Timex.Types.month() | Timex.Types.valid_datetime()) ::
  1..4 | {:error, term()}

Returns what quarter of the year the given date/time falls in.

examples

Examples

iex> Timex.quarter(4)
2

Return a new date/time value with the specified fields replaced by new values.

Values are automatically validated and clamped to good values by default. If you wish to skip validation, perhaps for performance reasons, pass validate: false.

Values are applied in order, so if you pass [datetime: dt, date: d], the date value from date will override datetime's date value.

Options which do not apply to the input value (for example, :hour against a Date struct), will be ignored.

example

Example

iex> use Timex
...> expected = ~D[2015-02-28]
...> result = Timex.set(expected, [month: 2, day: 30])
...> result == expected
true

iex> use Timex
...> expected = ~N[2016-02-29T23:30:00]
...> result = Timex.set(expected, [hour: 30])
...> result === expected
true

A single function for adjusting the date using various units: duration, microseconds, seconds, minutes, hours, days, weeks, months, years.

The result of applying the shift will be the same type as that of the input, with the exception of shifting DateTimes, which may result in an AmbiguousDateTime if the shift moves to an ambiguous time period for the zone of that DateTime.

Shifting by months will always return a date in the expected month. Because months have different number of days, shifting to a month with fewer days may not be the same day of the month as the original date.

If an error occurs, an error tuple will be returned.

examples

Examples

shifting-across-timezone-changes

Shifting across timezone changes

iex> use Timex
...> datetime = Timex.to_datetime({{2016,3,13}, {1,0,0}}, "America/Chicago")
...> # 2-3 AM doesn't exist due to leap forward, shift accounts for this
...> %DateTime{hour: 3} = Timex.shift(datetime, hours: 1)
...> shifted = Timex.shift(datetime, hours: 1)
...> {datetime.zone_abbr, shifted.zone_abbr, shifted.hour}
{"CST", "CDT", 3}

shifting-and-leap-days

Shifting and leap days

iex> use Timex
...> date = ~D[2016-02-29]
...> Timex.shift(date, years: -1)
~D[2015-03-01]

shifting-by-months

Shifting by months

iex> date = ~D[2016-01-15]
...> Timex.shift(date, months: 1)
~D[2016-02-15]

iex> date = ~D[2016-01-31]
...> Timex.shift(date, months: 1)
~D[2016-02-29]

iex> date = ~D[2016-01-31]
...> Timex.shift(date, months: 2)
~D[2016-03-31]
...> Timex.shift(date, months: 1) |> Timex.shift(months: 1)
~D[2016-03-29]
Link to this function

subtract(date, duration)

View Source

Subtract time from a date using a Duration Same as shift(date, Duration.from_minutes(5) |> Duration.invert, :timestamp).

Get a TimezoneInfo object for the specified offset or name.

When offset or name is invalid, exception is raised.

If no DateTime value is given for the second parameter, the current date/time will be used (in other words, it will return the current timezone info for the given zone). If one is provided, the timezone info returned will be based on the provided DateTime (or Erlang datetime tuple) value.

examples

Examples

iex> date = Timex.to_datetime({2015, 4, 12})
...> tz = Timex.timezone(:utc, date)
...> tz.full_name
"Etc/UTC"

iex> tz = Timex.timezone("America/Chicago", {2015,4,12})
...> {tz.full_name, tz.abbreviation}
{"America/Chicago", "CDT"}

iex> tz = Timex.timezone(+2, {2015, 4, 12})
...> {tz.full_name, tz.abbreviation}
{"Etc/UTC+2", "+02"}
@spec timezones() :: [String.t()]

Returns a list of all valid timezone names in the Olson database

@spec to_date(Timex.Types.valid_datetime()) :: Date.t() | {:error, term()}

Convert a date/time value to a Date struct.

@spec to_datetime(Timex.Types.valid_datetime()) :: DateTime.t() | {:error, term()}

Convert a date/time value and timezone name to a DateTime struct.

If the DateTime did not occur in the timezone, an error will be returned.

If the DateTime is ambiguous and cannot be resolved, an AmbiguousDateTime will be returned, allowing the developer to choose which of the two choices is desired.

If no timezone is provided, "Etc/UTC" will be used.

examples

Examples

iex> Timex.to_datetime(~N[2022-01-01 12:00:00], "America/New_York")
#DateTime<2022-01-01 12:00:00-05:00 EST America/New_York>

# This time was skipped as daylight savings started and clocks moved forward
iex> Timex.to_datetime(~N[2021-03-14 02:30:00], "America/New_York")
{:error, {:could_not_resolve_timezone, "America/New_York", 63782908200, :wall}}

# This time occurred twice as daylight savings ended and clocks moved back
iex> %AmbiguousDateTime{} = adt = Timex.to_datetime(~N[2021-11-07 01:30:00], "America/New_York")
...> match?(%DateTime{zone_abbr: "EDT"}, adt.before) && match?(%DateTime{zone_abbr: "EST"}, adt.after)
true

iex> Timex.to_datetime(~N[2022-01-01 12:00:00])
~U[2022-01-01 12:00:00Z]
Link to this function

to_datetime(from, timezone)

View Source

See Timex.Protocol.to_datetime/2.

@spec to_erl(Timex.Types.valid_datetime()) ::
  Timex.Types.date() | Timex.Types.datetime() | {:error, term()}

Convert a date/time value to it's Erlang representation

Link to this function

to_gregorian_microseconds(datetime)

View Source
@spec to_gregorian_microseconds(Timex.Types.valid_datetime()) ::
  non_neg_integer() | {:error, term()}

Convert a date/time value to gregorian microseconds (microseconds since start of year zero)

Link to this function

to_gregorian_seconds(datetime)

View Source
@spec to_gregorian_seconds(Timex.Types.valid_datetime()) ::
  non_neg_integer() | {:error, term()}

Convert a date/time value to gregorian seconds (seconds since start of year zero)

@spec to_julian(Timex.Types.valid_datetime()) :: integer() | {:error, term()}

Convert a date/time value to a Julian calendar date number

@spec to_naive_datetime(Timex.Types.valid_datetime()) ::
  NaiveDateTime.t() | {:error, term()}

Convert a date/time value to a NaiveDateTime struct.

@spec to_unix(Timex.Types.valid_datetime()) :: non_neg_integer() | {:error, term()}

Convert a date/time value to seconds since the UNIX epoch

@spec today() :: Date.t()

Returns a Date representing the current day in UTC

@spec today(Timex.Types.valid_timezone()) :: Date.t()

Returns a Date representing the current day in the provided timezone.

Link to this function

validate_format(format_string)

View Source
@spec validate_format(String.t()) :: :ok | {:error, term()}

Given a format string, validates that the format string is valid for the Default formatter.

Given a format string and a formatter, validates that the format string is valid for that formatter.

examples

Examples

iex> use Timex
...> Timex.validate_format("{YYYY}-{M}-{D}")
:ok

iex> use Timex
...> Timex.validate_format("{YYYY}-{M}-{V}")
{:error, "Expected end of input at line 1, column 11"}

iex> use Timex
...> Timex.validate_format("%FT%T%:z", :strftime)
:ok
Link to this function

validate_format(format_string, formatter)

View Source
@spec validate_format(String.t(), atom()) :: :ok | {:error, term()}

See Timex.Format.DateTime.Formatter.validate/2.

Returns the week number of the date provided, starting at 1.

examples

Examples

iex> Timex.week_of_month(~D[2016-03-05])
1

iex> Timex.week_of_month(~N[2016-03-14T00:00:00Z])
3
Link to this function

week_of_month(year, month, day)

View Source

Same as week_of_month/1, except takes year, month, and day as distinct arguments

examples

Examples

iex> Timex.week_of_month(2016, 3, 30)
5
Link to this function

weekday!(datetime, weekstart \\ :default)

View Source

Provides a version of weekday/1 and weekday/2 that raises on error.

@spec weekday(Timex.Types.valid_datetime()) ::
  Timex.Types.weekday() | {:error, :invalid_date}

Return weekday number (as defined by ISO 8601) of the specified date.

examples

Examples

iex> Timex.epoch |> Timex.weekday
4 # (i.e. Thursday)
Link to this function

weekday(datetime, weekstart)

View Source
@spec weekday(Timex.Types.valid_datetime(), Timex.Types.weekday_name()) ::
  Timex.Types.weekday() | {:error, :invalid_date}

Like weekday/1, but accepts a valid starting weekday value.

examples

Examples

iex> Timex.epoch() |> Elixir.Timex.weekday(:sunday)
5
@spec zero() :: Date.t()

Returns a Date representing the start of the Gregorian epoch