java print date different than the system - java

I need to set the system date in Centos 6.6 so what i did
cp /usr/share/zoneinfo/Europe/Paris /etc/localtime
And I wrote a small java application to print date and I print the date with the command date and i got this
[root#sandbox ~]# date
Fri May 20 19:13:32 CEST 2016
[root#sandbox ~]# java t
Fri May 20 17:13:35 UTC 2016
I really need to know why i have different time and how to fix it?
And i don't want to make change to the java code i want to fix the system date

We cannot precisely assist you until you post the source code for that little Java app.
Tracking date-time
One general concept you seem to be misunderstanding is that a date-time as tracked by a computer has no time zone. If you are using the old outmoded class java.util.Date, it tracks a number of milliseconds since the epoch reference date of first moment of 1970 in UTC.
Date-time != String
Another concept: A date-time object is not a string. You can generate a String to represent the date-time value in your date-time object, but that string is distinct from the date-time. Remember, internally that date-time is actually a count of milliseconds since 1970 UTC).
Your app is likely calling the toString method on java.util.Date class. That method confusingly applies the JVM’s current default time zone to the stored date-time creating the false illusion that the java.util.Date has that zone assigned.
Default time zone
The default time zone is usually picked up from the host OS when the JVM launches, but not always. Configuration flags for the JVM may indicate another time zone as default. And any code in any thread of any app within the JVM can change the JVM’s default time zone at any moment, during runtime! Because of being undependable, I suggest you avoid using the default, and instead always specify the desired/expected time zone.
Generally best practice is to keep servers on UTC. But I do not want my app to be vulnerable to such externalities as some sysadmin changing the server’s time zone, I always specify the desired/expected time zone in my Java code (shown further down).
No problem
So you have no problem to fix. Paris time (CEST) of 19:13:3x is two hours ahead of UTC, which your Java app is correctly showing as 17:13:3x for UTC time zone. These values make sense. These two date-time strings are two different representations of the very same moment on the timeline.
If you want a Paris time in your Java app, ask for a Paris time (shown further down below). If you want UTC, ask for UTC in your Java app (also shown further down).
As to why your Java app is showing the time in UTC remains a mystery until you show us your source code.
In the mean time, I can show the basics of capturing the current time and adjusting into a desired time zone.
java.time
You are use old date-time classes that have proven to be troublesome, confusing, and flawed. Avoid them. These old classes have been supplanted by the java.time framework built into Java 8 and later. Much of the java.time functionality has been back-ported to Java 6 & 7 in ThreeTen-Backport and further adapted to Android in ThreeTenABP.
An Instant is the current moment on the timeline in UTC, with resolution of nanoseconds (finer than the milliseconds in java.util.Date).
Instant instant = Instant.now();
Generally best to much of your business logic, database storage, other storage, and data exchange in UTC. So make frequent use of Instant.
Wall-clock time
Apply a time zone to get the wall-clock time for some locality. Apply a ZoneId to get a ZonedDateTime.
ZoneId zoneId = ZoneId.of( "Europe/Paris" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Generating ISO 8601 strings
The toString methods in java.time by default generate strings in the standard ISO 8601 formats. The ZonedDateTime class’ toString method extends the standard by appending the name of the time zone in square brackets.
String output = instant.toString();
2016-05-21T00:52:53.375Z
String output = zdt.toString();
2016-05-21T02:52:53.375+02:00[Europe/Paris]
You can adjust into yet another time zone. Notice the date being previous to that of Paris, 20 versus 21 of May (still “yesterday” in Montréal).
ZonedDateTime zdt_Montréal = zdt.withZoneSameInstant( ZoneId.of( "America/Montreal" ) ) ;
2016-05-20T20:52:53.375-04:00[America/Montreal]
So we have generated three different textual representations of the very same moment on the timeline (UTC, Paris, & Montréal).
Time zones
Avoid using 3-4 letter zone abbreviations like CEST. These are neither standardized, nor unique(!). Furthermore, they are not true time zones. Always use proper time zone names, in the format of continent/region.

if you don't like or you can't change java code then you have to change server/system/centos timeZone, First you have to see list of possible timezones in
ls /usr/share/zoneinfo
and result
see we have date Sat May 21 02:54:11 IRDT 2016 we are now going to change you need to change (or set) the symbolic link /etc/localtime so make a backup of the existing `localtime file
sudo mv /etc/localtime /etc/localtime.bak
Next, create the link:
sudo ln -s /usr/share/zoneinfo/America/Chicago /etc/localtime
Make sure to replace America/Chicago with the directory (if your zone has one) and filename of the timezone you wish to use for example
sudo ln -s /usr/share/zoneinfo/UTC /etc/localtime
Now you just need to test your change. Run date from the command line, i done it and result are
and for see huge list of timezone click here

Make sure you also check your /etc/timezone file and adjust accordingly

Ok first you should think of using #Basil-Bourque answer to change your code. it's a good practice
and for changing you Centos timezone try to export TZ to Europe/Paris like the following
export TZ="Europe/Paris"

Related

TimeZone isn't showing

I'm using IntelliJ (Kotlin and Java language), I'm trying to get a report of time by using query from my database and send that to the browser (I'm using Postman to see the result).
When I debug my code and go through the result from the query the timezone is ok like the way I want it, its even show -7 (the difference time between me and the UTC) but when it comes to the browser (Postman) it's showing UTC time and +0000, for example:
"date": "2017-10-12T15:00:33.000+0000"
instead of
"date": "2017-10-12T15:00:33.000+0007".
I tried many options and waste around 6 hours to find the solution but nothing work.
Postgres stores a TIMESTAMP WITH TIME ZONE in UTC, discarding the passed zone after using it to make the adjustment into UTC. Note that this is Postgres-specific behavior – databases vary widely in their date-time handling, and the SQL spec barely touches on the subject.
As commented by Marlowe, if you need to remember the time zone captured from data-entry, you will need to store that in another column. Capture a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
➠ Here's the rub: A Postgres session in an interactive tool such as pgAdmin dynamically applies a default time zone after fetching the UTC value. While well-intentioned, this is an anti-feature in my opinion as it obscures the true nature of the stored data.
Fetch the value in UTC using the modern java.time classes.
Instant instant = myResultSet.getObject( … , Instant.class ) ;
Adjust to your desired time zone.
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;
Generate a string for the web browser using the DateTimeFormatter class. Note the automatic localization features there.
All this has been covered many times on Stack Overflow. Search to learn more.
Solution: so i found the solution to my problem here:
Overriding BeanPropertyRowMapper to Support JodaTime DateTime
in shortly, timestamp type doesn't work well with timezone so i changed it to DateTime in Joda and wrapped the result of the query by costumed Bean (from the link i posted)

Changing timezone of a system using Java

I am currently writing an application where I want to provide a feature wherein a user can change the current time and timezone of the system.
Using the input timezone value , I run a shell script which links the local time to the passed timezone.
On UI, I am showing a list of timezones by calling - TimeZone.getAvailableIDs();
This retrieves TZ info from the "tzdb.dat" which comes along with the JRE.
But some of the timezones like "IST" are not supported by the native system. And these kind of unsupported Timezones are returned by TimeZone.getAvailableIDs().
So is there any way in Java where we can retrieve native system supported timezones ?
Time zones have a poor history
Time zones are, surprisingly, a real mess. I have been surprised to learn that they have not historically been well-defined and standardized.
In more recent times, a format of Continent/Region seems to have been widely adopted. See examples on this Wikipedia page. And learn about tzdata maintained currently by IANA.
You asked:
is there any way in Java where we can retrieve native system supported timezones ?
The TimeZone class in Java is now obsolete, supplanted by the modern java.time class ZoneId. Get a set of time zone names.
Set< String > zoneIds = ZoneId.getAvailableZoneIds() ;
Time zones change surprisingly often, both in their name and their currently used offset-from-UTC. Be sure to keep the tzdata in your Java implementation up-to-date. Ditto for your host OS. And your database system as well, with some such as Postgres having their own internal copy.
True time zones
You said:
But some of the timezones like "IST"
IST is not a real time zone. It is a pseudo-zone, which could mean Irish Standard Time, India Standard Time, or something else.
Specify a proper time zone name in the format of Continent/Region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 2-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).
If you meant India time, use:
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
If you meant Ireland time, use:
ZoneId z = ZoneId.of( "Europe/Dublin" ) ;
Do not rely on current default time zone
As commented by Matt Johnson-Pint, you should generally not be altering your host OS’ default time zone. Indeed, servers should usually be set for UTC (an offset of zero hours-minutes-seconds).
In your Java code, always specify your desired/expected time zone. The JVM’s current default time zone can be altered at any moment by any code in any thread of any app within the JVM — so depending on the current default is not reliable.
If you want the current moment as seen in India, specify the appropriate time zone.
ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = ZonedDateTime.now( z ) ; // Capture the current moment as seen in the wall-clock time used by the people of a particular region (a time zone).

new Date() is giving time in UTC in ec2 Instance which is configured as IST

I have an ec2 instance running in Singapore zone. By default time zone for this instance is UTC. So I've set it to IST assuming, application which is running in this instance generates time in IST which we store in the database.
i.e new Date() in my application shoud return time in IST. But it's still generating time in UTC which isn't we needed.
So, how to make new Date() gives time in IST in ec2 instance without adding explicit java code?
Try to set -Duser.timezone="Asia/India" as Environment Variable or run your java app with that switch from terminal using java filename -Duser.timezone="Asia/India"
java.time
ZonedDateTime.now(
ZoneId.of( "Asia/Kolkata" )
)
Details
The toString method of Date confusingly applies the JVM’s current default time zone while generating the string. This misleads you into thinking it has an assigned time zone but does not^. The Date object actually represents a value in UTC. One of many reasons to avoid these troublesome old legacy date-time classes.
This class is now supplanted by the java.time classes.
The Instant class represents a moment in UTC.
Instant instant = Instant.now();
Adjust into your desired time zone. Never use 3-4 letter abbreviations such as IST. Not a real time zone. Use real time zone names.
ZoneId z = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdt = instant.atZone( z );
This Question is really a duplicate of many others. Search Stack Overflow for much more discussions and examples.
Do not alter the time zone of your host operating system nor the JVM’s default time zone. You simply should not rely on the default time zone as it can be changed at any moment at runtime by any code in any thread of any app within your JVM. Always specify the optional argument for time zone when calling the java.time classes, problem solved.
^To make things even more confusing, there actually is a time zone within the Date class, but without getters or setters. Used internally, but irrelevant to our discussion here. These old legacy date-time classes are a very confusing mess.

Converting Date from ZoneDateTime gives local times instead of ZonedTime

I am trying to convert the ZonedDateTime to a Date. Looks like in the conversion, it looses the time zone and gets my local time.
System.out.println("zoneDate1::::::::::"+ZonedDateTime.now(ZoneId.of("America/Chicago")));
System.out.println("zoneDate1:Date::::::::::"+Date.from(ZonedDateTime.now(ZoneId.of("America/Chicago")).toInstant()));
The above outputs as below:
zoneDate1::::::::::2016-04-15T17:35:06.357-05:00[America/Chicago]
zoneDate1:Date::::::::::Fri Apr 15 18:35:06 EDT 2016
Is this because this is a Date type? How would i go about doing this kind of conversion and conserve the zoned time?
What is the problem? What did you expect? I see no misbehavior.
Your java.time type (ZonedDateTime) is assigned a time zone of America/Chicago.
Your JVM apparently has an assigned time zone related to east coast of North America, the clue being the EDT value seen in string output. The toString method on java.util.Date applies your JVM’s current default time zone when generating its textual representation of the date-time value. Poorly designed, this behavior is trying to be helpful but is actually confusing because you cannot actually get or set this time zone on the java.util.Date object.
At any rate, the east coast of North America (such as America/New_York time zone) is an hour ahead of America/Chicago. So you are seeing 17:xx:xx time for Chicago and 18:xx:xx for Eastern Daylight Saving Time. These values are correct.
You should call java.util.TimeZone.getDefault() when investigating the behavior of the old date-time classes.
java.time
The bigger problem is that you are even using these old date-time classes such as java.util.Date/.Calendar. They are poorly designed, confusing, and troublesome. Avoid these old classes altogether. They have been supplanted in Java 8 and later by the java.time framework.
Also, avoid using 3-4 letter zone abbreviations like EDT. These are neither standardized nor unique. Use proper time zone names in continent/region format.
Instant
To capture the current date-time in java.time, just use Instant. This class captures a moment on the timeline in UTC. Do most of your work in UTC. No need for time zones unless expected by your user when displayed in the user interface.
Instant now = Instant.now();
Database
To send to your database, first make sure you have defined the column in the table as something along the line of the SQL standard TIMESTAMP WITH TIME ZONE. By the way, support for date-time types various among databases with some doing a much better job than others.
Hopefully JDBC drivers will be updated someday to directly handle the java.time types. Until then, we must convert into a java.sql type when transferring data to/from a database. The old java.sql classes have new methods to facilitate these conversions.
java.sql.Timestamp
For a date-time value like Instant, we need the java.sql.Timestamp class and its from( Instant ) method.
java.sql.Timestamp ts = java.sql.Timestamp.from( now );
Avoid working in java.sql.Timestamp as it is part of the old poorly-designed mess that is the early Java date-time classes. Use them only for database transfer, then shift into java.time immediately.
Instant instant = ts.toInstant();
So simple, no time zones or offset-from-UTC involved. The Instant, java.sql.Timestamp, and database storage are all in UTC.
ZonedDateTime
When you do need to shift into some locality’s wall-clock time, apply a time zone.
ZoneId zoneId = ZoneId.of( "America/Chicago" ); // Or "America/New_York" and so on.
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
Huh? Date doesn't have time zones so, this is probably why it's failing. Maybe this is what you're looking for:
Date.from(java.time.ZonedDateTime.now().toInstant());
If your database allows you to store the timestamp along with the timezone, you should go ahead and save it as a timestamp.
If not, I would recommend that you store the date-time as per your timezone (or GMT). Add an additional column in the table to hold the value of the user's timezone.
When you fetch the value from the database, you can convert it to the user's timezone. Avoid storing just the date.

android java time

i'm building an android application which have a chat.
in this chat i each message to have its time sent signature.
my question is as follow:
lets say that the time in my country is X. my friend is abroad and his time is X minus 7 hours.
i'm sending him a message at 16:00 local time.
i want to avoid the situation that he will get at 09:00 a message which it signature will be 16:00 (which is a time in future if you're looking in the eyes of that friend in his country).
is there a way that in my phone the message will be written as 16:00 and in his phone it will be written as 09:00 ? i there a way to convert a time to a local time ?
System.currentTimeMillis() does give you the number of milliseconds since January 1, 1970 00:00:00 UTC. Date object does not save your local timezone.
You can use DateFormats to convert Dates to Strings in any timezone:
DateFormat df = DateFormat.getTimeInstance();
df.setTimeZone(TimeZone.getTimeZone("gmt"));
String gmtTime = df.format(new Date());
linked response
You should keep all time communications using UTC time. Then localize it for display based on the devices current timezone setting.
Use a long to save your time information as milliseconds since "epoch" (which is January 1, 1970, 00:00:00 GMT). It can be retreived with the Date.getTime() method and new Date objects are easily created using the Date(long millis) constructor. The Date objects are then displayed using the local timezone settings on each device.
EDIT:
Epoch is a defined point in time which is expressed differently in different time zones: 1970-01-01 00:00:00 GMT but
1969-12-31 19:00:00 EST. The timestamp is just the number of milliseconds elapsed since that time. So, for example the timestamp 1341169200 corresponds to 2012-07-01 19:00:00 GMT and 2012-07-01 14:00:00 EST.
You will need to save the time zone which your message will be saved in, and transfer it (or send the unix epoch time) and then on the other side make sure you read it in with the Locale time (using the Android documentation for things like http://developer.android.com/reference/java/util/Calendar.html can help).
Take a look at the answer over here:
https://stackoverflow.com/a/6094475/346232
You need to change the time to UTC and then convert on the device to the timezone.
Avoid java.util.Date/.Calendar
The java.util.Date/.Calendar classes bundled with Java (and Android) are notoriously troublesome, flawed in both design and implementation.
Joda-Time
The Joda-Time library is the way to go. This library inspired the java.time package now built into Java 8 (not available on Android).
UTC
As other answers suggested, the best practice (generally) is to keep your business logic and data storage/communication in UTC time zone (which some think of as no time zone or an "anti" time zone). Adjust to a specific time zone only when expected by the user or data-consumer.
Time Zone
The DateTime class in Joda-Time represents a date-time value along with an assigned time zone.
Note that it is best to specify a time zone in all your operations. Otherwise you will be implicitly relying on the JVM’s current default time zone. This is risky because that zone can change – even at runtime at any moment by any code in any thread of any app running within your app’s JVM. And use proper time zone names, never the 3-4 letter codes.
Example Code
Example code in Joda-Time 2.7.
DateTime sent = DateTime.now( DateTimeZone.getDefault() ) ;
DateTime sentUtc = nowMine.withZone( DateTimeZone.UTC ) ; // Generally, use this for your work, including communicating to other threads and apps and such.
When ready to display to the other user, adjust to the expected time zone.
DateTimeZone zone = DateTimeZone.forID( "America/Montreal" ) ; // Or DateTimeZone.getDefault() if you want to rely on their JVM’s current default. To be absolutely sure of expected time zone, you really must ask the user.
DateTime sentMontréal = sentUtc.withZone( zone );
To generate a textual representation of those date-time objects, search the many Questions and Answers on StackOverflow.com on that subject. Search for terms like "joda" and "DateTimeFormatter" and "DateTimeFormat".

Categories

Resources