Reputation: 2608
I am trying to convert UTC DateTime to some timezones. I am wondering what is the correct way of converting a timezone from UTC to the desired timezone.
for example.
This timezone is + 10 hours than UTC.
I have a list of dates.
such as
Now, this each day have a few hours in it. when you convert a single day from UTC to "Australia/Brisbane"
. like this
iex(6)> Calendar.DateTime.from_erl!({{2020, 6, 7}, {0, 0, 0}}, "Etc/UTC") |> Calendar.DateTime.shift_zone!("Australia/Brisbane")
#DateTime<2020-06-07 10:00:00+10:00 AEST Australia/Brisbane>
iex(7)>
this is mostly right and what this method supposed to do but there are some issues with it.
A day in UTC timezone when reaches 14th hour, such
iex(7)> Calendar.DateTime.from_erl!({{2020, 6, 7}, {14, 0, 0}}, "Etc/UTC") |> Calendar.DateTime.shift_zone!("Australia/Brisbane")
#DateTime<2020-06-08 00:00:00+10:00 AEST Australia/Brisbane>
iex(8)>
in Australia/Brisbane
its not 7th of June any more but it will become 8th June.
I am trying to populate a calendar through this in which.
the day 14 has 2 hours such as 22 and 23 which in UTC are 14th of June but when they shift to Australia/Brisbane
.
when I want to show in a monthly calendar, which day is available. with this
iex(6)> Calendar.DateTime.from_erl!({{2020, 6, 7}, {0, 0, 0}}, "Etc/UTC") |> Calendar.DateTime.shift_zone!("Australia/Brisbane")
#DateTime<2020-06-07 10:00:00+10:00 AEST Australia/Brisbane>
iex(7)>
this is right but as it has only 22 and 23 hours which are don't come in 14 of June but in timezone Australia/Brisbane
they will be in next day.
my question is that what is the right of converting a UTC day to another timezone where it will switch the full day at some point, as it 10 +.. same as for where it's 10 -...
In the case of +ve, it goes to the next day and in case of -ve it goes to the previous day.
How can we convert a UTC day to in another timezone where it also covers the day shift or there is any better way of dealing it?
Upvotes: 2
Views: 5616
Reputation: 1056
Using Timex
e.g.
"US/Pacific"
|> Timex.now()
|> Timex.to_datetime()
Upvotes: 0
Reputation: 9638
Timex is a helpful library for these types of things.
Here you can see a simple example using the Timex.shift/2
function. This would be a valid approach if you know the UTC offset you're working with:
iex> datetime_utc = DateTime.utc_now()
~U[2020-06-18 14:01:32.094925Z]
iex> Timex.shift(datetime_utc, hours: +10)
~U[2020-06-19 00:01:32.094925Z]
If you instead only know the timezone (and not necessarily the current offset), then you can use the Timex.Timezone.convert/2 function. This would be helpful when you have to deal with shifting offsets (because the hourly offsets change depending on the day, e.g. for daylight savings time).
iex> datetime_utc = DateTime.utc_now()
~U[2020-06-18 14:01:32.094925Z]
iex> Timex.is_valid_timezone?("Australia/Brisbane")
true
iex> timezone = Timex.Timezone.get("Australia/Brisbane", Timex.now())
#<TimezoneInfo(Australia/Brisbane - AEST (+10:00:00))>
iex> Timex.Timezone.convert(datetime_utc, timezone)
#DateTime<2020-06-19 00:01:32.094925+10:00 AEST Australia/Brisbane>
In the above example, the offset (+10) is affected by the Timex.now()
. You can see that the offset changes if you feed that function a different time, e.g. observe how Daylight Savings Time affects a timezone offset when we look at a date in January vs. a date in July:
iex> timezone = Timex.Timezone.get("America/Denver", ~U[2020-01-01 12:00:00.0Z])
#<TimezoneInfo(America/Denver - MST (-07:00:00))>
iex> timezone = Timex.Timezone.get("America/Denver", ~U[2020-07-01 12:00:00.0Z])
#<TimezoneInfo(America/Denver - MDT (-06:00:00))>
Hope that helps!
Upvotes: 2