-
Notifications
You must be signed in to change notification settings - Fork 3.5k
dk_use_iodata_for_datetime_formatting #14130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
4f66340
621cef0
9303f84
75ed764
6f63ca3
7025133
e091108
09eb9bf
fbdf235
3a1a74e
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -1220,6 +1220,29 @@ defmodule Calendar.ISO do | |||||||||||
| :basic | :extended | ||||||||||||
| ) :: String.t() | ||||||||||||
| def time_to_string( | ||||||||||||
| hour, | ||||||||||||
| minute, | ||||||||||||
| second, | ||||||||||||
| microsecond, | ||||||||||||
| format \\ :extended | ||||||||||||
| ) do | ||||||||||||
| time_to_iodata(hour, minute, second, microsecond, format) | ||||||||||||
| |> IO.iodata_to_binary() | ||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| @doc """ | ||||||||||||
| Converts the given time into a iodata. | ||||||||||||
|
|
||||||||||||
| Look at time_to_string/5 for more information | ||||||||||||
|
|
||||||||||||
| ## Examples | ||||||||||||
|
|
||||||||||||
| iex> Calendar.ISO.time_to_iodata(2, 2, 2, {2, 6}) | ||||||||||||
| [[["0", "2"], 58, ["0", "2"], 58, ["0", "2"]], 46, ["00000", "2"]] | ||||||||||||
|
||||||||||||
|
|
||||||||||||
| """ | ||||||||||||
| @doc since: "1.19.0" | ||||||||||||
josevalim marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||
| def time_to_iodata( | ||||||||||||
| hour, | ||||||||||||
| minute, | ||||||||||||
| second, | ||||||||||||
|
|
@@ -1228,24 +1251,41 @@ defmodule Calendar.ISO do | |||||||||||
| ) | ||||||||||||
| when is_hour(hour) and is_minute(minute) and is_second(second) and | ||||||||||||
| is_microsecond(ms_value, ms_precision) and format in [:basic, :extended] do | ||||||||||||
| time_to_string_guarded(hour, minute, second, microsecond, format) | ||||||||||||
| time_to_iodata_guarded(hour, minute, second, microsecond, format) | ||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| defp time_to_string_guarded(hour, minute, second, {_, 0}, format) do | ||||||||||||
| time_to_string_format(hour, minute, second, format) | ||||||||||||
| defp time_to_iodata_guarded(hour, minute, second, {_, 0}, format) do | ||||||||||||
| time_to_iodata_format(hour, minute, second, format) | ||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| defp time_to_string_guarded(hour, minute, second, {microsecond, precision}, format) do | ||||||||||||
| time_to_string_format(hour, minute, second, format) <> | ||||||||||||
| "." <> (microsecond |> zero_pad(6) |> binary_part(0, precision)) | ||||||||||||
| defp time_to_iodata_guarded(hour, minute, second, {microsecond, precision}, format) do | ||||||||||||
| [ | ||||||||||||
| time_to_iodata_format(hour, minute, second, format), | ||||||||||||
| ?., | ||||||||||||
| microseconds_to_iodata(microsecond, precision) | ||||||||||||
| ] | ||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| defp time_to_string_format(hour, minute, second, :extended) do | ||||||||||||
| zero_pad(hour, 2) <> ":" <> zero_pad(minute, 2) <> ":" <> zero_pad(second, 2) | ||||||||||||
| defp microseconds_to_iodata(_microsecond, 0), do: [] | ||||||||||||
| defp microseconds_to_iodata(microsecond, 6), do: zero_pad(microsecond, 6) | ||||||||||||
|
|
||||||||||||
| defp microseconds_to_iodata(microsecond, precision) do | ||||||||||||
| num = div(microsecond, div_factor(precision)) | ||||||||||||
| zero_pad(num, precision) | ||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| defp time_to_string_format(hour, minute, second, :basic) do | ||||||||||||
| zero_pad(hour, 2) <> zero_pad(minute, 2) <> zero_pad(second, 2) | ||||||||||||
| defp div_factor(1), do: 100_000 | ||||||||||||
| defp div_factor(2), do: 10_000 | ||||||||||||
| defp div_factor(3), do: 1_000 | ||||||||||||
| defp div_factor(4), do: 100 | ||||||||||||
| defp div_factor(5), do: 10 | ||||||||||||
|
|
||||||||||||
| defp time_to_iodata_format(hour, minute, second, :extended) do | ||||||||||||
| [zero_pad(hour, 2), ?:, zero_pad(minute, 2), ?:, zero_pad(second, 2)] | ||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| defp time_to_iodata_format(hour, minute, second, :basic) do | ||||||||||||
| [zero_pad(hour, 2), zero_pad(minute, 2), zero_pad(second, 2)] | ||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| @doc """ | ||||||||||||
|
|
@@ -1273,18 +1313,34 @@ defmodule Calendar.ISO do | |||||||||||
| @doc since: "1.4.0" | ||||||||||||
| @spec date_to_string(year, month, day, :basic | :extended) :: String.t() | ||||||||||||
| @impl true | ||||||||||||
| def date_to_string(year, month, day, format \\ :extended) | ||||||||||||
| def date_to_string(year, month, day, format \\ :extended) do | ||||||||||||
| date_to_iodata(year, month, day, format) | ||||||||||||
| |> IO.iodata_to_binary() | ||||||||||||
| end | ||||||||||||
|
|
||||||||||||
| @doc """ | ||||||||||||
| Converts the given date into a iodata. | ||||||||||||
| Look at date_to_string/4 for more information | ||||||||||||
|
||||||||||||
| Converts the given date into a iodata. | |
| Look at date_to_string/4 for more information | |
| Converts the given date into an iodata. | |
| See `date_to_string/4` for more information. |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Converts the given naive_datetime into a iodata. | |
| Look at naive_datetime_to_iodata/8 for more information | |
| Converts the given naive_datetime into an iodata. | |
| See `naive_datetime_to_iodata/8` for more information. |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
| Converts the given datetime into a iodata. | |
| Look at datetime_to_iodata/12 for more information | |
| Converts the given datetime into an iodata. | |
| See `datetime_to_iodata/12` for more information. |
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps a further optimization if we're using IO-data is to use improper lists when possible, replacing the last , by |:
| [?-, zero_pad(-val, count)] | |
| [?- | zero_pad(-val, count)] |
I haven't benchmarked it and wouldn't expect it to be a huge difference, but it should create less cons cells in theory?
(we might need to use @dialyzer :no_improper_lists)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@sabiwara it makes a difference in the memory usage:
Name ips average deviation median 99th %
Calendar.IOISO.datetime_to_iodata 4.89 M 204.42 ns ±19386.20% 160 ns 271 ns
Memory usage statistics:
Name Memory usage
Calendar.IOISO.datetime_to_iodata 376 B
**All measurements for memory usage were the same**
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.