-
Notifications
You must be signed in to change notification settings - Fork 408
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
Timestamps in seconds or milliseconds ? #1304
Comments
Lot of Good questions ! and you probably find something which smell not so good ... Actually, SenML is no the only one to support timestamped values, JSON content format (application/vnd.oma.lwm2m+json, 11543) support it too (ok this is also a kind of SenML format but not the official one). I quickly look at the LWM2M specification and I understand that timestamp for JSON is also in seconds. So conclusion is the same because all current format are using seconds (and not milliseconds).
I was thinking this too but reading more deeper about SenML RFC and LWM2M spec about JSON format, I finally understand that time are in seconds but could be float number, and so you could have milli or ever micro seconds (or even maybe more)...
Reading most of the encoder / decoder I understand current code are using /expecting seconds. But what should it be is less clear... especially with what I found above. ☝️ So my opinion about this : Mid/long term :
What do you think ? |
I prepared very small commit regardings the timestamps callculation in ManualDataSender: JaroslawLegierski@5eb946b. After this modification timestamps in ManualDataSender should be consistent with the others timestamps in Leshan code. When it comes to more precise timestamps, they are needed in many IoT use cases - and very important from the point of view of device vendors, of course we have to define the requirements in the first step. |
Do you plan to provide a PR ?
Yep so let discuss about that. I think we can use this issue. Generally timestamp are store in long. But do we need seconds, milli, micro or nano seconds ?
To get this result I used : System.out.println(new Date(Long.MAX_VALUE).toGMTString());
System.out.println(new Date(Long.MAX_VALUE/ 1_000).toGMTString());
System.out.println(new Date(Long.MAX_VALUE / 1_000_000).toGMTString()); (Please, double check if I'm not wrong) So if we target milli or micro it's largely OK. What do you think ? |
Hi, I'm going to chime in and speak on behalf of myself and @JaroslawLegierski 🙂. We decided to use Double as the data type for timestamps and in terms of time units it would be seconds with millisecond precision. There are several reasons behind that decision:
In summary, this is roughly how measuring current time would look like: long timestampMillis = System.currentTimeMillis();
double timestampSeconds = timestampMillis / 1000d; Does this sound OK to you? |
Using Floating point number (float or double) comes generally with headhache precision issue and generally I prefer to avoid to use it unless I have no choice. |
Here some code which can be used to play with Floating point number and see the kind of precision issue you can face.: public static void main(String[] args) {
// inputs
// ------
// Initials date
long timeInNano = (new GregorianCalendar(2022, 9, 7, 10, 6, 31).getTimeInMillis() + 951) * 1_000_000l;
// increment in
long incrementInNano = 1l;
int difference = 0;
for (int i = 0; i < 1000; i++) {
double timeInSeconds = timeInNano / 1_000_000_000d;
BigDecimal nano = new BigDecimal(timeInNano);
BigDecimal sec = new BigDecimal(timeInSeconds);
BigDecimal secFromString = new BigDecimal(Double.toString(timeInSeconds));
BigDecimal secFromNano = nano.divide(new BigDecimal(1_000_000_000));
System.out.println("=================================================");
System.out.println("Time in nano (long) : " + timeInNano);
System.out.println("Time in sec (double) (nano x 1_000_000d) : " + timeInSeconds);
System.out.println("Time in nano (Big decimal from long) : " + nano);
System.out.println("Time in sec (Big decimal) from nano BigDecimal: " + secFromNano);
System.out.println("Time in sec (Big decimal) from sec (double) : " + sec);
System.out.println("Time in sec (Big decimal) from sec (string) : " + secFromString);
if (sec.compareTo(secFromNano) != 0) {
difference++;
}
timeInNano = timeInNano + incrementInNano;
}
System.out.println("=================================================");
System.out.println("Number of difference :" + difference);
} |
Yes of course PR created: #1306 |
@sbernard31 Additionally, SenML specification tells us which fields should use which datatypes, specifically that Base Time and Time should use Double. There are several examples of this across the document, e.g. section 5.1.6 provides a sample payload with the Base Time field as a floating point number (1.320078429e+09). Ultimately, using floating point numbers would allow us to:
|
I'm not sure to get why you could face this kind of limitation in java but anyway, this is a protocol communication one peer could use Java, the other peer could use something else.
Maybe it's ok for milliseconds (I'm not even sure) but why milliseconds would the right target ?
Not exactly, this is double for senml+xml, for senml+cbor this could be any cbor number encoding and for senml+json this is a JSON number. A JSON number is a string and so can be any number (no real limitation), so probably a kind of BigDecimal in Java. Anyway, I think you mix up 2 API.
As @JaroslawLegierski said maybe one day we will see another format with more precise timestamp or which use Integer instead of floating point number. To come back to the initial question : how we encode it ?? |
That's a good idea; since according to the specification, timestamp values in SenML records are in seconds, we should convert them to an integer number. I think we should use long in |
Reading your comments, I understand that using milliseconds format for timestamp as integer number seems important to you. But I can understand why ? 🤔 As I said above, eventually I could understand that nano could be an issue as we can encode timestamp "just" up to 2262 (and even that I'm not sure this is a real issue, not sure that Leshan will still be used in 2262 😅 ...) But for mircro, I don't see any drawback so why using milliseconds and so dealing with an abstraction format (TimestampedLwM2mNode) less precise that transport format (senml)? |
(Note that maybe |
After some internal discussion, I think we can settle for |
I changed the SenML Record API and the new class for timestamped nodes ( Everything's working fine except for the fact that we lose two last decimal places when sending a timestamp with nanosecond precision using JSON. It has to do with the fact that Jackson saves this value to |
Strange, I pretty sure that jackson should be able to support BigDecimal 🤔 |
You can indeed encode a |
By the way, do you know roughly when M9 could come out, and will it include these changes? And also more broadly, when a stable release for Leshan v2.x could potentially be released? |
My plan does not change since I explain it at : #1222 I'm still focus on transport layer #1025. So I don't plan to release M9 soon. But if an M9 with just bug fixes and/or small feature is needed, we can consider it on demand. If you need lot of changes in next month maybe you should consider to use an internal fork waiting #1025 is ready. Sorry for the annoyance but the situation is pretty exceptional.
Clearly I'm not able to do that, but my bet this will not happen soon. |
About the Jackson / BigDecimal issue, I think this can be done in a second time. I mean most important is :
So we can start with a PR limited to this. |
I finished refactoring |
I just take a look quickly and I think there is no major point to discuss, so better to discuss it in a PR. |
Oups we just detect with #1313 that
So the question is :
I didn't like so much the idea to add a new dependency just for that, so at first sight I would not pick 3. 🤔 Note: that if we go with |
@sbernard31 By the way, you said that
so I was wondering if it would be possible to have a smaller M9 after integrating #1313. Also, we'd like to contribute to refactoring of the transport layer, since you said
In case you want our help, you can elaborate on what exactly we could do. |
Regarding the API conflict:
Ultimately I have no knowledge about how many devices could be using the old API (it's from 9 years ago), but if it's not a big deal, please consider upgrading it. Otherwise we'd probably have to fall back to using |
I think we will probably go in that way. (I try to get some feedback internally and it also goes in that direction)
Yep I think this is possible.
About question about what to work on, do not hesitate to use #1049. |
I take time to be able to release a M9 soon. |
Here I try to clarify my mind about timestamped value in LWM2M. AFAIK, there is nothing in LWM2M which define the precision of the timestamp. Currently there is 3 content format which allow to support timestamped value :
For Old JSON and SenML JSON, have timestamp value (
For SenML CBOR, this is pretty much the same thing,
So nothing forbid to use bigger precision than a I guess in an ideal world, we should :
I'm not saying we need to implement this now but try to get the big picture. |
Sure, if that means better interoperability, I'm all for it. But right now, I'd like to focus on getting the current changes on master and releasing M9. I should be done with adjustments after your review by the end of the day, by the way. |
Yes of course. Thank You very much. |
Thanks both of you to moved this forward 🙏 ! |
We got following feedback in timestamps topic which needs some clarifications. Timestamps in Leshan client in ManualDataSender class https://github.com/eclipse/leshan/blob/master/leshan-client-core/src/main/java/org/eclipse/leshan/client/send/ManualDataSender.java in collectData are curently calculated in miliseconds (ManualDataSender line 47). Maybe they are supposed to be calculated in seconds (as in SenML) ? The problem is wider, should be the timestamps in TimestampedLwM2mNode and TimestampedLwM2mNodes in milliseconds or in seconds only?
Currently only SenML manage timestamped values (in seconds) byt maybe in a future data format they could be in ms. What is your opinion on this topic ?
The text was updated successfully, but these errors were encountered: