Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion lib/elixir/lib/calendar/duration.ex
Original file line number Diff line number Diff line change
Expand Up @@ -532,7 +532,7 @@ defmodule Duration do
sign,
Integer.to_string(second),
?.,
ms |> Integer.to_string() |> String.pad_leading(6, "0") |> binary_part(0, p)
Calendar.ISO.microseconds_to_iodata(ms, p)
]
end

Expand Down
88 changes: 86 additions & 2 deletions lib/elixir/lib/json.ex
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,93 @@ defimpl JSON.Encoder, for: Map do
end
end

defimpl JSON.Encoder, for: [Date, Time, NaiveDateTime, DateTime, Duration] do
defimpl JSON.Encoder, for: Duration do
def encode(value, _encoder) do
[?", @for.to_iso8601(value), ?"]
[?", Duration.to_iso8601(value), ?"]
end
end

defimpl JSON.Encoder, for: Date do
def encode(%{calendar: Calendar.ISO} = date, _encoder) do
%{year: year, month: month, day: day} = date
[?", Calendar.ISO.date_to_iodata(year, month, day), ?"]
end

def encode(value, _encoder) do
[?", Date.to_iso8601(value), ?"]
end
end

defimpl JSON.Encoder, for: Time do
def encode(%{calendar: Calendar.ISO} = time, _encoder) do
%{
hour: hour,
minute: minute,
second: second,
microsecond: microsecond
} = time

[?", Calendar.ISO.time_to_iodata(hour, minute, second, microsecond), ?"]
end

def encode(value, _encoder) do
[?", Time.to_iso8601(value), ?"]
end
end

defimpl JSON.Encoder, for: NaiveDateTime do
def encode(%{calendar: Calendar.ISO} = naive_datetime, _encoder) do
%{
year: year,
month: month,
day: day,
hour: hour,
minute: minute,
second: second,
microsecond: microsecond
} = naive_datetime

[
?",
Calendar.ISO.date_to_iodata(year, month, day),
?T,
Calendar.ISO.time_to_iodata(hour, minute, second, microsecond),
?"
]
end

def encode(value, _encoder) do
[?", NaiveDateTime.to_iso8601(value), ?"]
end
end

defimpl JSON.Encoder, for: DateTime do
def encode(%{calendar: Calendar.ISO} = datetime, _encoder) do
%{
year: year,
month: month,
day: day,
hour: hour,
minute: minute,
second: second,
microsecond: microsecond,
time_zone: time_zone,
utc_offset: utc_offset,
std_offset: std_offset
} = datetime

[
?",
Calendar.ISO.date_to_iodata(year, month, day),
?T,
Calendar.ISO.time_to_iodata(hour, minute, second, microsecond),
Calendar.ISO.offset_to_iodata(utc_offset, std_offset, time_zone, :extended),
?"
]
end

def encode(value, _encoder) do
[?", DateTime.to_iso8601(value), ?"]
end
end

Expand Down
12 changes: 12 additions & 0 deletions lib/elixir/test/elixir/json_test.exs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,18 @@ defmodule JSONTest do
list = JSON.encode_to_iodata!([1, 1.0, "one", %{1 => 2, 3.0 => 4.0, key: :bar}])
assert is_list(list)
assert IO.iodata_to_binary(list) == "[1,1.0,\"one\",{\"1\":2,\"3.0\":4.0,\"key\":\"bar\"}]"

list =
JSON.encode_to_iodata!([
~T[12:34:56.78],
~D[2024-12-31],
~N[2010-04-17 14:00:00.123],
~U[2010-04-17 14:00:00.123Z],
Duration.new!(month: 2, hour: 3)
])

assert IO.iodata_to_binary(list) ==
~s'["12:34:56.78","2024-12-31","2010-04-17T14:00:00.123","2010-04-17T14:00:00.123Z","P2MT3H"]'
end

test "deprecated" do
Expand Down
Loading