Packages
postgrex
0.16.5
1.0.0-rc.1
retired
1.0.0-rc.0
retired
0.22.3
0.22.2
0.22.1
0.22.0
0.21.1
0.21.0
0.20.0
0.19.3
0.19.2
0.19.1
0.19.0
0.18.0
0.17.5
0.17.4
0.17.3
0.17.2
0.17.1
0.17.0
0.16.5
0.16.4
0.16.3
0.16.2
0.16.1
0.16.0
0.15.13
0.15.12
0.15.11
0.15.10
0.15.9
0.15.8
0.15.7
0.15.6
0.15.5
0.15.4
0.15.3
0.15.2
0.15.1
0.15.0
0.14.3
0.14.2
0.14.1
0.14.0
0.14.0-rc.1
0.14.0-rc.0
0.13.5
0.13.4
0.13.3
0.13.2
0.13.1
0.13.0
0.13.0-rc.0
0.12.2
0.12.1
0.12.0
0.11.2
0.11.1
0.11.0
0.10.0
0.9.1
0.9.0
0.8.4
0.8.3
0.8.2
0.8.1
0.8.0
0.7.0
0.6.0
0.5.5
0.5.4
0.5.3
0.5.2
0.5.1
0.5.0
0.4.2
PostgreSQL driver for Elixir
Security advisory:
This version has known vulnerabilities.
View advisories
Current section
Files
Jump to
Current section
Files
lib/postgrex/extensions/timetz.ex
defmodule Postgrex.Extensions.TimeTZ do
@moduledoc false
import Postgrex.BinaryUtils, warn: false
use Postgrex.BinaryExtension, send: "timetz_send"
@day (:calendar.time_to_seconds({23, 59, 59}) + 1) * 1_000_000
def encode(_) do
quote location: :keep do
%Time{calendar: Calendar.ISO} = time ->
unquote(__MODULE__).encode_elixir(time)
other ->
raise DBConnection.EncodeError, Postgrex.Utils.encode_msg(other, Time)
end
end
def decode(_) do
quote location: :keep do
<<12::int32(), microsecs::int64(), tz::int32()>> ->
unquote(__MODULE__).microsecond_to_elixir(microsecs, tz)
end
end
## Helpers
defp adjust_microsecond(microsec, tz) do
case microsec + tz * 1_000_000 do
adjusted_microsec when adjusted_microsec < 0 ->
@day + adjusted_microsec
adjusted_microsec when adjusted_microsec < @day ->
adjusted_microsec
adjusted_microsec ->
adjusted_microsec - @day
end
end
def encode_elixir(%Time{hour: hour, minute: min, second: sec, microsecond: {usec, _}})
when hour in 0..23 and min in 0..59 and sec in 0..59 and usec in 0..999_999 do
time = {hour, min, sec}
<<12::int32(), :calendar.time_to_seconds(time) * 1_000_000 + usec::int64(), 0::int32()>>
end
def microsecond_to_elixir(microsec, tz) do
microsec
|> adjust_microsecond(tz)
|> microsecond_to_elixir()
end
defp microsecond_to_elixir(microsec) do
sec = div(microsec, 1_000_000)
microsec = rem(microsec, 1_000_000)
sec
|> :calendar.seconds_to_time()
|> Time.from_erl!({microsec, 6})
end
end