diff --git a/lib/cocktail/util.ex b/lib/cocktail/util.ex index 21a85f5..c93bd5c 100644 --- a/lib/cocktail/util.ex +++ b/lib/cocktail/util.ex @@ -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 diff --git a/lib/cocktail/validation/shift.ex b/lib/cocktail/validation/shift.ex index 4f1975f..1c5c766 100644 --- a/lib/cocktail/validation/shift.ex +++ b/lib/cocktail/validation/shift.ex @@ -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 @@ -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