This question already has answers here:
Java Best Practice for Date Manipulation/Storage for Geographically Diverse Users
(2 answers)
What's the difference between Instant and LocalDateTime?
(4 answers)
Should I use Instant or DateTime or LocalDateTime in Java entities?
(3 answers)
Closed 2 days ago.
I am developing a Spring Boot app and there are some date/time fields in some entities. When considering an application will be used by multiple users from all around the world, the date and time fields should be treated properly and I am trying to follow one of the proper approach.
In this scene, what would you suggest to save date and time by users from different time zones. I think the following approaches:
I can save date and time based on UTC+0 and then when someone else retrieve data, I can show them based on their current time zone.
or save date and time based on the local time of the user with that local time zone.
I am really confused with this issue as I have no previous experience. And as far as I see, I can use LocalDateTime of java.time with Java 11+. But if you have another suggestion that is better than java.time, you can share also.
I highly recommend using the ZonedDateTime object which holds information about the date, the time, and the regarding timezone. With the Java Date and Time API introduced with Java 8 it is very easy to convert dates, times, zones, and to calculate with them. To store these objects directly, refer to your database abstraction layer you are using. If needed, you can use the DateTimeFormatter to create String representations easily to view and store.
If you need a more detailed answer, please provide a more detailed question, preferably with example code.
I will go for the first solution and give the client the time based on his/her zone. Keep in mind that the local time zone that you will display will be the time zone of the server which the client has called. To get the real time zone of the client you need to make sure to get it from the client itself. May be this link could help
Related
I am looking for the most simple and cleanest way to fix the timezone for all dates in an Android app. The idea is to have the app running as if the user were in another timezone. Let me clarify what I am looking for:
Let's say the user's phone is set to America/New_York then I would like my app to show all dates (are in UTC) in the Europe/Amsterdam timezone, regardless of the timezone that is set on the phone itself. And if I make a comparison with a new Date() it would be very nice if that new Date() is also in the current time of the Europe/Amsterdam timezone.
After searching the internet for solutions, I started to get the feeling that I will have to update every place in my app where a Date is used and force the use of the target timezone, like the solution of this stackoverflow post: Converting UTC dates to other timezones
Does anybody know how to get this done in a more easy and cleaner way?
The answer for anyone using java.time, the modern Java date and time API.
java.time does not include an option for setting the JVM default time zone. And wisely so. It’s not something you should want to do. By doing it you affect every program running in the same JVM, and also every part of your program and other program in the JVM may set it differently, ruining your intentions.
Avoid the need
In your time operations be explicit about which time zone you want, and you will always know what you get independently of the JVM setting. Example:
System.out.println(ZonedDateTime.now(ZoneId.of("Asia/Dushanbe")));
Example output:
2021-05-09T00:36:25.171213+05:00[Asia/Dushanbe]
System.setProperty
If you have already written a lot of code relying on the default time zone of the JVM, the hack to set it is:
System.setProperty("user.timezone", "Australia/Tasmania");
System.out.println(ZonedDateTime.now());
This just printed:
2021-05-09T05:38:03.568350+10:00[Australia/Tasmania]
It’s not very robust, though, for the reasons mentioned in the beginning.
If you want validation of the string you are passing, use:
System.setProperty("user.timezone", ZoneId.of("Australia/Tasmania").getId());
Disclaimer
It seems from your question that you are already using the old, poorly designed and long outdated java.util.Date class and friends. I still wanted to post the answer for users who have the option to go modern. (You may also use each of the two ideas presented with the out-dated API.)
I would try TimeZone.setDefault(TimeZone) like in:
TimeZone.setDefault(TimeZone.getTimeZone("Europe/Amsterdam"));
(advice to check returned time zone, getTimeZone does not throw exception for unknown time zone - or use ZoneId instead of the String)
see TimeZone (this also mentions the user.timezone system property)
but I am not an android programmer/user
This question already has answers here:
Daylight saving time and time zone best practices [closed]
(30 answers)
Closed 5 years ago.
What is the best way to handle multiple time zones in the application ?
The user can select the timezone that they are in. The user can be anywhere in the world.
When displaying data the time has to be adjusted to the timezone that the user has selected.
We have devices out in the field and they will be sending data, alerts etc.
What would be the best way to store data in database ?
Once data is stored then displaying will be straight forward.
I would suggest storing all times in UTC format. Perform all your calculations and algorithms with the UTC time. You only care about timezones for display purposes. For a particular user, convert the UTC time to their preferred timezone.
This question already has answers here:
How to use an Internet time server to get the time?
(5 answers)
Closed 6 years ago.
I am working on licensing and I need to get the current date and time from time server, that is irrespective of the time and date of the system.
I have tried Joda Time API and some classes of Java like TimeZone and I have seen that the value which I get is actually based on the system current time and date.
I have managed to get the TimeZone of the client machine to which it is set and now I want to query the time server for the current time of that TimeZone which will be not dependent on the system current date and time.
Will be helpful if I get some suggestions!
You can use TIMEAPI available here.
Alternatively, you can do some web-scraping.
www.time.is/GMT will give you current GMT time.
You can easily scrape the page with JSOUP or some other library.
FYI, the time is displayed within the element with the id of twd and the date is displayed within the element with the id dd.
This question already has answers here:
Daylight saving time and time zone best practices [closed]
(30 answers)
Closed 7 years ago.
I have following scenario:
A JSF application that can be used by a user to create tickets.
These tickets have a validity (from-to)
I have a application configuration which states in which TimeZone/ZoneID the context of the application runs.
I need to persist the validity of the ticket and be aware that the application configuration for TimeZone/ZoneID may change and therefore also previously created tickets should be visualized with the correct converted datetime
I'd like to know what the way to go would be? Having some custom converter to store the, adding the TimeZone information as additional field in the database or some other approach?
Is this topic database vendor specific or is there some sort of generic solution?
I'm a little puzzled, maybe I'm intending to do something that one shouldn't do, cause I didn't find too much information about this topic in general.
Finally I found a different solution, based on the fact that it is not necessary to keep the original timezone the ticket was created for. I now simply use java.util.Date in the backing bean for the date picker component and convert it to an java.time.Instant as soon as I push it to the backend.
For visualization purposes on the JSF frontend I just format the java.util.Date with a SimpleDateFormatter where I set the timezone to the one configured in the backend
String timeZoneOffset = "GMT+0100";
TimeZone timeZone = TimeZone.getTimeZone(timeZoneOffset);
DateFormat dateTimeFormat = new SimpleDateFormat("yyyy-MM-dd'T'hh:mm:ss.SSSZ");
dateTimeFormat.setTimeZone(this.timeZone);
To display the formatted java.util.Date objects in JSF I use a formatter like that
<p:outputLabel id="tripEndDate" value="#{registerBean.trip.tripEndDate}">
<f:convertDateTime pattern="yyyy-MM-dd HH:mm Z" timeZone="#{registerBean.timeZone.getID()}" />
</p:outputLabel>
Maybe as further input that might be interesting here is that I had some issues with storing the Timestamps to DB with Hibernate as Hibernate uses the systems default timezone, so if your server doesn't run in UTC you will observe this timezone conversions
I'm working on a GWT app where I need to support the following scenario:
The server is located in time zone A
The client's browser is set to time zone B
The GWT app is configured to display date/time in time zone C
Since GWT does not support Calendar and the native support for time
zones in javascript is non-existent I can't think of a nice and clean
solution to this problem.
Have any of you done something similar or do you know of any good
utils I could use?
Thanks!
In my experience, the following best practice significantly reduces complexity and confusion when dealing with dates and timezones in gwt:
Whenever operating/storing dates within the application, treat all dates as milliseconds since epoch in GMT timezone. You can store them as string or int, it doesn't really make a difference.
Whenever displaying the date to the end user, format the date using appropriate timezone.
For your case, when you create a date on the Server (timezone A) convert it to milliseconds since epoch in GMT before sending it to the Client. On the client, use DateTimeFormat (or write your own date formatter util) to convert it into either timezone B or timezone C as appropriate.
You can't change the GWT timezone, hence all java.util.Date's has the browser timezone. You will need to handle the current timezone setting manually.
I see 3 options:
You manage the timezone conversion yourself.
You override the serializer/deserializer of java.util.Date like in this post. And maybe using a custom java.util.Date implemtation, that overrides the getTimezoneOffset(). This approach requires recompilation of the GWT API!.
You implement your own Date, either by extending java.util.Date (like in option 2) or wrapping it with some timezone object. In this option CustomFieldSerializer's may still be usefull, but there is no need for recompiling the GWT API.
I would prefer option 3. At least until GWT RPC maybe someday will support for overriding the CustomFieldSerializer's
Usefull date/time formatting hints.
Dave Paroulek's answer is the right approach. If you want to see an example of this, we created widgets that work independent of TimeZone and process the values on the server-side where we have all of the TimeZone information we need.
UTCDateBox - Wrapper around the GWT DateBox and always chooses the date at midnight in GMT and represents the value as a Long instead of a Date.
UTCTimeBox - New widget that always chooses a time as millis since midnight, independent of timezone, also represented as a Long.
UTCDateTimeUtils - Server-side code that splits a Date into 2 Long values appropriate for UTCDateBox and UTCTimeBox in a given TimeZone and combines them back into a Date in a given TimeZone.
Here is an example of the date the time controls being used together.
Blog article describing their implementation.
These widgets are available on GitHub.
I'm assuming you are using RPC calls for server-client communication here. Also assuming that you don't care about timezone B, and you know what timezone C is on the server.
You have a few options here:
Calculate the desired date in the server (no Java limits on what you can do there) and send it in a String to be displayed to the client, so you don't have to do anymore transformations on the client.
or:
Calculate the offset between timezone A and C on the server, apply it to all the Date objects you are passing to the client and just display them on the client.
if for some reason none of these were valid for you
Calculate the offset, send it to the client and apply it to any Date you receive from the server by transforming to ms, adding the offset and then creating a Date object again.
see this demo project
GWT timezone demo project
I created a GWT-compatible Java version of the jsTimezoneDetect Javascript library specifically for this purpose. This should provide a (very good guess of) the timezone name purely on the client side. Feel free to try it out and let me know if it works or doesn't work for you.