I use a code of:
import java.time.LocalDateTime
import java.time.ZoneOffset
import java.time.format.DateTimeFormatter
var formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS")
LocalDateTime.now(ZoneOffset.UTC).format(formatter)
LocalDateTime.now().format(formatter)
to generate an event time timestamp in UTC in an Android app.
Example output could be:
2019-09-30T19:19:49.133 # the app (UTC)
2019-09-30T21:19:49.398 # my current time zone
Now when pushing it to a cloud message store (azure event hub), one field with submission time in UTC is added (enqueuedtimeutc, https://learn.microsoft.com/en-us/dotnet/api/microsoft.azure.eventhubs.eventdata.systempropertiescollection.enqueuedtimeutc?view=azure-dotnet)
However when calculating the distance there is an almost 2 hours shift between both timestamps supposedly being delivered in UTC:
distance(s) frequency
7194.0 0.350518
7196.0 0.133110
7195.0 0.084421
7199.0 0.077668
7193.0 0.075642
how can this be explained? I thought that both timestamps are in UTC. And in fact, the example output seems to work fine.
Is the clock on my Android device 2 hours off (also unlikely as smartphones usually sync itself up with a clock).
Why is the time difference not exactly 2hours * 60minuts * 60seconds = 7200 seconds
but lower?
As latency and processing time needs to be added, I would expect this value to be greater.
Maybe it is better to use:
DateTimeFormatter.ISO_INSTANT.format(Instant.now())
But this should not change anything i.e. is exactly (besides the format string) matching my time output.
I thought that both timestamps are in UTC.
Not exactly.
Never call LocalDateTime.now
. I cannot imagine a case where that makes sense. Certainly not in this case.
That class lacks any concept of time zone or offset-from-UTC. So it cannot be used to track a moment. A LocalDateTime
holds only a date and a time-of-day. So if you you capture the current moment of noon on January 23, 2020 in America/Montreal
by using LocalDateTime
, you just threw away the Montreal info. So we are left with only the date and the time-of-day. We no longer know if you meant noon in Tokyo Japan, noon in Tunis, Tunisia, or noon in Los Angeles, CA US — all very different moments several ours apart, and none of them your original intent. We lost your original intent.
You did capture the date and time-of-day as seen in UTC by passing ZoneOffset.UTC
, but using LocalDateTime
adds no value, only distraction or possibly unintended values.
Instant
To capture the current moment in UTC, use Instant
.
Instant instant = Instant.now() ; // Capture the current moment as seen in UTC.
The standard way to represent such a value is using the ISO 8601 formats, ending in either a +00:00
for an offset of zero hours-minutes-seconds from UTC, or its shortcut Z
(pronounced “Zulu”).
String output = Instant.toString() ; // Generate string in standard ISO 8601 format.
2019-09-30T20:04:56.827546Z
You may want to truncate to milliseconds if your data sink cannot handle microseconds.
Instant instant = Instant.now().truncatedTo( ChronoUnit.MILLIS ) ; // Lop off the microseconds, keeping milliseconds.
Parse.
Instant instant = Instant.parse( "2019-09-30T20:04:56.827546Z" ) ;
I cannot help further as I do not use either Android or Azure, and you did not describe enough detail.
Now when pushing it to a cloud message store (azure event hub),
Push what? By what API call? Your link leads to a page in C#, not Java. And that page appears to be a getter not a setter (not sure, I don't read C#).