Subject Re: [Firebird-Java] Timestamp Linux
Author Mark Rotteveel
On 25-3-2018 07:56, hugo.larson@... [Firebird-Java] wrote:

> select and inserting CURRENT_TIMESTAMP and CURRENT_TIMESTAMP(3) gives ms.
> Also inserting like this stores ms in Linux
> insert into debit (CUSTOMER_ID, USER_ID, TOTSELLPRICE, REG_ID,
> RECEIPT_ID, timedebit) values (1,1,'100', 1, 1, '2018-03-25 12:02:30.784')
>
> I should have explained better. The time is set with
> Calendar.getTimeInMillis().
> Another observation, I wrote before that ms could be lost in
> serialization but this is not true because when I send data to remote
> windows server (Java 7. FB 2.5.3) the ms is there.
>
> Here is the code:
> public final void setTimestamp(long val, int nanos) {
>     if (setType != TIMESTAMP && setType != 0)
>       typeProblem(setType, TIMESTAMP, false);
>     type = Variant.TIMESTAMP;
>     if (timestampVal == null)
>       timestampVal = new Timestamp(System.currentTimeMillis());
>   &nb sp; long secs = val/TimeConst.MILLIS_PER_SECOND;
>     nanos += (int)((val%TimeConst.MILLIS_PER_SECOND) *
> (TimeConst.NANOS_PER_SECOND/TimeConst.MILLIS_PER_SECOND));
>     while (nanos < 0) {
>       nanos += TimeConst.NANOS_PER_SECOND;
>       --secs;
>     }
>     while (nanos > TimeConst.NANOS_PER_SECOND) {
>       nanos -= TimeConst.NANOS_PER_SECOND;
>       ++secs;
>     }
>     timestampVal.setTime(secs*TimeConst.MILLIS_PER_SECOND);
>     timestampVal.setNanos(nanos);
>   }

I assume MILLIS_PER_SECOND = 1_000 and NANOS_PER_SECOND = 1_000_000_000

That calculation is rather complicated, and it has an edge case that
could result in a `IllegalArgumentException` if the resulting nanos ==
TimeConst.NANOS_PER_SECOND (although chance of that is probably not
high), change the condition to nanos >= TimeConst.NANOS_PER_SECOND.

If the input for `nanos` contains more than +/- 1.15 * NANOS_PER_SECOND,
this could overflow if the remainder milliseconds of val are close to
1000, but again this would not result in truncation.

The only immediate chance I see for truncation in above code would be if
the input nanos is exactly opposite of the number of remainder
milliseconds from val, so they cancel each other out.

I have also reviewed the code in Jaybird, and I don't see an immediate
problem there. It would be very helpful to have reproducible testcase.

Exactly which version of Java are you using on Linux (full version
string from java -version if possible), and which version of Jaybird
(full version)?

Mark
--
Mark Rotteveel