What a cell can hold.
| Kind | Elixir | In Sheets |
|---|---|---|
:empty | nil | an empty cell |
:number | integer() or float() | a number (a double) |
:string | String.t() | text |
:boolean | true or false | TRUE / FALSE |
:formula | {:formula, "=SUM(A1:A9)"} | a formula |
:date | Date.t() | a serial number |
:datetime | NaiveDateTime.t() or DateTime.t() | a serial number |
:time | Time.t() | a serial number |
Sheets keeps dates as days since 1899-12-30 with the time of day as the
fraction, and shows them as dates only through a number format. Writers use
to_serial/1 and default_number_format/1; readers use from_serial/2.
A DateTime is written as its own wall-clock time with the zone dropped, so
what you see in Elixir is what you see in the sheet.
Integers beyond 2^53 and Decimals do not survive a double; store them as
strings.
Summary
Functions
The number format that makes a temporal value readable in Sheets, or nil
for values that need none. Writers apply it when a cell's style has no
:number_format of its own.
A serial number back to a Date, NaiveDateTime or Time, rounded to the
millisecond. Sub-second parts keep millisecond precision; whole seconds come
back with none, so a second-precision value round-trips as ==.
The kind of a valid value. Raises ArgumentError for anything else; use
validate/1 for the checked version.
A temporal value as a Sheets serial number.
Whether the term is a cell value.
Checks a value.
Types
@type kind() ::
:empty | :number | :string | :boolean | :formula | :date | :datetime | :time
@type t() :: nil | number() | String.t() | boolean() | {:formula, String.t()} | Date.t() | NaiveDateTime.t() | DateTime.t() | Time.t()
Functions
The number format that makes a temporal value readable in Sheets, or nil
for values that need none. Writers apply it when a cell's style has no
:number_format of its own.
iex> Sheetshow.Value.default_number_format(~D[2026-09-12])
"yyyy-mm-dd"
iex> Sheetshow.Value.default_number_format(42)
nil
@spec from_serial(number(), :date | :datetime | :time) :: Date.t() | NaiveDateTime.t() | Time.t()
A serial number back to a Date, NaiveDateTime or Time, rounded to the
millisecond. Sub-second parts keep millisecond precision; whole seconds come
back with none, so a second-precision value round-trips as ==.
iex> Sheetshow.Value.from_serial(25569, :date)
~D[1970-01-01]
iex> Sheetshow.Value.from_serial(45292.5, :datetime)
~N[2024-01-01 12:00:00]
iex> Sheetshow.Value.from_serial(0.25, :time)
~T[06:00:00]
The kind of a valid value. Raises ArgumentError for anything else; use
validate/1 for the checked version.
iex> Sheetshow.Value.kind(2.5)
:number
iex> Sheetshow.Value.kind({:formula, "=A1*2"})
:formula
iex> Sheetshow.Value.kind(~N[2026-09-12 08:30:00])
:datetime
@spec to_serial(Date.t() | NaiveDateTime.t() | DateTime.t() | Time.t()) :: number()
A temporal value as a Sheets serial number.
iex> Sheetshow.Value.to_serial(~D[1970-01-01])
25569
iex> Sheetshow.Value.to_serial(~N[2024-01-01 12:00:00])
45292.5
iex> Sheetshow.Value.to_serial(~T[06:00:00])
0.25
Whether the term is a cell value.
@spec validate(term()) :: :ok | {:error, Sheetshow.Error.t()}
Checks a value.
iex> Sheetshow.Value.validate("hello")
:ok
iex> {:error, %Sheetshow.Error{reason: :invalid_value}} = Sheetshow.Value.validate({:formula, "SUM(A1)"})