-
Notifications
You must be signed in to change notification settings - Fork 14.3k
KAFKA-18585 Fix fail test ValuesTest#shouldConvertDateValues #18611
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
Conversation
Hello @AndrewJSchofield, if you have free cycle, PTAL |
java.util.Date d3 = Values.convertToDate(Date.SCHEMA, LocalDate.ofEpochDay(days).format(DateTimeFormatter.ISO_LOCAL_DATE)); | ||
assertEquals(currentDate, d3); |
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 must be missing something here so please help me understand the following:
Java's util.Date is timezone agnostic (it's always epochs in UTC timezone) until you want to print it (where you can format it). Hence, the currentDate here should already be in UTC timezone. And the actual value from LocalDate.ofEpochDay(days).format(DateTimeFormatter.ISO_LOCAL_DATE)
should also be in UTC. So, where is the disconnect here?
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.
Yes, I'm not sure either. But I can believe it's possible to write a test that is timezone-dependent.
Digging into this further, I would say that the behaviour for some of these tests with respect to timezones is incorrect, or at least unwise. I am not convinced by this patch, but I will dig into it further and give a more concrete answer shortly. |
java.util.Date d3 = Values.convertToDate(Date.SCHEMA, LocalDate.ofEpochDay(days).format(DateTimeFormatter.ISO_LOCAL_DATE)); | ||
assertEquals(currentDate, d3); |
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.
@divijvaidya is correct that java.util.Date
is timezone-agnostic. However, the LocalDate
here is timezone-ignorant and the timezone offset is not accounted for. The methods available for manipulating dates and times with timezones are a bit limited, and I think that it's best to stop using LocalDate.ofEpochDay(long)
and moving to LocalDateTime.ofInstant(Instant, ZoneId)
.
I suggest replacing the first line of the method with:
LocalDateTime localTime = LocalDateTime.now();
LocalDateTime localTimeTruncated = localTime.truncatedTo(ChronoUnit.DAYS);
ZoneOffset zoneOffset = ZoneId.systemDefault().getRules().getOffset(localTime);
java.util.Date current = new java.util.Date(localTime.toEpochSecond(zoneOffset) * 1000);
And then the check becomes:
// ISO8601 strings - accept a string matching pattern "yyyy-MM-dd"
java.util.Date d3 = Values.convertToDate(Date.SCHEMA, LocalDate.ofEpochDay(days).format(DateTimeFormatter.ISO_LOCAL_DATE));
LocalDateTime date3 = LocalDateTime.ofInstant(Instant.ofEpochMilli(d3.getTime()), ZoneId.systemDefault());
assertEquals(localTimeTruncated, date3);
I tried this with various timezones locally and it seems to work properly. Essentially, the time information is discarded in a way that a person in the timezone would expect looking at a clock.
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.
We can observe that when java.util.Date
performs equals comparison, it takes timezone into account. Therefore, the equals comparison will yield different results under different timezones. In my case, being in UTC+8, it results in an 8-hour difference.
https://github.com/openjdk/jdk/blob/master/src/java.base/share/classes/java/util/Date.java#L1210
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.
@m1a2st Are you happy that this works now?
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.
Sure, using LocalDateTime
makes sense to me.
…18611) Reviewers: Divij Vaidya <[email protected]>, Andrew Schofield <[email protected]>
…18611) Reviewers: Divij Vaidya <[email protected]>, Andrew Schofield <[email protected]>
…18611) Reviewers: Divij Vaidya <[email protected]>, Andrew Schofield <[email protected]>
Jira: https://issues.apache.org/jira/browse/KAFKA-18585
The test scenario involves inputting dates in ISO8601 format
yyyy-MM-dd
. At this point, the time information is already lost. Then in theValues#convertToDate
method, the date conversion is performed using string manipulation, without any timezone information being provided. Therefore, it's expected and normal behavior that the time gets converted to 00:00:00.The solution is to explicitly convert Java Date objects, which internally store UTC timestamps, to UTC+0 timezone
before:


after:
Committer Checklist (excluded from commit message)