I have a date stored in a database as a UTC date ('2015-04-24 00:00:00'). When I get this date (using Hibernate) on a server running in the Eastern US Timezone, is shown as the correct date, '2015-04-24 00:00:00'. However, when I get this data on a server running on AWS in the us-west-1 region, which I assume is Pacific Time, the date shows as '2015-04-23 20:00:00'. Does anyone know why this would happen? I assume it has something to do with the date converting to local time, rather than UTC, but how can I prevent this from happening? Thanks!
Short answer: Just convert your Date to utc
Somewhat longer answer: As long as we don't consider relativistic effects a date (or more appropriately named a point in time) doesn't have a time zone. But if you display it as a String there are many variants of displaying it. One kind of variation is the choice of a timezone.
If you don't take special care to use a specific time zone, many programs will choose the timezone that the machine is 'living' in, which is configured on the os level and set to the time zone that is apropriate for the location the computer is most of the time.
Related
I have many users and they are located in different timezones. When a user changes some data (for instance edits) with her or his timezone, others must see it with their timezone. For this what can I do? Firstly , I need to save date with UTC timezone and when user wants to get it, It does request to api and gets returned date. After that user can convert this date with its timezone. Other users also do so. I think it works such
In short:
if you have to deal with daylight saving time (DST), you have to stick to java.time.ZonedDateTime
If you don't care about DST - use java.time.OffsetDateTime
In any case for all communications use ISO8601 standard
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.
If unix timestamp is the same across the world how is am I able to get local time.
Or is it based on the different timezones the timestamp is different. i.e. I am in US the current seconds from UTC 1970 is 5,000 but if I am in Asia and check timestamp it will be 4,000 seconds ?
UTC is the same for every country in the world, whether you check in the US or in Asia the value will be the same.
Local time is calculated by using a time-zone offset (usually provided through the IANA time zone database). This is added to UTC time to determine the "Local Time" since 1970.
Both oldschool java.util.Date and modern java.time.SystemClock are using System#currentTimeMillis() to get system time, so let's assume you have same Unix time value on both machines.
Unix time to local time conversion could be a Bachelor's degree thesis: you have to consider leap years, leap seconds, daylight savings time, some changes to country's timezones made by government. You can read more about all that in OpenJDK's tzdata sources.
So, you need both system time and tzdata to be the same on your machines.
I think epoch converter can answer your question:
http://www.epochconverter.com/
You will see that Unix time is the same across the world, and it will print date accordingly to your localization
I have a Client-Server based java application.The client is running in US/Pacific timezone and the server in UTC( I am saving the time in the database in UTC)
So for example, if I save the date as 09:00 Hrs Pacific time, it gets saved in the DB as 14:00 Hrs UTC.
When I read this time back from DB, daylight saving gets applied and it now gets converted to 08:00 hrs pacific time instead of 09:00 hrs.
So when converting from Pacific time to UTC, no daylight saving is considered, but when converting back from UTC to Pacific, it is applied which is not consistent.
In the DB, the column type is TIME and in java I am reading it into a date object.
How do I handle this ?
Normally the DB server decides on the time, applies daylight savings or not, and the time zone, which UTC is a standard.
Suggestion:
Maybe you want to set the time by the client side as a string field with another field for the time zone PST, EST, or whatever.
Make a field just for the time zone, and calculate the time for display to the client side.
I think the best thing you can do is make sure as much of your time handling as possible is done free from time zones at all. For example, millis since the Unix Epoch. Then you only apply time zone data just before it is displayed to the user.
So, in this case, do not apply any local time assumptions when you report to the server and when you retrieve from the server. In this way, it is impossible to have mismatching time zone or DST treatment of the data.
With all this aside, I suggest you use getLong manually and construct the Date object yourself.
Trying to get a time stored in a datadase.
select dbtimezone from dual gives me -07:00
I am using Java program to get the Date from Oracle
Column i type of Date.
while i am fetching the time in my java program am getting it as GMT.
actually i want the time as it is there in database not converted time.
Though i can convert back to -07:00 , i am seeking another way to do because conversion always depends on the dbtimezone of the database using.
Can any one help me ?
Thanks in advance
That oracle just has one timezone can make life difficult if you deal with different timezones. I've always thought life was easier if you consider timezone a view artifact and
represent all times as UTC, then convert in the view. You put the timezone information someplace in the database and convert accordingly.
...actually getting that right can get interesting because you don't want to make the same mistake of being too general again. For example, a client may be based in a particular timezone, but have offices in many. Though an office is in a particular timezone, the activity relating to the time may involve a different timezone etc.
See java.util.TimeZone, more specifically the getOffset methods, which return the number of milliseconds to add to the UTC time to get local time. Note that it also considers the daylight saving time.