Closed silva96 closed 3 years ago
More insights
End of day of 4th of april 2020 in America/Santiago fails, gives 22:00 -03 instead of 23.59.59 -03 Beginning of day of 5th of april 2020 in America/Santiago is ok in timex though.
left_date = Timex.to_datetime({{2020,4,4}, {23,59,0}}, "America/Santiago") # this is day at 23:59:59.999 -03:00, time goes back to 23:00:00 -04:00
next_day = Timex.to_datetime({{2020,4,5}, {5,0,0}}, "America/Santiago") #arbitrary non-conflictive datetime in conflictive day
Timex.end_of_day(left_date)
#DateTime<2020-04-04 22:00:00-03:00 -03 America/Santiago>
Timex.beginning_of_day(next_day)
#DateTime<2020-04-05 00:00:00-04:00 -04 America/Santiago>
In ruby/rails it works.
left_date = "2020-04-04 23:59:00"
next_day = "2020-04-05 05:00:00"
ActiveSupport::TimeZone.new('America/Santiago').parse(left_date).end_of_day
=> Sat, 04 Apr 2020 23:59:59 -03 -03:00
# correct result, different from timex
ActiveSupport::TimeZone.new('America/Santiago').parse(next_day).beginning_of_day
=> Sun, 05 Apr 2020 00:00:00 -04 -04:00
# same result as in timex
For april 4 at 22.59 -03, times in timex and in apple clock match
at 23.59 -03, times in timex and in apple clock match too, because nothing happened yet (regarding time offset change)
after a minute, clocks should go backwards to 23.00 but with offset -04
which apple clock handles correctly but timex doesn't, timex gives 00:00 -04
I have just run into this issue as well, for the duration of exactly one, the Pacific/Easter
timezone when called with Timex.Timezone.get/1
was broken.
you can replicate it with the following:
iex(24)> Timex.Timezone.get("Pacific/Easter", {{2019, 9, 7}, {22, 10, 0}})
{:error, {:could_not_resolve_timezone, "Pacific/Easter", 63735113400, :wall}}
we had an error for exactly one hour, which led me down this rabbit hole, and as it has happened with at least two time zones at different times, i'm sure there's an underlying bug.
I am experiencing a similar issue.
any datetime between 02:00:00
to 02:59:59
will throw the same error.
Timex.parse!("2019-10-06T02:00:00.765Z", "{ISO:Extended:Z}") |> Timex.local
{:error, {:could_not_resolve_timezone, "Australia/Sydney", 63737546400, :wall}}
Update 1: I found if Timezone in OS is set to UTC, it will not cause any error. If Timezone is set to something different, it will cause Timex to throw the error. Tested both on CentOS and Debian
We hit this bug in production today and had a lot of issues for 1 hour. I really hope this gets fixed eventually.
Each year a new victim :D
Just to chime back in on this. There actually isn't a bug. The problem occurs when you try to resolve a time that actually doesn't exist in a specific timezone. I remember digging in deep.
the time doesn't exist because during daylight savings times, different regions skip hours, so the time inside of that hour for that TZ is invalid.
bottom line is: you should confirm that when you resolve a time it returns a struct, rather than an error tuple.
i'd recommend @bitwalker closes this issue
There is a better solution to helping this actually, and I’m finishing up the changes along with a variety of other fixes; should be pushed by EOW
Just to chime back in on this. There actually isn't a bug. The problem occurs when you try to resolve a time that actually doesn't exist in a specific timezone. I remember digging in deep.
the time doesn't exist because during daylight savings times, different regions skip hours, so the time inside of that hour for that TZ is invalid.
bottom line is: you should confirm that when you resolve a time it returns a struct, rather than an error tuple.
i'd recommend @bitwalker closes this issue
In my opinion it is a bug and a serious one too. When I simply want a datetime and all I get during that 1 hour of timezone change, is an error. Even though I catch the error tuple, then what I do with it. There is no way for me to get a timestamp anyway.
Just to chime back in on this. There actually isn't a bug. The problem occurs when you try to resolve a time that actually doesn't exist in a specific timezone. I remember digging in deep.
the time doesn't exist because during daylight savings times, different regions skip hours, so the time inside of that hour for that TZ is invalid.
bottom line is: you should confirm that when you resolve a time it returns a struct, rather than an error tuple.
i'd recommend @bitwalker closes this issue
There is actually a bug. You can check here for instructions on how to reproduce it: https://github.com/bitwalker/timex/issues/625#issuecomment-799680070 That is converting a UTC time to a time in a timezone. This should always work (excluding some edge cases). UTC time refers to an unambiguous point in time. So if I could travel to a particular point in UTC time and then looked at a clock in that timezone I should always see a time (it exists) and I should only see 1 time (it is unambiguous). However, going in the other direction has problems but I'm not complaining about that.
This is fixed in 3.7
@bitwalker thank you so much for the quick turn around here!
Thanks for looking into this @bitwalker. I'm seeing the issue as described in https://github.com/bitwalker/timex/issues/587 with 3.7.1
{:ok, before_dst, _} = DateTime.from_iso8601("2021-03-14T01:00:00Z")
%Timex.TimezoneInfo{} = Timex.timezone("America/New_York", before_dst)
{:ok, at_dst, _} = DateTime.from_iso8601("2021-03-14T02:00:00Z")
{:error, {:could_not_resolve_timezone, "America/New_York", 63782906400, :wall}} = Timex.timezone("America/New_York", at_dst)
Edit: It looks like Timex.Timezone.resolve/3
returns what I expect when given :utc
as the third arg.
iex(1)> {:ok, two_am_utc, _} = DateTime.from_iso8601("2021-03-14T02:00:00Z")
{:ok, ~U[2021-03-14 02:00:00Z], 0}
iex(2)> Timex.Timezone.resolve("America/New_York", Timex.to_gregorian_seconds(two_am_utc), :utc)
#<TimezoneInfo(America/New_York - EST (-05:00:00))>
iex(3)> Timex.Timezone.resolve("America/New_York", Timex.to_gregorian_seconds(two_am_utc), :wall)
{:error, {:could_not_resolve_timezone, "America/New_York", 63782906400, :wall}}
Why does Timex.timezone/2
require the use of the default :wall
instead of :utc
?
@nonrational I’m not sure why you would use timezone/2
vs Timex.to_datetime/2
or Timex.Timezone.convert/2
, both of which are more appropriate for getting a DateTime in a desired timezone. Is there a particular reason you are using that function directly?
Also, can you try with 3.7.2?
I'm using Timex.timezone/2
to look up the full %Timex.TimezoneInfo{}
as of a given UTC datetime for a named timezone (e.g. "America/New_York"
-> %Timex.TimezoneInfo{abbreviation: "EDT"}
).
Will try with 3.7.2!
As of 3.7.2 you are better off calling ‘Timex.Timezone.get/2` with a NaiveDateTime if you want a TimezoneInfo that reflects the wall clock time in a given zone, give that a shot instead.
Timex.Timezone.get/2
works exactly as expected. Thank you!
Hello guys, I've experienced this issue last Sunday when the DST happened in Spain (Using v3.6.1). Today I've just reproduced it doing the following
Timex.Timezone.get("Europe/Madrid", NaiveDateTime.utc_now())
then I got
** (FunctionClauseError) no function clause matching in Timex.Timezone.total_offset/1
The following arguments were given to Timex.Timezone.total_offset/1:
# 1
{:error, {:could_not_resolve_timezone, "Europe/Madrid", 63784117369, :wall}}
Attempted function clauses (showing 1 out of 1):
def total_offset(%Timex.TimezoneInfo{offset_std: std, offset_utc: utc})
(timex) lib/timezone/timezone.ex:447: Timex.Timezone.total_offset/1
Timex.Timezone.get("Europe/Madrid", NaiveDateTime.utc_now())
and I got again the same error:
** (FunctionClauseError) no function clause matching in Timex.Timezone.total_offset/1
The following arguments were given to Timex.Timezone.total_offset/1:
# 1
{:error, {:could_not_resolve_timezone, "Europe/Madrid", 63784117369, :wall}}
Attempted function clauses (showing 1 out of 1):
def total_offset(%Timex.TimezoneInfo{offset_std: std, offset_utc: utc})
(timex) lib/timezone/timezone.ex:447: Timex.Timezone.total_offset/1
has this issue already been fixed? and it's me missing something??
Unfortunately Timex introduced a broken(a serious one) change.
Which is te relation between the given example and the breaking change you are pointing? I', using in the example a NaiveDateTime
that is supposed to be agnostic from timezones. 🤔 So AFAIK there should be no relation. Moreover, this behaviour is just transient and after one hour it backs to the right one.
Unfortunately Timex introduced a broken(a serious one) change.
651
I updated to 3.6.1 hoping the commit (https://github.com/bitwalker/timex/commit/ab03f307fd2204a869183a9d957967bdf2eef8b1) that fixes #514 would solve the issue, but it doesn't.
What I need to do is have the DateTime for the very beginning of the day of the 8th of september in America/Santiago timezone. This day, there is a change from CLT to CLST (summer time, daylight savings ends exactly at 23.59.59.999999 and time goes to 01 am instead of 00 am.)
Having the following example, I would expect to have valid dates in both cases (07-september-2019 and 08-september-2019, but the latter fails with
:could_not_resolve_timezone
In ruby/rails works perfectly fine.
More over, substracting minutes from the beginning of conflicting day gives totally wrong date: