Cldr.DateTime.Relative (Cldr Dates & Times v2.23.0)
View SourceFunctions to support the string formatting of relative time/datetime numbers.
This module provides formatting of numbers (as integers, floats, Dates or DateTimes) as "ago" or "in" with an appropriate time unit. For example, "2 days ago" or "in 10 seconds"
Summary
Functions
An example implementation of a function to derive an appropriate time unit for a relative time.
Returns a list of the valid unit keys for to_string/2
Calculates the time span in the given unit
from the time given in seconds.
Returns a {:ok, string}
representing a relative time (ago, in) for a given
number, Date or Datetime. Returns {:error, reason}
when errors are detected.
Returns a string representing a relative time (ago, in) for a given number, Date or Datetime or raises an exception on error.
Returns an estimate of the appropriate time unit for an integer of a given magnitude of seconds.
Functions
An example implementation of a function to derive an appropriate time unit for a relative time.
Arguments
relative
, the first argument provided toto_string/3
.relative_to
the value of option:relative_to
provided toto_string/3
or its default value.time_difference
is the difference in seconds betweenrelative
andrelative_to
.unit
being the requested time unit which may benil
. Ifnil
then the time unit must be derived and thetime_difference
scaled to that time unit. If specified then thetime_difference
must be scaled to that time unit.
Returns
{relative, unit}
whererelative
is the integer value of the derived and scaled time unit.unit
is the derived or given time unit.
Notes
- In this implementation
the time difference is used to derive seconds, minutes, hours, days and weeks.
The
:month
and:year
fields of the therelative
struct are used to derive months and years.
Returns a list of the valid unit keys for to_string/2
Example
iex> Cldr.DateTime.Relative.known_units()
[:day, :fri, :hour, :minute, :mon, :month, :quarter, :sat, :second,
:sun, :thu, :tue, :wed, :week, :year]
Calculates the time span in the given unit
from the time given in seconds.
Examples
iex> Cldr.DateTime.Relative.scale_relative(1234, :second)
1234
iex> Cldr.DateTime.Relative.scale_relative(1234, :minute)
21
iex> Cldr.DateTime.Relative.scale_relative(1234, :hour)
0
@spec to_string( integer() | float() | Date.t() | DateTime.t(), Cldr.backend(), Keyword.t() ) :: {:ok, String.t()} | {:error, {module(), String.t()}}
Returns a {:ok, string}
representing a relative time (ago, in) for a given
number, Date or Datetime. Returns {:error, reason}
when errors are detected.
relative
is an integer orDateTime.t/0
,Date.t/0
orTime.t/0
representing the time distance fromnow
or fromoptions[:relative_to]
.backend
is any module that includesuse Cldr
and therefore is aCldr
backend module. The default isCldr.default_backend/0
.options
is aKeyword.t/0
list of options.
Options
:locale
is the locale in which the binary is formatted. The default isCldr.get_locale/0
:format
is the format of the binary. Format may be:default
,:narrow
or:short
.:unit
is the time unit for the formatting. The allowable units are:second
,:minute
,:hour
,:day
,:week
,:month
,:year
,:mon
,:tue
,:wed
,:thu
,:fri
,:sat
,:sun
,:quarter
. If no:unit
is specified, one will be derived using the:derive_unit_from
option.:relative_to
is the baselinet:Date/0
ort:Datetime.t/0
from which the difference fromrelative
is calculated whenrelative
is a Date or a DateTime. The default for aDate.t/0
isDate.utc_today/0
, for aDateTime.t/0
it isDateTime.utc_now/0
.:derive_unit_from
is used to derive the most appropriate time unit if none is provided. THere are two ways to specify:derive_unit_from
.The first option is a map. The map is required to have the keys
:second
,:minute
,:hour
,:day
,:week
,:month
, and:year
with the values being the number of seconds below which the key defines the time unit difference. This is the default and its value is:%{second: 1, month: 2629743.83, day: 86400, year: 31556926, minute: 60, hour: 3600, week: 604800}
The second option is to specify a function reference. The function must take four arguments as described below.
The :derive_unit_from` map
Any
:derive_unit_from
map is first merged into the default map. This means that developers can use the default values and override only specific entries by providing a sparse map.Any entry in the
:derive_unit_from
map that has a value ofnil
is ignored. This has the result that any key set tonil
will never be represented in the output.Any entry in the
:derive_unit_from
map that has the value:infinity
will always be the largest time unit used to represent the relative time.
The :derive_unit_from function
The function must take four arguments:
relative
, being the first argument toto_string/3
.relative_to
being the value of option:relative_to
or its default value.time_difference
being the difference in seconds betweenrelative
andrelative_to
.unit
being the requested time unit which may benil
. Ifnil
then the time unit must be derived and thetime_difference
scaled to that time unit. If specified then thetime_difference
must be scaled to that time unit.
The function must return a tuple of the form
{relative, unit}
whererelative
is an integer value andunit
is the appropriate time unit atom.See the
Cldr.DateTime.Relative.derive_unit_from/4
function for an example.
Examples
iex> Cldr.DateTime.Relative.to_string(-1, MyApp.Cldr)
{:ok, "1 second ago"}
iex> Cldr.DateTime.Relative.to_string(1, MyApp.Cldr)
{:ok, "in 1 second"}
iex> Cldr.DateTime.Relative.to_string(1, MyApp.Cldr, unit: :day)
{:ok, "tomorrow"}
iex> Cldr.DateTime.Relative.to_string(1, MyApp.Cldr, unit: :day, locale: "fr")
{:ok, "demain"}
iex> Cldr.DateTime.Relative.to_string(1, MyApp.Cldr, unit: :day, format: :narrow)
{:ok, "tomorrow"}
iex> Cldr.DateTime.Relative.to_string(1234, MyApp.Cldr, unit: :year)
{:ok, "in 1,234 years"}
iex> Cldr.DateTime.Relative.to_string(1234, MyApp.Cldr, unit: :year, locale: "fr")
{:ok, "dans 1 234 ans"}
iex> Cldr.DateTime.Relative.to_string(31, MyApp.Cldr)
{:ok, "in 31 seconds"}
iex> Cldr.DateTime.Relative.to_string(~D[2017-04-29], MyApp.Cldr, relative_to: ~D[2017-04-26])
{:ok, "in 3 days"}
iex> Cldr.DateTime.Relative.to_string(310, MyApp.Cldr, format: :short, locale: "fr")
{:ok, "dans 5 min"}
iex> Cldr.DateTime.Relative.to_string(310, MyApp.Cldr, format: :narrow, locale: "fr")
{:ok, "+5 min"}
iex> Cldr.DateTime.Relative.to_string 2, MyApp.Cldr, unit: :wed, format: :short, locale: "en"
{:ok, "in 2 Wed."}
iex> Cldr.DateTime.Relative.to_string 1, MyApp.Cldr, unit: :wed, format: :short
{:ok, "next Wed."}
iex> Cldr.DateTime.Relative.to_string -1, MyApp.Cldr, unit: :wed, format: :short
{:ok, "last Wed."}
iex> Cldr.DateTime.Relative.to_string -1, MyApp.Cldr, unit: :wed
{:ok, "last Wednesday"}
iex> Cldr.DateTime.Relative.to_string -1, MyApp.Cldr, unit: :quarter
{:ok, "last quarter"}
iex> Cldr.DateTime.Relative.to_string -1, MyApp.Cldr, unit: :mon, locale: "fr"
{:ok, "lundi dernier"}
iex> Cldr.DateTime.Relative.to_string(~D[2017-04-29], MyApp.Cldr, unit: :ziggeraut)
{:error, {Cldr.DateTime.UnknownTimeUnit,
"Unknown time unit :ziggeraut. Valid time units are [:day, :fri, :hour, :minute, :mon, :month, :quarter, :sat, :second, :sun, :thu, :tue, :wed, :week, :year]"}}
@spec to_string!( integer() | float() | Date.t() | DateTime.t(), Cldr.backend(), Keyword.t() ) :: String.t()
Returns a string representing a relative time (ago, in) for a given number, Date or Datetime or raises an exception on error.
Arguments
relative
is an integer orDateTime.t/0
,Date.t/0
orTime.t/0
representing the time distance fromnow
or fromoptions[:relative_to]
.backend
is any module that includesuse Cldr
and therefore is aCldr
backend module. The default isCldr.default_backend/0
.options
is aKeyword.t/0
list of options.
Options
:locale
is the locale in which the binary is formatted. The default isCldr.get_locale/0
.:format
is the format of the binary. Format may be:default
,:narrow
or:short
. The default is:default
.:unit
is the time unit for the formatting. The allowable units are:second
,:minute
,:hour
,:day
,:week
,:month
,:year
,:mon
,:tue
,:wed
,:thu
,:fri
,:sat
,:sun
,:quarter
. If no:unit
is specified, one will be derived using the:derive_unit_from
option.:relative_to
is the baselinet:Date/0
ort:Datetime.t/0
from which the difference fromrelative
is calculated whenrelative
is a Date or a DateTime. The default for aDate.t/0
isDate.utc_today/0
, for aDateTime.t/0
it isDateTime.utc_now/0
.:derive_unit_from
is used to derive the most appropriate time unit if none is provided. THere are two ways to specify:derive_unit_from
.The first option is a map. The map is required to have the keys
:second
,:minute
,:hour
,:day
,:week
,:month
, and:year
with the values being the number of seconds below which the key defines the time unit difference. This is the default and its value is:%{second: 1, month: 2629743.83, day: 86400, year: 31556926, minute: 60, hour: 3600, week: 604800}
The second option is to specify a function reference. The function must take four arguments as described below.
The :derive_unit_from` map
Any
:derive_unit_from
map is first merged into the default map. This means that developers can use the default values and override only specific entries by providing a sparse map.Any entry in the
:derive_unit_from
map that has a value ofnil
is ignored. This has the result that any key set tonil
will never be represented in the output.Any entry in the
:derive_unit_from
map that has the value:infinity
will always be the largest time unit used to represent the relative time.
The :derive_unit_from function
The function must take four arguments:
relative
, being the first argument toto_string/3
.relative_to
being the value of option:relative_to
or its default value.time_difference
being the difference in seconds betweenrelative
andrelative_to
.unit
being the requested time unit which may benil
. Ifnil
then the time unit must be derived and thetime_difference
scaled to that time unit. If specified then thetime_difference
must be scaled to that time unit.
The function must return a tuple of the form
{relative, unit}
whererelative
is an integer value andunit
is the appropriate time unit atom.See the
Cldr.DateTime.Relative.derive_unit_from/4
function for an example.
See to_string/3
for example usage.
Returns an estimate of the appropriate time unit for an integer of a given magnitude of seconds.
Examples
iex> Cldr.DateTime.Relative.unit_from_relative_time(1234)
:minute
iex> Cldr.DateTime.Relative.unit_from_relative_time(12345)
:hour
iex> Cldr.DateTime.Relative.unit_from_relative_time(123456)
:day
iex> Cldr.DateTime.Relative.unit_from_relative_time(1234567)
:week
iex> Cldr.DateTime.Relative.unit_from_relative_time(12345678)
:month
iex> Cldr.DateTime.Relative.unit_from_relative_time(123456789)
:year