Feel.Type.Image (feel v0.1.0)

Copy Markdown View Source

The numbers that stand for the values of a date or a duration, so that their sets can be sets of numbers (D-109).

A Feel.Type.NumberSet is a set of numbers in intervals, and the algebra on it (Feel.Analysis.Intervals) is that of numbers. A date and the two kinds of duration are ordered and, for the durations, added, subtracted, multiplied and divided as numbers are, so Feel.Type.Union holds their sets as sets of numbers too: {:date, set}, {:years_and_months_duration, set} and {:days_and_time_duration, set}. What the numbers of the set are is the image of the values:

KindThe image of a value
dateits number of days in the proleptic Gregorian calendar (Date.to_gregorian_days/1: 0 is 0000-01-01)
years and months durationits number of months
days and time durationits number of seconds
time, date and timethe whole second it falls in, on a line for the values with no zone and a line for those with one (Feel.Type.Moment, D-109)

The image of a date or a duration is one-to-one and keeps the order, so a < b for two values is < for their images, and a = b is =. For the durations it keeps the operations too: the image of a + b is the sum of the images, and the image of a * n is the image of a times n. Two dates are as many days apart as their images are, so date - date has a set too. The image does not carry the other temporal operations: a date plus months has its day clamped to the month, and a years and months duration times a number is rounded, so the image of the result is not a sum of images (D-54). That of a time and a date and time is neither: it is the second, and the order of two depends on a zone (Feel.Type.Moment).

The set of every value of a kind is its universe. For the durations it is every number of decimal128, since a duration is as large as a number can be, and for a date it is the days from -999,999,999-01-01 to 999,999,999-12-31. A set that holds the universe is the bare kind (Feel.Type.Union).

A set is written as the values it has: P1DT2H, [PT0S..P1D], 2024-01-31.

iex> Feel.Type.Image.image(Feel.Value.DaysAndTimeDuration.new(93_600))
Decimal.new("93600")
iex> Feel.Type.Image.image(~D[0000-01-02])
Decimal.new("1")
iex> Feel.Type.Image.format_value(:days_and_time_duration, Decimal.new(93_600))
"P1DT2H"

Summary

Types

A kind whose sets are sets of images.

Functions

Returns true when the set has every value of the kind.

Writes a set of images as the values it has, as Feel.Type.NumberSet.format/2 does for numbers.

Writes the value that an image stands for: a date as 2024-01-31, a years and months duration as P1Y2M, a days and time duration as P1DT2H3M4.5S. A number that is not the image of a value, as half a month is not, is written as the number.

The image of a date or a duration.

The kinds whose sets are sets of images: :date, the two durations, :time and :date_and_time.

The set of the images of every value of a kind. A number is its own image, so the universe of :number is every number.

Types

kind()

@type kind() ::
  :date
  | :years_and_months_duration
  | :days_and_time_duration
  | :time
  | :date_and_time

A kind whose sets are sets of images.

Functions

covers?(kind, set)

@spec covers?(kind() | :number, Feel.Type.NumberSet.t()) :: boolean()

Returns true when the set has every value of the kind.

iex> Feel.Type.Image.covers?(:date, Feel.Type.Image.universe(:date))
true
iex> Feel.Type.Image.covers?(:date, Feel.Type.NumberSet.point(Decimal.new(0)))
false

format_set(kind, set)

@spec format_set(kind(), Feel.Type.NumberSet.t()) :: String.t()

Writes a set of images as the values it has, as Feel.Type.NumberSet.format/2 does for numbers.

iex> set = Feel.Type.NumberSet.interval(Decimal.new(0), Decimal.new(86_400))
iex> Feel.Type.Image.format_set(:days_and_time_duration, set)
"[PT0S..P1D]"

format_value(kind, number)

@spec format_value(kind(), Decimal.t()) :: String.t()

Writes the value that an image stands for: a date as 2024-01-31, a years and months duration as P1Y2M, a days and time duration as P1DT2H3M4.5S. A number that is not the image of a value, as half a month is not, is written as the number.

iex> Feel.Type.Image.format_value(:date, Decimal.new(739_281))
"2024-01-31"
iex> Feel.Type.Image.format_value(:years_and_months_duration, Decimal.new(14))
"P1Y2M"
iex> Feel.Type.Image.format_value(:years_and_months_duration, Decimal.new(-12))
"-P1Y"
iex> Feel.Type.Image.format_value(:days_and_time_duration, Decimal.new("0.5"))
"PT0.5S"
iex> Feel.Type.Image.format_value(:days_and_time_duration, Decimal.new(0))
"PT0S"
iex> Feel.Type.Image.format_value(:days_and_time_duration, Decimal.new("-5E+40"))
"-PT5E+40S"

image(date)

The image of a date or a duration.

iex> Feel.Type.Image.image(Feel.Value.YearsAndMonthsDuration.new(-14))
Decimal.new("-14")

kinds()

@spec kinds() :: [kind(), ...]

The kinds whose sets are sets of images: :date, the two durations, :time and :date_and_time.

universe(kind)

@spec universe(kind() | :number) :: Feel.Type.NumberSet.t()

The set of the images of every value of a kind. A number is its own image, so the universe of :number is every number.

iex> Feel.Type.Image.universe(:days_and_time_duration) == Feel.Type.NumberSet.all()
true
iex> Feel.Type.NumberSet.format(Feel.Type.Image.universe(:date))
"[-365242499634..365242499999]"