zf

zenflows testing
git clone https://s.sonu.ch/~srfsh/zf.git
Log | Files | Refs | Submodules | README | LICENSE

timetz.ex (1637B)


      1 defmodule Postgrex.Extensions.TimeTZ do
      2   @moduledoc false
      3   import Postgrex.BinaryUtils, warn: false
      4   use Postgrex.BinaryExtension, send: "timetz_send"
      5 
      6   @day (:calendar.time_to_seconds({23, 59, 59}) + 1) * 1_000_000
      7 
      8   def encode(_) do
      9     quote location: :keep do
     10       %Time{calendar: Calendar.ISO} = time ->
     11         unquote(__MODULE__).encode_elixir(time)
     12 
     13       other ->
     14         raise DBConnection.EncodeError, Postgrex.Utils.encode_msg(other, Time)
     15     end
     16   end
     17 
     18   def decode(_) do
     19     quote location: :keep do
     20       <<12::int32(), microsecs::int64(), tz::int32()>> ->
     21         unquote(__MODULE__).microsecond_to_elixir(microsecs, tz)
     22     end
     23   end
     24 
     25   ## Helpers
     26 
     27   defp adjust_microsecond(microsec, tz) do
     28     case microsec + tz * 1_000_000 do
     29       adjusted_microsec when adjusted_microsec < 0 ->
     30         @day + adjusted_microsec
     31 
     32       adjusted_microsec when adjusted_microsec < @day ->
     33         adjusted_microsec
     34 
     35       adjusted_microsec ->
     36         adjusted_microsec - @day
     37     end
     38   end
     39 
     40   def encode_elixir(%Time{hour: hour, minute: min, second: sec, microsecond: {usec, _}})
     41       when hour in 0..23 and min in 0..59 and sec in 0..59 and usec in 0..999_999 do
     42     time = {hour, min, sec}
     43     <<12::int32(), :calendar.time_to_seconds(time) * 1_000_000 + usec::int64(), 0::int32()>>
     44   end
     45 
     46   def microsecond_to_elixir(microsec, tz) do
     47     microsec
     48     |> adjust_microsecond(tz)
     49     |> microsecond_to_elixir()
     50   end
     51 
     52   defp microsecond_to_elixir(microsec) do
     53     sec = div(microsec, 1_000_000)
     54     microsec = rem(microsec, 1_000_000)
     55 
     56     sec
     57     |> :calendar.seconds_to_time()
     58     |> Time.from_erl!({microsec, 6})
     59   end
     60 end