-
Notifications
You must be signed in to change notification settings - Fork 828
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
More test and fix for issues discovered by #2476 #2488
More test and fix for issues discovered by #2476 #2488
Conversation
This is basically a copy of the other test for |
…zone! I also added timestamp without TZ
In my last commit I copied over the modified test from #2476 to check if it fails. On my local timezone (UTC+2) it passes. |
I was able to break the test in @davecramer 's timezone (I set my computer to US Eastern time). The issue happens when the time zone is converted multiple times. |
Ok now I figured out:
If I revert #2467, there is only one test failure:
The same happens when I revert all changes and go back to Postgresql tag of last Maven release (42.3.2). Only one test fails (the getDate one). It looks like theres something wrong with setting dates already. Now the fix for the whole problem looks like is caused by one change in #2467 and the fix is already mentioned there: It looks like theres a difference between It is still unclear how to fix testGetDate() because it also fails in US Eastern Timezone on the release Tag. |
Further investigations (printing the String values of all transmitted dates) it looks like this is caused by the combination of timezones and BC dates. If I set my local timezone (server and also client) to US Eastern Timezone on Microsoft Windows 10, Postgres 13, all BC Dates by postgres are returned as a string value like this one: Look at specifically the time offset? It is totally off, I would have expected it to be -5 So this looks like a server problem. But also Java seems to have a difference between SimpleTimeZone and M yproposal would be to revert the change getting the cleandar in #2467 and use this code in TimestampUtils as suggested in that issue: private Calendar getCalendar(ZoneOffset offset) {
if (calCache != null && Objects.equals(offset, calCacheZone)) {
return calCache;
}
final String tzid = (offset.getTotalSeconds() == 0) ? "UTC" : "GMT".concat(offset.getId());
final TimeZone syntheticTZ = new SimpleTimeZone(offset.getTotalSeconds() * 1000, tzid);
calCache = new GregorianCalendar(syntheticTZ);
calCacheZone = offset;
return calCache;
} This restores the same behaviour as last Postgresql JDBC driver (as seen on Maven Central). That the test still fails here is then a different thing. What do you think? |
What is completely broken on Postgres 13 seems to be when you set a timestamptz column with a plain BC date as string. It then returns some very strange zone offset (at least on my windows computer). |
…ous pgjdbc version.
I pushed a commit to work around the strange server behaviour with totally whacky timezone offsets returned by Postgres 13 and also 14 (just different) for BC dates. The reason for the whole issue looks like This restores the old behaviour. We should still ask the server people why the timezones BC are returned like that. The other test in this issue also shows that LocalDate works correct with BC dates. |
Hi, So there's still something fishy. Maybe we should comment out the "timestamptz" column in the My fix at least restores original behaviour. |
This job runs on postgres 13, so it looks like same setup like I have. There seems to be a problem. But previous runs have shown that without my fix 2 tests fail. Maybe add assumpion to test to only run testGetDate in Postgres 14+? @davecramer |
I also have the feeling the test fails depending on time of day! |
…mezones like Aperica/New_York it fails while America/Toronto it works. This explains the problems.
OK, I improved the test to make a parameterized on cycling over timezones. Without the SimpleTimeZone fix that was broken since #2467, many tests failed, so this has to do with SimpleTimeZone work better than With the bugxfix applied and restoring the behaviour of pgjdbc 42.3.2 now only 3 timezones fail:
As you see "America/Toronto" does not fail (this is why @davecramer does not see an issue on What is funny in Niobe the test also fails in 1950 :-) So to conclude: There is something wrong with the server side (Postgres 13 and possibly also 14, @davecramer can you test this if you get same output?). The issue comes from the following fact: If you insert a string-formatted To fix this, I have the feeling we should fix Postgres client side string date parsing to not parse the whole timestamp including time and timezone when you only want to get a date out of it. It should stop parsing after the day of month. Or we should set all fields to zero after parsing and before passing it to Calendar API. |
Hi,
I also limited the GMT zones (which are unproblematic) to not have tooooooo many test executions. As noted before all is symmetric only the problems around some "local timezones" in combination with passing the date as string to server and later reading it. The problem here is that few timezones have bugs (wich also depends on server version). For this I added an assume to the test. We may change the assume to allow all local timezones except the 3 mentioned above, but I don't know which other timezone bugs are there in other server versions than 13 and 14.. @davecramer what do you think. We can try to fix the issues or report them to the Postgres people where the symmetry between input/output types does not seem to be give. |
…s did not exist at that time), so removing them. Instead use a more common timezone
I changed away from the test time zones Azores and Niue, because those are special: we have extra tests for them. Those break with some dates we have:
We already have quite good tests for time zone conversions, but this one uses paraeters so it tests many more combinations. But this testing has more problems, because daylight saving is unpredictable. This is my personal problem with the legacy datetime types: they allow to do shit nobody would or should ever do! And this brings those non-symmetric cases. |
I am done with that now. Legacy time types are a never-ending story. Plesae don't touch them! Sorry for doing this in my cleanup #2467. 😱😱😱 |
FYI, with java.time we no longer allow to do bad conversions like converting between tz and non-tz types. What's also bad: the server sometimes adds a time zone, too. |
It finally passed all tests! Time to go to bed. |
TODO: Use this also in TimestampUtils
As mentioned in other issue, I rewrote the |
calCache = new GregorianCalendar(TimeZone.getTimeZone(offset)); | ||
// normally we would use: | ||
// calCache = new GregorianCalendar(TimeZone.getTimeZone(offset)); | ||
// But this seems to cause issues for some crazy offsets as returned by server for BC dates! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this is a postgres specific thing java does the same
jshell> java.time.ZoneId.of("America/Toronto").
...> getRules().
...> nextTransition(java.time.Instant.parse("0101-01-01T00:00:00Z"))
$1 ==> Transition[Gap at 1895-01-01T00:00-05:17:32 to -05:00]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is more that the conversion from ZoneOffset to Timezone using Timezone.get(ZoneOffset) is somehow broken. That's why I want to open a bug report at JDK. Not sure how this comes together. I will do some detailed analysis. At least this fixes the problem, although it is not really what the new Java API suggests. This code just restores the old behaviour. The comment was added that there's something fishiy and not somebody else tries to "simplify" it.
It is still strange why different Postgres versions fail differently.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
05:17:32
is the geographic timezone based on latitude/longitude. Interestingly not all timezones have this rule in 1895.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The problem is more that the conversion from ZoneOffset to Timezone using Timezone.get(ZoneOffset) is somehow broken.
Just guessing from my observations: To me it looks like Timezone.get() with those offsets down to second return the default Timezone! It should better throw exception when it cannot parse the ZoneOffset.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I opened a JDK bug report about converting a ZoneOffset to TimeZone, which is buggy for offsets with seconds: https://bugs.openjdk.java.net/browse/JDK-8285844
We should maybe add a link to this issue here! @davecramer can you add the above issue to the comment above? Or do I need to open a bug report.
e031510
to
5f301fd
Compare
Thanks @davecramer |
The thanks goes to you for all the work you did on this. Really appreciate it! |
I opened a JDK bug report about converting a ZoneOffset to TimeZone, which is buggy for offsets with seconds: https://bugs.openjdk.java.net/browse/JDK-8285844 |
This is a PR related to issues found in #2476, maybe caused by #2464 or #2467