Junaid Farooq
Junaid Farooq

Reputation: 2608

what is the correct way of shifting the timezone elixir

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.

  1. 1 to n June. 2020 in UTC
  2. 1 to n June. 2020 in "Australia/Brisbane"

This timezone is + 10 hours than UTC.

I have a list of dates.

such as

DAYS

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.

enter image description here

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

Answers (2)

Zubair Nabi
Zubair Nabi

Reputation: 1056

Using Timex

e.g.

 "US/Pacific"
 |> Timex.now()
 |> Timex.to_datetime()

Upvotes: 0

Everett
Everett

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

Related Questions