fix(isthmus): convert pre-epoch temporal literals instead of throwing - #1127
fix(isthmus): convert pre-epoch temporal literals instead of throwing#1127alexandrefimov wants to merge 2 commits into
Conversation
|
Self-review turned up one thing in my own change, fixed in 0f6168d. Flooring the split means a negative value no longer reaches Two other checks came back clean: both One thing worth knowing for whoever reads the test: precision 9 is unreachable through this path even though the switch accepts it — |
0f6168d to
12bcfed
Compare
nielspardon
left a comment
There was a problem hiding this comment.
The floorDiv/floorMod split is the right fix, and sharing it between the two methods is a real improvement.
This overlaps #1121 — both rewrite getTimestampString and createTimeString with the same split, so whichever lands second will conflict. I'd take this one first and let #1121's generalization sit on top; no need to act on the {0,3,6,9} Javadoc here, since #1121 replaces that switch outright.
One for the description, which becomes the squash-merge commit message: "both failure messages are unchanged" is no longer true — the second commit adds a third, and a rejection path precision_time didn't have.
getTimestampString and createTimeString split a value into whole seconds and a nanosecond remainder with truncating division. Before the epoch the value is negative, so truncation leaves a negative remainder, and both TimestampString and TimeString reject that with a bare IllegalArgumentException: a precision_timestamp of -500 at precision 3, which is 1969-12-31 23:59:59.5, did not convert at all. Split with floorDiv/floorMod so the remainder is never negative, and share the split between the two methods rather than repeating it once per supported precision. The set of supported precisions and both failure messages are unchanged.
Found reviewing the change above. A precision_time is a time of day, so a value below zero or a day or more is not one. Neither is reported as such today: a negative value reaches TimeString.fromMillisOfDay and comes back as a corrupt time string (Invalid time format: [00:00:0/]), and a value of a day or more is either Guava's "Hour out of range: [24]" from inside TimeString or, once the millisecond count overflows an int, a silently wrong time - 4346734 seconds converts to 14:22:46. A range check names the value instead, and makes the narrowing to int provably safe.
12bcfed to
3ff105d
Compare
|
Rebased onto main and reworked per the review: the guard is a range check now, the test covers both ends of the domain with the boundary second either side, and the description no longer claims the failure messages are unchanged. Taking this one first, with #1121 to follow on top. Unrelated to this PR, found while checking the branch: |
getTimestampStringandcreateTimeStringsplit a temporal value into whole seconds and a nanosecond remainder, once per supported precision, with truncating division:Before the epoch the value is negative and truncation rounds towards zero, so the remainder comes out negative — and
TimestampString.withNanosrejects that. Aprecision_timestampof-500at precision 3, which is1969-12-31 23:59:59.5, did not convert at all; it threw anIllegalArgumentExceptioncarrying no message.Split with
floorDiv/floorModinstead, so the remainder is never negative, and share the split between the two methods rather than repeating it four times each. The set of supported precisions (0, 3, 6, 9) is unchanged.The second commit adds a rejection path
precision_timedid not have: it is a time of day, so a value below zero or a day or more is reported by value. Both ends read worse before — a negative value came back fromTimeString.fromMillisOfDayas a corrupt time string, and a large one as either Guava'sHour out of range: [24]or, once the millisecond count overflows an int, a silently wrong time (4346734 seconds converted to 14:22:46). The bound is our reading of what aprecision_timeis;algebra.protodeclares the field a signedint64with no stated range.The new tests fail on
main— the pre-epoch one with exactly the reported exception, the range one because nothing is thrown at all.Closes #1126.