Current section
Files
Jump to
Current section
Files
lib/formatter.ex
defmodule Moment.Formatter do
@doc """
Format moment according to format string.
"""
def format(moment, format_str) do
format(moment, format_str, "")
end
# Tail-recursive format
# ---------------------
defp format(moment, "YYYY" <> rest, output_str) do
format(moment, rest, output_str <> Integer.to_string(moment.year))
end
defp format(moment, "YY" <> rest, output_str) do
format(moment, rest, output_str <> format_digits(rem(moment.year, 100), 2))
end
defp format(moment, "Q" <> rest, output_str) do
format(moment, rest, output_str <> Integer.to_string(Moment.quarter(moment)))
end
defp format(moment, "MM" <> rest, output_str) do
format(moment, rest, output_str <> format_digits(moment.month, 2))
end
defp format(moment, "M" <> rest, output_str) do
format(moment, rest, output_str <> Integer.to_string(moment.month))
end
defp format(moment, "DD" <> rest, output_str) do
format(moment, rest, output_str <> format_digits(moment.day, 2))
end
defp format(moment, "D" <> rest, output_str) do
format(moment, rest, output_str <> Integer.to_string(moment.day))
end
defp format(moment, "HH" <> rest, output_str) do
format(moment, rest, output_str <> format_digits(moment.hour, 2))
end
defp format(moment, "H" <> rest, output_str) do
format(moment, rest, output_str <> Integer.to_string(moment.hour))
end
defp format(moment, "mm" <> rest, output_str) do
format(moment, rest, output_str <> format_digits(moment.minute, 2))
end
defp format(moment, "m" <> rest, output_str) do
format(moment, rest, output_str <> Integer.to_string(moment.minute))
end
defp format(moment, "ss" <> rest, output_str) do
format(moment, rest, output_str <> format_digits(moment.second, 2))
end
defp format(moment, "s" <> rest, output_str) do
format(moment, rest, output_str <> Integer.to_string(moment.second))
end
defp format(moment, "SSSSSSSSS" <> rest, output_str) do
format(moment, rest, output_str <> format_digits(moment.nanosecond, 9))
end
defp format(moment, "SSSSSS" <> rest, output_str) do
format(moment, rest, output_str <> format_digits(div(moment.nanosecond, 1_000), 6))
end
defp format(moment, "SSS" <> rest, output_str) do
format(moment, rest, output_str <> format_digits(div(moment.nanosecond, 1_000_000), 3))
end
defp format(moment, "SS" <> rest, output_str) do
format(moment, rest, output_str <> format_digits(div(moment.nanosecond, 10_000_000), 2))
end
defp format(moment, "S" <> rest, output_str) do
format(moment, rest, output_str <> Integer.to_string(div(moment.nanosecond, 100_000_000)))
end
defp format(moment, "ZZ" <> rest, output_str) do
format(moment, rest, output_str <> format_offset(moment, ""))
end
defp format(moment, "Z" <> rest, output_str) do
format(moment, rest, output_str <> format_offset(moment, ":"))
end
defp format(moment, << h, rest :: binary >>, output_str) do
format(moment, rest, output_str <> <<h>>)
end
defp format(_, "", output_str) do
output_str
end
# Private
# -------
defp format_offset(moment, separator) do
offset_h = format_digits(div(abs(moment.offset), 60), 2)
offset_m = format_digits(rem(abs(moment.offset), 60), 2)
sign = if moment.offset >= 0, do: "+", else: "-"
"#{sign}#{offset_h}#{separator}#{offset_m}"
end
defp format_digits(i, n) do
:erlang.iolist_to_binary(:io_lib.format("~.#{n}.0w", [i]))
end
end