I have web application in which I have to draw a chart according to time.
Now because the Daylight time is changing to standard time on 3rd November at 2AM.
I have change the code according to these time changes, but I want to know some API which tell me this date and time when these changes occur. Like "3rd November at 2AM".
Joda-Time is a great solution. Check this.
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
When using Magnolia CMS' DateFieldDefinition class: if my computer's current date is not matching the saved date's Daylight saving time, the saved date's time will be incorrect.
The relevant class: info.magnolia.ui.form.field.definition.DateFieldDefinition.
The relevant Vaadin component "Date and Time Input with DateField".
Another person seemed to have the same problem.
EDIT: Magnolia CMS appears to have a ticket about this issue already
Example:
In this example, I am running Magnolia CMS locally.
My computer's current date is Oct 17th, 2016
My computer's TimeZone is "Switzerland/Zurich"; hence I am on GMT+2 for the current date (summer time for my time zone)
In Magnolia Admin Panel, I save a date on Nov 3rd, 2016, hence that date is in winter time for my time zone, so GMT+1
That's where it gets interesting:
I change my computer's date to Nov 2nd, 2016, hence I am on GMT+1 (winter time for my time zone)
In Magnolia Admin Panel I open that date, it shows one-hour less.
Illustrations
The date/time implementation in Magnolia 5 was (and possibly still is) rather bad because of several issues:
It failed to distinguish between points in time (e.g. Skype appointment with someone possibly in another time zone) and "concept" times (e.g. a note when to make breakfast - it will always be at 7:00, no matter what time zone, so it's not about a specific point in time but about the concept of 7 o'clock)
It saved dates as timestamps although dates are neither timestamps nor time spans. This inaccuracy lead to the next problem:
Since dates were treated as timestamps by Magnolia 5 and timestamps were always handled as "points in time" by Magnolia 5, dates were also treated as points in time by Magnolia 5 although this is always wrong. Dates are always just "concepts" (in above sense), e.g. dates of birth. If I'm born on 1st January 1980, then that's my date of birth, and that is so in every time zone. My date of birth is not 31st December 1979 in another timezone, like it would with the "point in time" semantics mentioned earlier.
Dates and times were saved as instances of Calendar in JCR, that is a timestamp with a timezone. When transferring data from one Magnolia instance to another (Export, Import, Activation), the actual timestamps were copied as they were, they were not converted to the timezone of the target system. This meant that when the target system finally read the values, it may have seen wrong dates and/or times unless it explicitly converted the values.
Magnolia used to use the Browser's time zone for reading dates/times from the user by the Vaadin date/time fields but the server time zone for storing them in JCR. This meant there was always an implicit translation that may or may not have been wanted in the business logic. In many cases wrong values would end up in the repository (e.g. when entering dates of birth), so the later processing based on them had a certain probability of going wrong. In any case it had to be expected that the date/time saved in the repository was not the one the user had entered.
In a support ticket I wrote to Magnolia about these isuees they said they had fixed it in Magnolia CORE 5.4.11, which will be available since 5.5.1. I haven't tested these fixes yet, but unless you use this fixed version I wouldn't recommend to expect a simple solution for your problem, which comes on top of the problems I mentioned above. I did so just to document how little room there is to get the correct behavior for your use case with provided classes unless you needed exactly the use case they had implemented.
Now correct time zone for Moscow is UTC +3. But Android 4.4.4 only knows UTC +4 for Moscow.
And java.util.Date give wrong time:
Date now = new Date();
Sat Nov 21 00:37:24 GMT+04:00 2015
1448051844024 in (milliseconds)
Using Joda org.joda.time
DateTime nowWithCorrect = new DateTime()
.withZone(DateTimeZone.forID("Europe/Moscow"));
2015-11-20T23:37:24.023+03:00
1448051844024 in (milliseconds)
But problem is the user (on devices with incorrect time zone) has manually corrected time on device. And joda and java give incorrect time in milliseconds.
I get from web service timestamp and on device calculate different with local time. But local time incorrect and give incorrect results.
I want check joda and java time and manually to correct timestamp.
Question: can I get different between time zone and different between time in hours (now and nowWithCorrect)?
For example: differentTimeZone = 1, differentTimeHours = 1
Confusing Time Zone Changes In Russia
Russia has gone through some confusing time zone changes in recent years, with Moscow’s offset-from-UTC shifting back-and-forth between +03:00 and +04:00. See Wikipedia pages on Time in Russia and Moscow Time.
Before autumn of 2011, Moscow had standard time was +03:00 with a Daylight Saving Time (DST) of +04:00.
Starting in the autumn of 2011, Russia took a decision to stay permanently on DST, +04:00, and abolish the standard time of +03:00. See this RT.com article.
In July 2014, that decision was drastically altered. Now Russia is permanently on a standard time of +03:00 and has abolished DST (no more +04:00).
Outdated tz Database
So I assume your troubles are due to your time zone tz database (formerly known as the Olson database) being outdated. The real Java platform has a tz database, and its host operating system likely has a tz database. Joda-Time has its own tz database. I assume Android does as well, though I do not know about Android.
Obviously keeping all these tz database up-to-date is a real chore.
For Joda-Time, simply replace your Joda-Time library with the latest. While you can replace just the tz database in Joda-Time, as far as I can remember, there are virtually no backward-compatibility issues with Joda-Time 2, so no reason not to update the entire library. But read the release notes to be sure. If using Joda-Time, this is the only minimum requirement for updating; I would recommend updating Android, Java, and host OS as well but not necessary.
For the real Java platform, recent versions made it much easier to update the tz database. Previous versions required some hacking. Alternatively, update to the latest Java 8 to get the latest library.
For your host OS, its regular updating system probably contains tz updates. However, some of those updates may lag behind. So you may need to do a manual update.
Work In UTC
The best practice for date-time work is usually to do all of your back-end work in UTC. Business logic, data storage, database, data exchange, and such should all be in UTC. Adjust into a time zone such as Europe/Moscow only when expected/desired by the user or data sink.
In Java 8 and later, we would use the built-in java.time framework. Use Instant for a moment in UTC. Specify a ZoneId to get a ZonedDateTime when a time zone is needed. But Java 8 technology is not yet available in Android. I believe there is back-port library for java.time for Android, but I do not know the details.
For Joda-Time, ask for the current moment in UTC.
DateTime nowUtc = DateTime.now( DateTimeZone.UTC );
If you cannot trust the user’s local device/computer clock to be accurate and set correctly, then this UTC date-time will be wrong. Nothing you can do about that. Instead trust an outside source, but that assumes a network connection.
Adjust into Moscow time as needed.
DateTime nowMoscow = nowUtc.withZone( DateTimeZone.forID( "Europe/Moscow" ) );
If the user’s tz database for Joda-Time is outdated, this will return a wrong result. No way to prevent that as you cannot predict what the Russian authorities will do next to their time-keeping rules. The only solution is to keep your app updated with a Joda-Time library that has an updated tz database. Or, again, trust an outside source such as your server or some other web service, but that assumes a network connection.
Verify Count-From-Epoch
If you are getting confused and want to verify a date-time object’s true value, look at the count-from-epoch.
Both Joda-Time and the old java.util.Date/.Calendar classes count milliseconds from first moment of 1970 UTC. These values are shown in the Question. See how both milliseconds-from-epoch values in the Question are the same, so same moment on the timeline but an incorrect adjustment into Moscow time by Android's Date class (almost certainly because of an outdated tz database).
Note that java.time uses a different count-from-epoch, counting nanoseconds from same epoch (1970 UTC). In Joda-Time, call getMillis to get the count-from-epoch. In java.util.Date, call getTime.
You could find the difference between joda-time timezone (which is based on last IANA) and android system timezone:
long diff = DateTimeZone.getDefault().getOffset(yourTimeStapm) - TimeZone.getDefault().getOffset(yourTimeStapm);
Also you could use fork of joda-time which is used system timezones:
https://gitlab.com/olekdia/common/utils/support-joda-time
I stumbled upon this piece of code to get current time in EST with daylight saving. It seems to work fine, when checked on the internet by the time displayed in sites providing current time in EST with daylight saving.
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MMM-dd HH:mm:ss.SSS");
dateFormat.setTimeZone(TimeZone.getTimeZone("EST5EDT"));
System.out.println(dateFormat.format(new Date()));
I just want to confirm, has anybody used something like this before or there is a better way to achieve the same. I cannot use Joda library due to constraints.
Thanks in advance.
Yes, that's the best (and indeed the only) way to do this using Java's standard libraries.
Hi i have a typical requirement in my web application, i have to fill a dropdown box with all system timezones and set the selected time zone where from the client is browsing.
Only timezoneoffset is not enough to handle this suituation, since there are two reasons
1.the latest OS having more than one time zone with the same offset
2.If Day light save is enabled or disable(can be detected from Javascript) the offset will vary.
is ther any ways of handling this in Java script?
Short answer:
Use this open source JavaScript project: jsTimezoneDetect. It is based on the code that MK linked here, which is great, but not enough since different regions within the same timezone start their daylight savings at different times. Hemisphere also plays a factor.
Long answer:
One example is the -07:00 UTC timezone which basically has three sub timezones.
US Mountain Standard Time (no daylight saving... this is Arizona)
US Mountain Time (with daylight savings)
Mexico Mountain Time (with daylight savings)
Assuming that you know your user's UTC offset you will now have to check whether your timezone uses daylight savings. Create one January and one June date and check these two dates. If their UTC offsets differ, then you are in a timezone that uses daylight savings.
Say that you have determined that your user is -07:00 with daylight savings, that means either US Mountain Time (America/Denver) or Mexico Mountain Time (America/Chihuahua). How to tell them apart? Well, the date they start their daylight savings differ.
US daylight savings starts in 2011 starts 13 March, and in Mexico it 4th April. So start with Denver and check if 13 march is summer time, no? Ok, check if 4th April is summer time. Yes? Bingo.
Check this: Auto detect a time zone with JavaScript.