Current section
Files
Jump to
Current section
Files
src/calendar@naive_datetime.erl
-module(calendar@naive_datetime).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/calendar/naive_datetime.gleam").
-export([new/8, new_simple/6, from_date_and_time/2, to_date/1, to_time/1, to_timestamp/1, compare/2, utc_now_with_precision/2, utc_now/0, local_now_with_calendar/1, local_now/0, diff/3, diff_days/2, diff_hours/2, diff_minutes/2, shift/2, truncate/2, before/2, 'after'/2, to_erl/1, from_erl/3, from_erl_unchecked/3, convert/2, convert_unchecked/2, beginning_of_day/1, end_of_day/1, to_gregorian_seconds/1, today_with_time_and_calendar/5, today_with_time/3, equal/2, day_of_year/1, day_of_week/1, week_of_year/1, year/1, month/1, day/1, hour/1, minute/1, second/1, microsecond/1, calendar/1, is_valid/7, replace/8, replace_partial/4, from_iso8601/1, from_iso8601_unchecked/1, to_string/1, to_iso8601_with_format/2, to_iso8601/1, inspect/1, from_timestamp/1, add_seconds/2, add_days/2, add_hours/2, add_minutes/2, add_with_validation/3, add/3, from_gregorian_seconds/3, range/3]).
-export_type([naive_date_time/0, naive_date_time_error/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type naive_date_time() :: {naive_date_time,
integer(),
integer(),
integer(),
integer(),
integer(),
integer(),
{integer(), integer()},
binary()}.
-type naive_date_time_error() :: invalid_naive_date_time |
invalid_date |
invalid_time.
-file("src/calendar/naive_datetime.gleam", 45).
?DOC(" Creates a new NaiveDateTime struct.\n").
-spec new(
integer(),
integer(),
integer(),
integer(),
integer(),
integer(),
{integer(), integer()},
binary()
) -> {ok, naive_date_time()} | {error, naive_date_time_error()}.
new(Year, Month, Day, Hour, Minute, Second, Microsecond, Calendar) ->
case calendar@date:new(Year, Month, Day, Calendar) of
{error, _} ->
{error, invalid_date};
{ok, _} ->
case calendar@time:new(Hour, Minute, Second, Microsecond, Calendar) of
{error, _} ->
{error, invalid_time};
{ok, _} ->
{ok,
{naive_date_time,
Year,
Month,
Day,
Hour,
Minute,
Second,
Microsecond,
Calendar}}
end
end.
-file("src/calendar/naive_datetime.gleam", 79).
?DOC(" Creates a new NaiveDateTime with simple parameters.\n").
-spec new_simple(
integer(),
integer(),
integer(),
integer(),
integer(),
integer()
) -> {ok, naive_date_time()} | {error, naive_date_time_error()}.
new_simple(Year, Month, Day, Hour, Minute, Second) ->
new(Year, Month, Day, Hour, Minute, Second, {0, 0}, <<"Calendar.ISO"/utf8>>).
-file("src/calendar/naive_datetime.gleam", 91).
?DOC(" Creates a NaiveDateTime from separate Date and Time structs.\n").
-spec from_date_and_time(calendar@date:date(), calendar@time:time()) -> {ok,
naive_date_time()} |
{error, naive_date_time_error()}.
from_date_and_time(Date_val, Time_val) ->
case erlang:element(5, Date_val) =:= erlang:element(6, Time_val) of
true ->
{ok,
{naive_date_time,
erlang:element(2, Date_val),
erlang:element(3, Date_val),
erlang:element(4, Date_val),
erlang:element(2, Time_val),
erlang:element(3, Time_val),
erlang:element(4, Time_val),
erlang:element(5, Time_val),
erlang:element(5, Date_val)}};
false ->
{error, invalid_naive_date_time}
end.
-file("src/calendar/naive_datetime.gleam", 180).
?DOC(" Extracts the Date part from a NaiveDateTime.\n").
-spec to_date(naive_date_time()) -> calendar@date:date().
to_date(Ndt) ->
case calendar@date:new(
erlang:element(2, Ndt),
erlang:element(3, Ndt),
erlang:element(4, Ndt),
erlang:element(9, Ndt)
) of
{ok, D} ->
D;
{error, _} ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid date in valid NaiveDateTime struct"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"calendar/naive_datetime"/utf8>>,
function => <<"to_date"/utf8>>,
line => 183})
end.
-file("src/calendar/naive_datetime.gleam", 188).
?DOC(" Extracts the Time part from a NaiveDateTime.\n").
-spec to_time(naive_date_time()) -> calendar@time:time().
to_time(Ndt) ->
case calendar@time:new(
erlang:element(5, Ndt),
erlang:element(6, Ndt),
erlang:element(7, Ndt),
erlang:element(8, Ndt),
erlang:element(9, Ndt)
) of
{ok, T} ->
T;
{error, _} ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid time in valid NaiveDateTime struct"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"calendar/naive_datetime"/utf8>>,
function => <<"to_time"/utf8>>,
line => 193})
end.
-file("src/calendar/naive_datetime.gleam", 214).
?DOC(" Convert NaiveDateTime to Unix timestamp (seconds since epoch).\n").
-spec to_timestamp(naive_date_time()) -> integer().
to_timestamp(Ndt) ->
Date_part = to_date(Ndt),
Date_timestamp = calendar@date:to_timestamp(Date_part),
Time_seconds = ((erlang:element(5, Ndt) * 3600) + (erlang:element(6, Ndt) * 60))
+ erlang:element(7, Ndt),
Date_timestamp + Time_seconds.
-file("src/calendar/naive_datetime.gleam", 198).
?DOC(" Compare two NaiveDateTime structs.\n").
-spec compare(naive_date_time(), naive_date_time()) -> gleam@order:order().
compare(Ndt1, Ndt2) ->
Ts1 = to_timestamp(Ndt1),
Ts2 = to_timestamp(Ndt2),
gleam@int:compare(Ts1, Ts2).
-file("src/calendar/naive_datetime.gleam", 240).
?DOC(" Helper function to pad string with leading characters.\n").
-spec pad_left(binary(), integer(), binary()) -> binary().
pad_left(Str, Width, Pad_char) ->
Current_length = string:length(Str),
case Current_length >= Width of
true ->
Str;
false ->
<<(gleam@string:repeat(Pad_char, Width - Current_length))/binary,
Str/binary>>
end.
-file("src/calendar/naive_datetime.gleam", 254).
?DOC(" Returns the current naive datetime in UTC with precision.\n").
-spec utc_now_with_precision(calendar@time:time_unit(), binary()) -> {ok,
naive_date_time()} |
{error, naive_date_time_error()}.
utc_now_with_precision(Precision, Calendar) ->
Current_date = calendar@date:utc_today_with_calendar(Calendar),
case calendar@time:utc_now_with_precision(Precision, Calendar) of
{ok, Current_time} ->
new(
erlang:element(2, Current_date),
erlang:element(3, Current_date),
erlang:element(4, Current_date),
erlang:element(2, Current_time),
erlang:element(3, Current_time),
erlang:element(4, Current_time),
erlang:element(5, Current_time),
Calendar
);
{error, _} ->
{error, invalid_time}
end.
-file("src/calendar/naive_datetime.gleam", 249).
?DOC(" Returns the current naive datetime in UTC.\n").
-spec utc_now() -> {ok, naive_date_time()} | {error, naive_date_time_error()}.
utc_now() ->
utc_now_with_precision(microsecond, <<"Calendar.ISO"/utf8>>).
-file("src/calendar/naive_datetime.gleam", 282).
?DOC(" Returns the current local naive datetime with calendar.\n").
-spec local_now_with_calendar(binary()) -> {ok, naive_date_time()} |
{error, naive_date_time_error()}.
local_now_with_calendar(Calendar) ->
utc_now_with_precision(microsecond, Calendar).
-file("src/calendar/naive_datetime.gleam", 277).
?DOC(" Returns the current local naive datetime.\n").
-spec local_now() -> {ok, naive_date_time()} | {error, naive_date_time_error()}.
local_now() ->
local_now_with_calendar(<<"Calendar.ISO"/utf8>>).
-file("src/calendar/naive_datetime.gleam", 395).
?DOC(" Calculate difference between two naive datetimes.\n").
-spec diff(naive_date_time(), naive_date_time(), calendar@time:time_unit()) -> integer().
diff(Ndt1, Ndt2, Unit) ->
Ts1 = to_timestamp(Ndt1),
Ts2 = to_timestamp(Ndt2),
Diff_seconds = Ts1 - Ts2,
case Unit of
second ->
Diff_seconds;
microsecond ->
Diff_seconds * 1000000;
millisecond ->
Diff_seconds * 1000;
_ ->
Diff_seconds
end.
-file("src/calendar/naive_datetime.gleam", 317).
?DOC(" Calculate difference in days between two naive datetimes.\n").
-spec diff_days(naive_date_time(), naive_date_time()) -> integer().
diff_days(Ndt1, Ndt2) ->
diff(Ndt1, Ndt2, second) div 86400.
-file("src/calendar/naive_datetime.gleam", 322).
?DOC(" Calculate difference in hours between two naive datetimes.\n").
-spec diff_hours(naive_date_time(), naive_date_time()) -> integer().
diff_hours(Ndt1, Ndt2) ->
diff(Ndt1, Ndt2, second) div 3600.
-file("src/calendar/naive_datetime.gleam", 327).
?DOC(" Calculate difference in minutes between two naive datetimes.\n").
-spec diff_minutes(naive_date_time(), naive_date_time()) -> integer().
diff_minutes(Ndt1, Ndt2) ->
diff(Ndt1, Ndt2, second) div 60.
-file("src/calendar/naive_datetime.gleam", 413).
?DOC(" Shift naive datetime by duration.\n").
-spec shift(naive_date_time(), calendar@duration:duration()) -> {ok,
naive_date_time()} |
{error, naive_date_time_error()}.
shift(Ndt, Duration) ->
Month_shift = (erlang:element(2, Duration) * 12) + erlang:element(
3,
Duration
),
Day_shift = (erlang:element(4, Duration) * 7) + erlang:element(5, Duration),
{Us, _} = erlang:element(9, Duration),
{Y, M, D, H, Min, S, Microsecond} = calendar@iso:shift_naive_datetime(
erlang:element(2, Ndt),
erlang:element(3, Ndt),
erlang:element(4, Ndt),
erlang:element(5, Ndt),
erlang:element(6, Ndt),
erlang:element(7, Ndt),
erlang:element(8, Ndt),
Month_shift,
Day_shift,
((erlang:element(6, Duration) * 3600) + (erlang:element(7, Duration) * 60))
+ erlang:element(8, Duration),
Us
),
new(Y, M, D, H, Min, S, Microsecond, erlang:element(9, Ndt)).
-file("src/calendar/naive_datetime.gleam", 440).
?DOC(" Truncate naive datetime to specified precision.\n").
-spec truncate(naive_date_time(), integer()) -> {ok, naive_date_time()} |
{error, naive_date_time_error()}.
truncate(Ndt, Precision) ->
Current_time = to_time(Ndt),
Truncated_time = calendar@time:truncate(Current_time, Precision),
new(
erlang:element(2, Ndt),
erlang:element(3, Ndt),
erlang:element(4, Ndt),
erlang:element(2, Truncated_time),
erlang:element(3, Truncated_time),
erlang:element(4, Truncated_time),
erlang:element(5, Truncated_time),
erlang:element(9, Ndt)
).
-file("src/calendar/naive_datetime.gleam", 459).
?DOC(" Check if first datetime is before second.\n").
-spec before(naive_date_time(), naive_date_time()) -> boolean().
before(Ndt1, Ndt2) ->
case compare(Ndt1, Ndt2) of
lt ->
true;
_ ->
false
end.
-file("src/calendar/naive_datetime.gleam", 467).
?DOC(" Check if first datetime is after second.\n").
-spec 'after'(naive_date_time(), naive_date_time()) -> boolean().
'after'(Ndt1, Ndt2) ->
case compare(Ndt1, Ndt2) of
gt ->
true;
_ ->
false
end.
-file("src/calendar/naive_datetime.gleam", 494).
?DOC(" Convert NaiveDateTime to Erlang datetime tuple.\n").
-spec to_erl(naive_date_time()) -> {{integer(), integer(), integer()},
{integer(), integer(), integer()}}.
to_erl(Ndt) ->
{{erlang:element(2, Ndt), erlang:element(3, Ndt), erlang:element(4, Ndt)},
{erlang:element(5, Ndt), erlang:element(6, Ndt), erlang:element(7, Ndt)}}.
-file("src/calendar/naive_datetime.gleam", 499).
?DOC(" Create NaiveDateTime from Erlang datetime tuple.\n").
-spec from_erl(
{{integer(), integer(), integer()}, {integer(), integer(), integer()}},
{integer(), integer()},
binary()
) -> {ok, naive_date_time()} | {error, naive_date_time_error()}.
from_erl(Erl_datetime, Microsecond, Calendar) ->
{{Year, Month, Day}, {Hour, Minute, Second}} = Erl_datetime,
new(Year, Month, Day, Hour, Minute, Second, Microsecond, Calendar).
-file("src/calendar/naive_datetime.gleam", 509).
?DOC(" Create NaiveDateTime from Erlang tuple, panicking on error.\n").
-spec from_erl_unchecked(
{{integer(), integer(), integer()}, {integer(), integer(), integer()}},
{integer(), integer()},
binary()
) -> naive_date_time().
from_erl_unchecked(Erl_datetime, Microsecond, Calendar) ->
case from_erl(Erl_datetime, Microsecond, Calendar) of
{ok, Ndt} ->
Ndt;
{error, _} ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid Erlang datetime tuple"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"calendar/naive_datetime"/utf8>>,
function => <<"from_erl_unchecked"/utf8>>,
line => 516})
end.
-file("src/calendar/naive_datetime.gleam", 521).
?DOC(" Convert between calendars.\n").
-spec convert(naive_date_time(), binary()) -> {ok, naive_date_time()} |
{error, naive_date_time_error()}.
convert(Ndt, Target_calendar) ->
case erlang:element(9, Ndt) =:= Target_calendar of
true ->
{ok, Ndt};
false ->
case new(
erlang:element(2, Ndt),
erlang:element(3, Ndt),
erlang:element(4, Ndt),
erlang:element(5, Ndt),
erlang:element(6, Ndt),
erlang:element(7, Ndt),
erlang:element(8, Ndt),
Target_calendar
) of
{ok, Result} ->
{ok, Result};
{error, E} ->
{error, E}
end
end.
-file("src/calendar/naive_datetime.gleam", 549).
?DOC(" Convert between calendars, panicking on error.\n").
-spec convert_unchecked(naive_date_time(), binary()) -> naive_date_time().
convert_unchecked(Ndt, Target_calendar) ->
case convert(Ndt, Target_calendar) of
{ok, Converted} ->
Converted;
{error, _} ->
erlang:error(#{gleam_error => panic,
message => <<"Calendar conversion failed"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"calendar/naive_datetime"/utf8>>,
function => <<"convert_unchecked"/utf8>>,
line => 555})
end.
-file("src/calendar/naive_datetime.gleam", 560).
?DOC(" Get beginning of day (00:00:00).\n").
-spec beginning_of_day(naive_date_time()) -> naive_date_time().
beginning_of_day(Ndt) ->
case new(
erlang:element(2, Ndt),
erlang:element(3, Ndt),
erlang:element(4, Ndt),
0,
0,
0,
{0, 0},
erlang:element(9, Ndt)
) of
{ok, Result} ->
Result;
{error, _} ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid beginning of day"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"calendar/naive_datetime"/utf8>>,
function => <<"beginning_of_day"/utf8>>,
line => 563})
end.
-file("src/calendar/naive_datetime.gleam", 568).
?DOC(" Get end of day (23:59:59.999999).\n").
-spec end_of_day(naive_date_time()) -> naive_date_time().
end_of_day(Ndt) ->
case new(
erlang:element(2, Ndt),
erlang:element(3, Ndt),
erlang:element(4, Ndt),
23,
59,
59,
{999999, 6},
erlang:element(9, Ndt)
) of
{ok, Result} ->
Result;
{error, _} ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid end of day"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"calendar/naive_datetime"/utf8>>,
function => <<"end_of_day"/utf8>>,
line => 573})
end.
-file("src/calendar/naive_datetime.gleam", 594).
?DOC(" Convert to Gregorian seconds since epoch 0000-01-01 00:00:00.\n").
-spec to_gregorian_seconds(naive_date_time()) -> {integer(), integer()}.
to_gregorian_seconds(Ndt) ->
Timestamp = to_timestamp(Ndt),
Gregorian_seconds = Timestamp + 62167219200,
{Ms, _} = erlang:element(8, Ndt),
{Gregorian_seconds, Ms}.
-file("src/calendar/naive_datetime.gleam", 612).
?DOC(" Create NaiveDateTime with current date and specified time and calendar.\n").
-spec today_with_time_and_calendar(
integer(),
integer(),
integer(),
{integer(), integer()},
binary()
) -> {ok, naive_date_time()} | {error, naive_date_time_error()}.
today_with_time_and_calendar(Hour, Minute, Second, Microsecond, Calendar) ->
Today = calendar@date:utc_today_with_calendar(Calendar),
new(
erlang:element(2, Today),
erlang:element(3, Today),
erlang:element(4, Today),
Hour,
Minute,
Second,
Microsecond,
Calendar
).
-file("src/calendar/naive_datetime.gleam", 603).
?DOC(" Create NaiveDateTime with current date and specified time.\n").
-spec today_with_time(integer(), integer(), integer()) -> {ok,
naive_date_time()} |
{error, naive_date_time_error()}.
today_with_time(Hour, Minute, Second) ->
today_with_time_and_calendar(
Hour,
Minute,
Second,
{0, 0},
<<"Calendar.ISO"/utf8>>
).
-file("src/calendar/naive_datetime.gleam", 633).
?DOC(" Check if two naive datetimes are equal.\n").
-spec equal(naive_date_time(), naive_date_time()) -> boolean().
equal(Ndt1, Ndt2) ->
case compare(Ndt1, Ndt2) of
eq ->
true;
_ ->
false
end.
-file("src/calendar/naive_datetime.gleam", 641).
?DOC(" Get the day of year (1-366).\n").
-spec day_of_year(naive_date_time()) -> integer().
day_of_year(Ndt) ->
calendar@iso:day_of_year(
erlang:element(2, Ndt),
erlang:element(3, Ndt),
erlang:element(4, Ndt)
).
-file("src/calendar/naive_datetime.gleam", 646).
?DOC(" Get the day of week (1=Monday, 7=Sunday).\n").
-spec day_of_week(naive_date_time()) -> integer().
day_of_week(Ndt) ->
calendar@iso:day_of_week(
erlang:element(2, Ndt),
erlang:element(3, Ndt),
erlang:element(4, Ndt),
monday
).
-file("src/calendar/naive_datetime.gleam", 651).
?DOC(" Get the week of year (1-53).\n").
-spec week_of_year(naive_date_time()) -> integer().
week_of_year(Ndt) ->
(day_of_year(Ndt) div 7) + 1.
-file("src/calendar/naive_datetime.gleam", 656).
?DOC(" Get year from naive datetime.\n").
-spec year(naive_date_time()) -> integer().
year(Ndt) ->
erlang:element(2, Ndt).
-file("src/calendar/naive_datetime.gleam", 661).
?DOC(" Get month from naive datetime.\n").
-spec month(naive_date_time()) -> integer().
month(Ndt) ->
erlang:element(3, Ndt).
-file("src/calendar/naive_datetime.gleam", 666).
?DOC(" Get day from naive datetime.\n").
-spec day(naive_date_time()) -> integer().
day(Ndt) ->
erlang:element(4, Ndt).
-file("src/calendar/naive_datetime.gleam", 671).
?DOC(" Get hour from naive datetime.\n").
-spec hour(naive_date_time()) -> integer().
hour(Ndt) ->
erlang:element(5, Ndt).
-file("src/calendar/naive_datetime.gleam", 676).
?DOC(" Get minute from naive datetime.\n").
-spec minute(naive_date_time()) -> integer().
minute(Ndt) ->
erlang:element(6, Ndt).
-file("src/calendar/naive_datetime.gleam", 681).
?DOC(" Get second from naive datetime.\n").
-spec second(naive_date_time()) -> integer().
second(Ndt) ->
erlang:element(7, Ndt).
-file("src/calendar/naive_datetime.gleam", 686).
?DOC(" Get microsecond from naive datetime.\n").
-spec microsecond(naive_date_time()) -> {integer(), integer()}.
microsecond(Ndt) ->
erlang:element(8, Ndt).
-file("src/calendar/naive_datetime.gleam", 691).
?DOC(" Get calendar from naive datetime.\n").
-spec calendar(naive_date_time()) -> binary().
calendar(Ndt) ->
erlang:element(9, Ndt).
-file("src/calendar/naive_datetime.gleam", 696).
?DOC(" Validate if components make a valid naive datetime.\n").
-spec is_valid(
integer(),
integer(),
integer(),
integer(),
integer(),
integer(),
{integer(), integer()}
) -> boolean().
is_valid(Year, Month, Day, Hour, Minute, Second, Microsecond) ->
case new(
Year,
Month,
Day,
Hour,
Minute,
Second,
Microsecond,
<<"Calendar.ISO"/utf8>>
) of
{ok, _} ->
true;
{error, _} ->
false
end.
-file("src/calendar/naive_datetime.gleam", 733).
?DOC(" Create a new naive datetime with specified components replaced.\n").
-spec replace(
naive_date_time(),
integer(),
integer(),
integer(),
integer(),
integer(),
integer(),
{integer(), integer()}
) -> {ok, naive_date_time()} | {error, naive_date_time_error()}.
replace(Ndt, Year, Month, Day, Hour, Minute, Second, Microsecond) ->
new(
Year,
Month,
Day,
Hour,
Minute,
Second,
Microsecond,
erlang:element(9, Ndt)
).
-file("src/calendar/naive_datetime.gleam", 747).
?DOC(" Create a new naive datetime with only some components replaced.\n").
-spec replace_partial(naive_date_time(), integer(), integer(), integer()) -> {ok,
naive_date_time()} |
{error, naive_date_time_error()}.
replace_partial(Ndt, Year, Month, Day) ->
new(
Year,
Month,
Day,
erlang:element(5, Ndt),
erlang:element(6, Ndt),
erlang:element(7, Ndt),
erlang:element(8, Ndt),
erlang:element(9, Ndt)
).
-file("src/calendar/naive_datetime.gleam", 787).
?DOC(" Parse ISO8601 naive datetime string.\n").
-spec parse_iso8601_naive_datetime(binary()) -> {ok,
{integer(),
integer(),
integer(),
integer(),
integer(),
integer(),
{integer(), integer()}}} |
{error, nil}.
parse_iso8601_naive_datetime(Iso_string) ->
case gleam@string:split(Iso_string, <<"T"/utf8>>) of
[Date_part, Time_part] ->
case {gleam@string:split(Date_part, <<"-"/utf8>>),
gleam@string:split(Time_part, <<":"/utf8>>)} of
{[Year_str, Month_str, Day_str],
[Hour_str, Minute_str, Second_part]} ->
case {gleam_stdlib:parse_int(Year_str),
gleam_stdlib:parse_int(Month_str),
gleam_stdlib:parse_int(Day_str),
gleam_stdlib:parse_int(Hour_str),
gleam_stdlib:parse_int(Minute_str)} of
{{ok, Year},
{ok, Month},
{ok, Day},
{ok, Hour},
{ok, Minute}} ->
case gleam@string:split(Second_part, <<"."/utf8>>) of
[Second_str] ->
case gleam_stdlib:parse_int(Second_str) of
{ok, Second} ->
{ok,
{Year,
Month,
Day,
Hour,
Minute,
Second,
{0, 0}}};
{error, _} ->
{error, nil}
end;
[Second_str@1, Ms_str] ->
case {gleam_stdlib:parse_int(Second_str@1),
gleam_stdlib:parse_int(Ms_str)} of
{{ok, Second@1}, {ok, Ms}} ->
Precision = string:length(Ms_str),
{ok,
{Year,
Month,
Day,
Hour,
Minute,
Second@1,
{Ms, Precision}}};
{_, _} ->
{error, nil}
end;
_ ->
{error, nil}
end;
{_, _, _, _, _} ->
{error, nil}
end;
{_, _} ->
{error, nil}
end;
_ ->
{error, nil}
end.
-file("src/calendar/naive_datetime.gleam", 475).
?DOC(" Parse ISO8601 string to NaiveDateTime.\n").
-spec from_iso8601(binary()) -> {ok, naive_date_time()} |
{error, naive_date_time_error()}.
from_iso8601(Iso_string) ->
case parse_iso8601_naive_datetime(Iso_string) of
{ok, {Year, Month, Day, Hour, Minute, Second, Microsecond}} ->
new(
Year,
Month,
Day,
Hour,
Minute,
Second,
Microsecond,
<<"Calendar.ISO"/utf8>>
);
{error, _} ->
{error, invalid_naive_date_time}
end.
-file("src/calendar/naive_datetime.gleam", 486).
?DOC(" Parse ISO8601 string to NaiveDateTime, panicking on error.\n").
-spec from_iso8601_unchecked(binary()) -> naive_date_time().
from_iso8601_unchecked(Iso_string) ->
case from_iso8601(Iso_string) of
{ok, Ndt} ->
Ndt;
{error, _} ->
erlang:error(#{gleam_error => panic,
message => <<"Invalid ISO8601 naive datetime format"/utf8>>,
file => <<?FILEPATH/utf8>>,
module => <<"calendar/naive_datetime"/utf8>>,
function => <<"from_iso8601_unchecked"/utf8>>,
line => 489})
end.
-file("src/calendar/naive_datetime.gleam", 839).
?DOC(" Helper function to format microseconds with proper padding.\n").
-spec pad_microseconds(integer(), integer()) -> binary().
pad_microseconds(Microseconds, Precision) ->
Ms_str = erlang:integer_to_binary(Microseconds),
Padded = case string:length(Ms_str) < Precision of
true ->
<<(gleam@string:repeat(
<<"0"/utf8>>,
Precision - string:length(Ms_str)
))/binary,
Ms_str/binary>>;
false ->
Ms_str
end,
gleam@string:slice(Padded, 0, Precision).
-file("src/calendar/naive_datetime.gleam", 112).
?DOC(" Converts a NaiveDateTime to a string in ISO8601 format.\n").
-spec to_string(naive_date_time()) -> binary().
to_string(Ndt) ->
Date_part = <<<<<<<<(pad_left(
erlang:integer_to_binary(erlang:element(2, Ndt)),
4,
<<"0"/utf8>>
))/binary,
"-"/utf8>>/binary,
(pad_left(
erlang:integer_to_binary(erlang:element(3, Ndt)),
2,
<<"0"/utf8>>
))/binary>>/binary,
"-"/utf8>>/binary,
(pad_left(
erlang:integer_to_binary(erlang:element(4, Ndt)),
2,
<<"0"/utf8>>
))/binary>>,
Time_part = <<<<<<<<(pad_left(
erlang:integer_to_binary(erlang:element(5, Ndt)),
2,
<<"0"/utf8>>
))/binary,
":"/utf8>>/binary,
(pad_left(
erlang:integer_to_binary(erlang:element(6, Ndt)),
2,
<<"0"/utf8>>
))/binary>>/binary,
":"/utf8>>/binary,
(pad_left(
erlang:integer_to_binary(erlang:element(7, Ndt)),
2,
<<"0"/utf8>>
))/binary>>,
{Ms, Precision} = erlang:element(8, Ndt),
Microsecond_part = case (Ms =:= 0) orelse (Precision =:= 0) of
true ->
<<""/utf8>>;
false ->
<<"."/utf8, (pad_microseconds(Ms, Precision))/binary>>
end,
<<<<<<Date_part/binary, " "/utf8>>/binary, Time_part/binary>>/binary,
Microsecond_part/binary>>.
-file("src/calendar/naive_datetime.gleam", 142).
?DOC(" Converts a NaiveDateTime to ISO8601 with format option.\n").
-spec to_iso8601_with_format(naive_date_time(), calendar@iso:format()) -> binary().
to_iso8601_with_format(Ndt, Format) ->
{Ms, Precision} = erlang:element(8, Ndt),
Microsecond_part = case (Ms =:= 0) orelse (Precision =:= 0) of
true ->
<<""/utf8>>;
false ->
<<"."/utf8, (pad_microseconds(Ms, Precision))/binary>>
end,
case Format of
extended ->
Date_part = <<<<<<<<(pad_left(
erlang:integer_to_binary(erlang:element(2, Ndt)),
4,
<<"0"/utf8>>
))/binary,
"-"/utf8>>/binary,
(pad_left(
erlang:integer_to_binary(erlang:element(3, Ndt)),
2,
<<"0"/utf8>>
))/binary>>/binary,
"-"/utf8>>/binary,
(pad_left(
erlang:integer_to_binary(erlang:element(4, Ndt)),
2,
<<"0"/utf8>>
))/binary>>,
Time_part = <<<<<<<<(pad_left(
erlang:integer_to_binary(erlang:element(5, Ndt)),
2,
<<"0"/utf8>>
))/binary,
":"/utf8>>/binary,
(pad_left(
erlang:integer_to_binary(erlang:element(6, Ndt)),
2,
<<"0"/utf8>>
))/binary>>/binary,
":"/utf8>>/binary,
(pad_left(
erlang:integer_to_binary(erlang:element(7, Ndt)),
2,
<<"0"/utf8>>
))/binary>>,
<<<<<<Date_part/binary, "T"/utf8>>/binary, Time_part/binary>>/binary,
Microsecond_part/binary>>;
basic ->
Date_part@1 = <<<<(pad_left(
erlang:integer_to_binary(erlang:element(2, Ndt)),
4,
<<"0"/utf8>>
))/binary,
(pad_left(
erlang:integer_to_binary(erlang:element(3, Ndt)),
2,
<<"0"/utf8>>
))/binary>>/binary,
(pad_left(
erlang:integer_to_binary(erlang:element(4, Ndt)),
2,
<<"0"/utf8>>
))/binary>>,
Time_part@1 = <<<<(pad_left(
erlang:integer_to_binary(erlang:element(5, Ndt)),
2,
<<"0"/utf8>>
))/binary,
(pad_left(
erlang:integer_to_binary(erlang:element(6, Ndt)),
2,
<<"0"/utf8>>
))/binary>>/binary,
(pad_left(
erlang:integer_to_binary(erlang:element(7, Ndt)),
2,
<<"0"/utf8>>
))/binary>>,
<<<<<<Date_part@1/binary, "T"/utf8>>/binary, Time_part@1/binary>>/binary,
Microsecond_part/binary>>
end.
-file("src/calendar/naive_datetime.gleam", 137).
?DOC(" Converts a NaiveDateTime to ISO8601 extended format.\n").
-spec to_iso8601(naive_date_time()) -> binary().
to_iso8601(Ndt) ->
to_iso8601_with_format(Ndt, extended).
-file("src/calendar/naive_datetime.gleam", 578).
?DOC(" Get string representation for inspection.\n").
-spec inspect(naive_date_time()) -> binary().
inspect(Ndt) ->
<<<<"~N["/utf8, (to_string(Ndt))/binary>>/binary, "]"/utf8>>.
-file("src/calendar/naive_datetime.gleam", 222).
?DOC(" Create NaiveDateTime from Unix timestamp.\n").
-spec from_timestamp(integer()) -> {ok, naive_date_time()} |
{error, naive_date_time_error()}.
from_timestamp(Timestamp) ->
Days_since_epoch = case 86400 of
0 -> 0;
Gleam@denominator -> Timestamp div Gleam@denominator
end,
Seconds_in_day = case 86400 of
0 -> 0;
Gleam@denominator@1 -> Timestamp rem Gleam@denominator@1
end,
case calendar@date:from_timestamp(Days_since_epoch * 86400) of
{error, _} ->
{error, invalid_date};
{ok, Date_val} ->
case calendar@time:from_seconds_after_midnight(Seconds_in_day) of
{error, _} ->
{error, invalid_time};
{ok, Time_val} ->
from_date_and_time(Date_val, Time_val)
end
end.
-file("src/calendar/naive_datetime.gleam", 205).
?DOC(" Add seconds to a NaiveDateTime.\n").
-spec add_seconds(naive_date_time(), integer()) -> {ok, naive_date_time()} |
{error, naive_date_time_error()}.
add_seconds(Ndt, Seconds) ->
Current_timestamp = to_timestamp(Ndt),
from_timestamp(Current_timestamp + Seconds).
-file("src/calendar/naive_datetime.gleam", 290).
?DOC(" Add days to a naive datetime.\n").
-spec add_days(naive_date_time(), integer()) -> {ok, naive_date_time()} |
{error, naive_date_time_error()}.
add_days(Ndt, Days) ->
Current_timestamp = to_timestamp(Ndt),
from_timestamp(Current_timestamp + (Days * 86400)).
-file("src/calendar/naive_datetime.gleam", 299).
?DOC(" Add hours to a naive datetime.\n").
-spec add_hours(naive_date_time(), integer()) -> {ok, naive_date_time()} |
{error, naive_date_time_error()}.
add_hours(Ndt, Hours) ->
Current_timestamp = to_timestamp(Ndt),
from_timestamp(Current_timestamp + (Hours * 3600)).
-file("src/calendar/naive_datetime.gleam", 308).
?DOC(" Add minutes to a naive datetime.\n").
-spec add_minutes(naive_date_time(), integer()) -> {ok, naive_date_time()} |
{error, naive_date_time_error()}.
add_minutes(Ndt, Minutes) ->
Current_timestamp = to_timestamp(Ndt),
from_timestamp(Current_timestamp + (Minutes * 60)).
-file("src/calendar/naive_datetime.gleam", 345).
?DOC(" Add amount to naive datetime with validation.\n").
-spec add_with_validation(
naive_date_time(),
integer(),
calendar@time:time_unit()
) -> {ok, naive_date_time()} | {error, naive_date_time_error()}.
add_with_validation(Ndt, Amount, Unit) ->
Microseconds_to_add = case Unit of
second ->
Amount * 1000000;
millisecond ->
Amount * 1000;
microsecond ->
Amount;
native ->
Amount
end,
Current_timestamp = to_timestamp(Ndt) * 1000000,
{Ms, _} = erlang:element(8, Ndt),
Total_us = (Current_timestamp + Ms) + Microseconds_to_add,
Total_seconds = Total_us div 1000000,
Remaining_us = Total_us rem 1000000,
Precision = case Unit of
second ->
0;
millisecond ->
3;
microsecond ->
6;
native ->
6
end,
{_, Old_precision} = erlang:element(8, Ndt),
Final_precision = case Precision > Old_precision of
true ->
Precision;
false ->
Old_precision
end,
Days_since_epoch = case 86400 of
0 -> 0;
Gleam@denominator -> Total_seconds div Gleam@denominator
end,
Seconds_in_day = case 86400 of
0 -> 0;
Gleam@denominator@1 -> Total_seconds rem Gleam@denominator@1
end,
case calendar@date:from_days_since_unix_epoch(
Days_since_epoch,
erlang:element(9, Ndt)
) of
{error, _} ->
{error, invalid_date};
{ok, Date_val} ->
case calendar@time:from_seconds_after_midnight_with_microsecond(
Seconds_in_day,
{Remaining_us, Final_precision},
erlang:element(9, Ndt)
) of
{error, _} ->
{error, invalid_time};
{ok, Time_val} ->
from_date_and_time(Date_val, Time_val)
end
end.
-file("src/calendar/naive_datetime.gleam", 332).
?DOC(" Add amount to a naive datetime with specified unit.\n").
-spec add(naive_date_time(), integer(), calendar@time:time_unit()) -> naive_date_time().
add(Ndt, Amount, Unit) ->
case add_with_validation(Ndt, Amount, Unit) of
{ok, New_ndt} ->
New_ndt;
{error, _} ->
Ndt
end.
-file("src/calendar/naive_datetime.gleam", 583).
?DOC(" Create from Gregorian seconds since epoch 0000-01-01 00:00:00.\n").
-spec from_gregorian_seconds(integer(), {integer(), integer()}, binary()) -> {ok,
naive_date_time()} |
{error, naive_date_time_error()}.
from_gregorian_seconds(Seconds, _, _) ->
from_timestamp(Seconds - 62167219200).
-file("src/calendar/naive_datetime.gleam", 767).
-spec range_helper(integer(), integer(), integer(), list(naive_date_time())) -> list(naive_date_time()).
range_helper(Current_ts, End_ts, Step, Acc) ->
case Current_ts >= End_ts of
true ->
_pipe = Acc,
lists:reverse(_pipe);
false ->
case from_timestamp(Current_ts) of
{ok, Ndt} ->
range_helper(Current_ts + Step, End_ts, Step, [Ndt | Acc]);
{error, _} ->
_pipe@1 = Acc,
lists:reverse(_pipe@1)
end
end.
-file("src/calendar/naive_datetime.gleam", 714).
?DOC(" Create naive datetime range.\n").
-spec range(naive_date_time(), naive_date_time(), integer()) -> list(naive_date_time()).
range(Start, End, Step_seconds) ->
case Step_seconds =< 0 of
true ->
[];
false ->
Start_ts = to_timestamp(Start),
End_ts = to_timestamp(End),
case Start_ts >= End_ts of
true ->
[];
false ->
range_helper(Start_ts, End_ts, Step_seconds, [])
end
end.