Skip to content

Commit 5d103ea

Browse files
authored
Add support for epoch time (%s) to Calendar strftime (#12380)
1 parent aae95da commit 5d103ea

File tree

2 files changed

+49
-0
lines changed

2 files changed

+49
-0
lines changed

lib/elixir/lib/calendar.ex

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -464,6 +464,7 @@ defmodule Calendar do
464464
p | "AM" or "PM" (noon is "PM", midnight as "AM") | AM, PM
465465
P | "am" or "pm" (noon is "pm", midnight as "am") | am, pm
466466
q | Quarter | 1, 2, 3, 4
467+
s | Number of seconds since the Epoch, 1970-01-01 00:00:00+0000 (UTC) | 1565888877
467468
S | Second | 00, 59, 60
468469
u | Day of the week | 1 (Monday), 7 (Sunday)
469470
x | Preferred date (without time) representation | 2018-10-17
@@ -804,6 +805,34 @@ defmodule Calendar do
804805
parse(rest, datetime, format_options, [result | acc])
805806
end
806807

808+
# Epoch time for DateTime with time zones
809+
defp format_modifiers(
810+
"s" <> rest,
811+
_width,
812+
_pad,
813+
datetime = %{utc_offset: _utc_offset, std_offset: _std_offset},
814+
format_options,
815+
acc
816+
) do
817+
result =
818+
datetime
819+
|> DateTime.shift_zone!("Etc/UTC")
820+
|> NaiveDateTime.diff(~N[1970-01-01 00:00:00])
821+
|> Integer.to_string()
822+
823+
parse(rest, datetime, format_options, [result | acc])
824+
end
825+
826+
# Epoch time
827+
defp format_modifiers("s" <> rest, _width, _pad, datetime, format_options, acc) do
828+
result =
829+
datetime
830+
|> NaiveDateTime.diff(~N[1970-01-01 00:00:00])
831+
|> Integer.to_string()
832+
833+
parse(rest, datetime, format_options, [result | acc])
834+
end
835+
807836
# +hhmm/-hhmm time zone offset from UTC (empty string if naive)
808837
defp format_modifiers(
809838
"z" <> rest,

lib/elixir/test/elixir/calendar_test.exs

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,26 @@ defmodule CalendarTest do
336336
assert Calendar.strftime(~N[2019-08-15 17:07:57], "%010A") == "00Thursday"
337337
end
338338

339+
test "formats Epoch time with %s" do
340+
assert Calendar.strftime(~N[2019-08-15 17:07:57], "%s") == "1565888877"
341+
342+
datetime = %DateTime{
343+
year: 2019,
344+
month: 8,
345+
day: 15,
346+
hour: 17,
347+
minute: 7,
348+
second: 57,
349+
microsecond: {0, 0},
350+
time_zone: "Europe/Berlin",
351+
zone_abbr: "CET",
352+
utc_offset: 3600,
353+
std_offset: 0
354+
}
355+
356+
assert Calendar.strftime(datetime, "%s") == "1565885277"
357+
end
358+
339359
test "formats datetime with all options and modifiers" do
340360
assert Calendar.strftime(
341361
~U[2019-08-15 17:07:57.001Z],

0 commit comments

Comments
 (0)