How you handle timezones

Hi everyone,

I am going to discuss a timezone problem we are having at the moment. We are working as a CCTV camera company, and we are saving jpegs for a camera, on a filesystem in the cloud.

Cameras are in different timezones but all the images are being saved in the cloud with UTC timezone. Here is an example.

this is how 15 of March looks like in filesystem and in UTC

now If I want to display it in

on calendar

now as hour are correctly shown because we are asking hours for
from start of the day |> Shifted to timezone
to start of the day |> Shifted to timezone

this we way get all the hours, merge them and unique them and display.

but as in its -5 hours timezone.

the 0th hour in the calendar is not 0th,

when you go back -5 hours while converting the 0 to 23 hours?

as those, all hours were in 15th day, after conversion. first 5 hours will fall in the 16th of May

now on the calendar as we first show days. and then hours. in such cases those conversion hours cannot be displayed. can you suggest something for this?

The list of hours is always from 0 to 23? Or there might be gaps? Maybe not the best example…

You cannot take the date in UTC and then the time in the local time zone. You have to computer the whole datetimes into the local time zone.

Maybe that’s why analytics softwares asking us for local time zone when creating an application. For recording the events, to NOT deal with these kind of problems.

Time zones can be confusing. I have an example in my TimeZoneInfo package to play around with time zones. In this example, you can set the current time (UTC). The sample also contains a clock with a time zone you can set. With this example, you can do something like this.

iex> FakeUtcDateTime.put(~U[2020-03-15 00:00:00Z])
:ok
iex> Clock.put_time_zone("Europe/London")
:okiex> FakeUtcDateTime.put(~U[2020-03-15 00:00:00Z])
:ok
iex> Clock.put_time_zone("Europe/London")
:ok
iex> lon = [{Clock.now(), Clock.now() |> Date }]
Date        DateTime
iex> lon = [{Clock.now(), Clock.now() |> DateTime.shift_zone!("Etc/UTC")}]
[
  {#DateTime<2020-03-15 00:01:30+00:00 GMT Europe/London>,
   ~U[2020-03-15 00:01:30Z]}
]
iex> Clock.put_time_zone("America/Winnipeg")
:ok
iex> win = [{Clock.now(), Clock.now() |> DateTime.shift_zone!("Etc/UTC")}]
[
  {#DateTime<2020-03-14 19:02:03-05:00 CDT America/Winnipeg>,
   ~U[2020-03-15 00:02:03Z]}
]
iex> FakeUtcDateTime.put(~U[2020-03-15 12:00:00Z])
:ok
iex> Clock.put_time_zone("Europe/London")
:ok
iex> lon = [{Clock.now(), Clock.now() |> DateTime.shift_zone!("Etc/UTC")}|lon]
[
  {#DateTime<2020-03-15 12:00:29+00:00 GMT Europe/London>,
   ~U[2020-03-15 12:00:29Z]},
  {#DateTime<2020-03-15 00:01:30+00:00 GMT Europe/London>,
   ~U[2020-03-15 00:01:30Z]}
]
iex> Clock.put_time_zone("America/Winnipeg")
:ok
iex> win = [{Clock.now(), Clock.now() |> DateTime.shift_zone!("Etc/UTC")}|win]
[
  {#DateTime<2020-03-15 07:00:40-05:00 CDT America/Winnipeg>,
   ~U[2020-03-15 12:00:40Z]},
  {#DateTime<2020-03-14 19:02:03-05:00 CDT America/Winnipeg>,
   ~U[2020-03-15 00:02:03Z]}
]
iex> FakeUtcDateTime.put(~U[2020-03-15 23:00:00Z])
:ok
iex> Clock.put_time_zone("Europe/London")
:ok
iex> lon = [{Clock.now(), Clock.now() |> DateTime.shift_zone!("Etc/UTC")}|lon]
[
  {#DateTime<2020-03-15 23:00:13+00:00 GMT Europe/London>,
   ~U[2020-03-15 23:00:13Z]},
  {#DateTime<2020-03-15 12:00:29+00:00 GMT Europe/London>,
   ~U[2020-03-15 12:00:29Z]},
  {#DateTime<2020-03-15 00:01:30+00:00 GMT Europe/London>,
   ~U[2020-03-15 00:01:30Z]}
]
iex> Clock.put_time_zone("America/Winnipeg")
:ok
iex> win = [{Clock.now(), Clock.now() |> DateTime.shift_zone!("Etc/UTC")}|win]
[
  {#DateTime<2020-03-15 18:00:32-05:00 CDT America/Winnipeg>,
   ~U[2020-03-15 23:00:32Z]},
  {#DateTime<2020-03-15 07:00:40-05:00 CDT America/Winnipeg>,
   ~U[2020-03-15 12:00:40Z]},
  {#DateTime<2020-03-14 19:02:03-05:00 CDT America/Winnipeg>,
   ~U[2020-03-15 00:02:03Z]}
]
iex> Enum.zip(lon, win)
[
  {{#DateTime<2020-03-15 23:00:13+00:00 GMT Europe/London>,
    ~U[2020-03-15 23:00:13Z]},
   {#DateTime<2020-03-15 18:00:32-05:00 CDT America/Winnipeg>,
    ~U[2020-03-15 23:00:32Z]}},
  {{#DateTime<2020-03-15 12:00:29+00:00 GMT Europe/London>,
    ~U[2020-03-15 12:00:29Z]},
   {#DateTime<2020-03-15 07:00:40-05:00 CDT America/Winnipeg>,
    ~U[2020-03-15 12:00:40Z]}},
  {{#DateTime<2020-03-15 00:01:30+00:00 GMT Europe/London>,
    ~U[2020-03-15 00:01:30Z]},
   {#DateTime<2020-03-14 19:02:03-05:00 CDT America/Winnipeg>,
    ~U[2020-03-15 00:02:03Z]}}
]

I hope that is not confusing more.

To see if I understood your problem, you’re already retrieving the correct dates right, as in, in this case, you’re returning the results from day 14th 19h, to day 15th 19h right?

And your problem is that when showing them the dates will be shifted? So instead of the first being 15th:00:00 utc, it will be 14th:19:00 utc ?

What is the format of the response you send and how are you organising the view/display of the values on the frontend, do your server-side render the response or it’s for a frontend to display?