Skip to content

Commit

Permalink
fix: Daylight saving
Browse files Browse the repository at this point in the history
  • Loading branch information
Matsa59 committed Jan 3, 2024
1 parent f3ea473 commit 29e618f
Show file tree
Hide file tree
Showing 2 changed files with 12 additions and 24 deletions.
12 changes: 12 additions & 0 deletions lib/cocktail/util.ex
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,22 @@ defmodule Cocktail.Util do
def shift_time(datetime, opts) do
datetime
|> Timex.shift(opts)
|> shift_dst(datetime)
|> no_ms()
end

def no_ms(time) do
Map.put(time, :microsecond, {0, 0})
end

# In case of datetime we may expect the same timezone hour
# For example after daylight saving 10h MUST still 10h the next day.
# This behaviour could only happen on datetime with timezone (that include `std_offset`)
defp shift_dst(time, datetime) do
if offset = Map.get(datetime, :std_offset) do
Timex.shift(time, seconds: offset - time.std_offset)
else
time
end
end
end
24 changes: 0 additions & 24 deletions lib/cocktail/validation/shift.ex
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ defmodule Cocktail.Validation.Shift do
time
|> shift_time("#{type}": amount)
|> apply_option(option)
|> maybe_dst_change(time)

{:change, new_time}
end
Expand All @@ -30,27 +29,4 @@ defmodule Cocktail.Validation.Shift do
defp apply_option(time, :beginning_of_day), do: time |> beginning_of_day()
defp apply_option(time, :beginning_of_hour), do: %{time | minute: 0, second: 0, microsecond: {0, 0}}
defp apply_option(time, :beginning_of_minute), do: %{time | second: 0, microsecond: {0, 0}}

defp maybe_dst_change(%DateTime{} = new_time, %DateTime{} = time) do
dst_diff = new_time.std_offset - time.std_offset

case dst_diff do
0 ->
new_time

diff ->
maybe_shift_time(new_time, time, diff)
end
end

defp maybe_dst_change(new_time, _time), do: new_time

defp maybe_shift_time(new_time, time, dst_diff) do
shifted_time = shift_time(new_time, seconds: -dst_diff)

case DateTime.compare(shifted_time, time) do
:eq -> new_time
_ -> shifted_time
end
end
end

0 comments on commit 29e618f

Please sign in to comment.