ISO 8601
I am presenting two suggestions. I am not sure which one will best fulfil your goal. Both suggestions involve ISO 8601, the international standard for dates and times.
1. Send date and time in UTC: Since it works to send a point in time that is independent of time zone, I suggest that you do that by sending the date and time in UTC. For example:
2020-03-22T19:04:57.110540Z
This is more human readable than a count of seconds or milliseconds since the epoch, yet perfectly machine readable too. The trailing Z
means UTC.
2. Send just the date in UTC: The problem as I understood it was that the dates didn’t agree because of different time zones. However the client knows its own timezone and can fairly easily find the date in UTC and send it to the server, and then the server will understand.
2020-03-22
Again you may append Z
to make it explicit that the date is in UTC if you prefer. It’s not much used, though occasionally. Again this format is readable by both humans and machines, which is why I’d prefer it over a count of days since the epoch day.
Edit: From the chat:
I want the data for "today" of the client.
And from the question:
The problem is that "today" on the client is one day after (for
example) the server which is UTC.
Then I don’t understand how that is a problem. As far as I can see, you were getting what you say that you want.
I would still recommend sending the date in ISO 8601 rather than a count of days since the epoch.
How to write and read ISO 8601 in Java?
java.time, the modern Java date and time API, has been designed to work excellently with ISO 8601. To write date and time in UTC from a device in an arbitrary time zone:
String dateTimeUtcString = Instant.now().toString();
System.out.println(dateTimeUtcString);
Example output from running just now:
2020-03-22T19:34:48.034Z
In case you were wondering why I presented six decimals on the seconds before and only print three decimals this time: the number of decimals is free within the standard, you may even leave out the decimal part of the seconds completely if you don’t need it. It will all work.
To read this string on the server, parse back into an Instant
:
Instant i = Instant.parse(dateTimeUtcString);
If you wanted just the date, to write the UTC date from the device:
String dateString = LocalDate.now(ZoneOffset.UTC).toString();
System.out.println(dateString);
2020-03-22
Edit: since you want the client’s “today”, you should use ZoneId.systemDefault()
instead of ZoneOffset.UTC
in the call to LocalDate.now()
above.
And to parse it on the server;
LocalDate date = LocalDate.parse(dateString);
If you wanted Z
to indicate UTC, it’s slightly longer:
String dateUtcString = OffsetDateTime.now(ZoneOffset.UTC)
.format(DateTimeFormatter.ISO_OFFSET_DATE);
System.out.println(dateUtcString);
2020-03-22Z
To parse use the same formatter in the server:
LocalDate date = LocalDate.parse(
dateUtcString, DateTimeFormatter.ISO_OFFSET_DATE);
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
- In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in.
- In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
- On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from
org.threeten.bp
with subpackages.
Links