Skip to content

Commit ef53759

Browse files
committed
Merge pull request #4786 from lau/datetime_unix
add DateTime.to_unix/2 can accept non-UTC DateTime structs
2 parents 25fee6a + 32b9b5e commit ef53759

File tree

1 file changed

+31
-24
lines changed

1 file changed

+31
-24
lines changed

lib/elixir/lib/calendar.ex

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ defmodule DateTime do
10561056
@doc """
10571057
Converts the given DateTime to Unix time.
10581058
1059-
The DateTime is expected to be UTC using the ISO calendar
1059+
The DateTime is expected to be using the ISO calendar
10601060
with a year greater than or equal to 1970.
10611061
10621062
It will return the integer with the given unit,
@@ -1067,12 +1067,19 @@ defmodule DateTime do
10671067
iex> 1464096368 |> DateTime.from_unix!() |> DateTime.to_unix()
10681068
1464096368
10691069
1070+
iex> %DateTime{calendar: Calendar.ISO, day: 20, hour: 18, microsecond: {273806, 6}, minute: 58,
1071+
...> month: 11, second: 19, time_zone: "America/Montevideo",
1072+
...> utc_offset: -10800, std_offset: 3600, year: 2014, zone_abbr: "UYST"}
1073+
...> |> DateTime.to_unix()
1074+
1416517099
10701075
"""
10711076
@spec to_unix(DateTime.t, System.time_unit) :: non_neg_integer
1072-
def to_unix(%DateTime{std_offset: 0, utc_offset: 0, time_zone: "Etc/UTC",
1077+
def to_unix(%DateTime{std_offset: std_offset, utc_offset: utc_offset,
10731078
hour: hour, minute: minute, second: second, microsecond: {microsecond, _},
10741079
year: year, month: month, day: day}, unit \\ :seconds) when year >= 1970 do
10751080
seconds = :calendar.datetime_to_gregorian_seconds({{year, month, day}, {hour, minute, second}})
1081+
|> Kernel.-(utc_offset)
1082+
|> Kernel.-(std_offset)
10761083
System.convert_time_unit((seconds - @unix_epoch) * 1_000_000 + microsecond, :microseconds, unit)
10771084
end
10781085

@@ -1084,9 +1091,9 @@ defmodule DateTime do
10841091
10851092
## Examples
10861093
1087-
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CEST",
1094+
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
10881095
...> hour: 23, minute: 0, second: 7, microsecond: {0, 1},
1089-
...> utc_offset: 3600, std_offset: 3600, time_zone: "Europe/Warsaw"}
1096+
...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
10901097
iex> DateTime.to_naive(dt)
10911098
~N[2000-02-29 23:00:07.0]
10921099
@@ -1105,9 +1112,9 @@ defmodule DateTime do
11051112
11061113
## Examples
11071114
1108-
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CEST",
1109-
...> hour: 23, minute: 0, second: 7, microsecond: 0,
1110-
...> utc_offset: 3600, std_offset: 3600, time_zone: "Europe/Warsaw"}
1115+
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
1116+
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
1117+
...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
11111118
iex> DateTime.to_date(dt)
11121119
~D[2000-02-29]
11131120
@@ -1124,9 +1131,9 @@ defmodule DateTime do
11241131
11251132
## Examples
11261133
1127-
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CEST",
1134+
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
11281135
...> hour: 23, minute: 0, second: 7, microsecond: {0, 1},
1129-
...> utc_offset: 3600, std_offset: 3600, time_zone: "Europe/Warsaw"}
1136+
...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
11301137
iex> DateTime.to_time(dt)
11311138
~T[23:00:07.0]
11321139
@@ -1149,23 +1156,23 @@ defmodule DateTime do
11491156
11501157
### Examples
11511158
1152-
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CEST",
1153-
...> hour: 23, minute: 0, second: 7, microsecond: 0,
1154-
...> utc_offset: 3600, std_offset: 3600, time_zone: "Europe/Warsaw"}
1159+
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
1160+
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
1161+
...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
11551162
iex> DateTime.to_iso8601(dt)
1156-
"2000-02-29T23:00:07+02:00"
1163+
"2000-02-29T23:00:07+01:00"
11571164
11581165
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "UTC",
1159-
...> hour: 23, minute: 0, second: 7, microsecond: 0,
1166+
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
11601167
...> utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}
11611168
iex> DateTime.to_iso8601(dt)
11621169
"2000-02-29T23:00:07Z"
11631170
1164-
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "BRM",
1165-
...> hour: 23, minute: 0, second: 7, microsecond: 0,
1166-
...> utc_offset: -12600, std_offset: 3600, time_zone: "Brazil/Manaus"}
1171+
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
1172+
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
1173+
...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
11671174
iex> DateTime.to_iso8601(dt)
1168-
"2000-02-29T23:00:07-02:30"
1175+
"2000-02-29T23:00:07-04:00"
11691176
"""
11701177
@spec to_iso8601(DateTime.t) :: String.t
11711178
def to_iso8601(%DateTime{calendar: Calendar.ISO} = dt) do
@@ -1177,23 +1184,23 @@ defmodule DateTime do
11771184
11781185
### Examples
11791186
1180-
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CEST",
1187+
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "CET",
11811188
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
1182-
...> utc_offset: 3600, std_offset: 3600, time_zone: "Europe/Warsaw"}
1189+
...> utc_offset: 3600, std_offset: 0, time_zone: "Europe/Warsaw"}
11831190
iex> DateTime.to_string(dt)
1184-
"2000-02-29 23:00:07+02:00 CEST Europe/Warsaw"
1191+
"2000-02-29 23:00:07+01:00 CET Europe/Warsaw"
11851192
11861193
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "UTC",
11871194
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
11881195
...> utc_offset: 0, std_offset: 0, time_zone: "Etc/UTC"}
11891196
iex> DateTime.to_string(dt)
11901197
"2000-02-29 23:00:07Z"
11911198
1192-
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "BRM",
1199+
iex> dt = %DateTime{year: 2000, month: 2, day: 29, zone_abbr: "AMT",
11931200
...> hour: 23, minute: 0, second: 7, microsecond: {0, 0},
1194-
...> utc_offset: -12600, std_offset: 3600, time_zone: "Brazil/Manaus"}
1201+
...> utc_offset: -14400, std_offset: 0, time_zone: "America/Manaus"}
11951202
iex> DateTime.to_string(dt)
1196-
"2000-02-29 23:00:07-02:30 BRM Brazil/Manaus"
1203+
"2000-02-29 23:00:07-04:00 AMT America/Manaus"
11971204
"""
11981205
@spec to_string(DateTime.t) :: String.t
11991206
def to_string(%DateTime{calendar: calendar} = dt) do

0 commit comments

Comments
 (0)