2

I have a Java Application running in my Ubuntu Server in USA and configure CEST Time Zone.

If I run Date command in terminal it return date in CEST Zone time - this is perfect.

But In Java if I run the following code

System.out.println (new Date ());

It returns me time in EDT. What configuration am I missing.

syv
  • 3,528
  • 7
  • 35
  • 50
  • see http://stackoverflow.com/questions/3010035/converting-a-utc-time-to-a-local-time-zone-in-java?rq=1 – Justin Oct 26 '13 at 06:31
  • I've recently faced and debugged this. Written an article on how it's working. https://syogaraj.medium.com/debugging-timezone-issue-in-java-linux-957f237098ea – Yogaraj Mar 14 '22 at 16:31

3 Answers3

2

You have to be careful in interpreting date objects from the display you get in console because they are formatted using the default TimeZone of the VM on which this program is running (which by default inherits it from timezone of OS). Of course you can supply your own TimeZone as explained in the answer by Jesper. But while doing so I would strongly recommend to use IANA timezone identifiers like America/New_York instead of EST. More so because abbreviations having "standard" do not take into account day light savings.

So if you simply print the date object on console and you are not getting expected result, chances are high that you have your server timezone is set to wrong value or your OS is set at wrong timezone.

For changing the JVM timezone you can use this parameter on startup

-Duser.timezone="America/New_York" 
Shailendra
  • 8,874
  • 2
  • 28
  • 37
0

You say the server is configured to be in the CEST timezone, but according to Java the default timezone is EDT. Java gets the default timezone from the operating system, so probably your server is not properly set to be in CEST.

If you want to print the date in a specific timezone, use a DateFormat and set the timezone on it:

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("CET"));
System.out.println(df.format(new Date()));

Note: CEST is not a valid timezone according to my Java (Java 7u45). Did you mean "CET"? (CEST is the summertime variant of CET, but if you use CET, Java will automatically display the time in summertime if appropriate).

Jesper
  • 202,709
  • 46
  • 318
  • 350
0

tl;dr

UTC:

Instant.now()    // Instantiate an object capturing the current moment in UTC.
    .toString()  // Generate a String representing textually that date-time value using standard ISO 8601 format.

2018-03-16T00:57:34.233762Z

Zoned:

ZonedDateTime.now( ZoneId.of( "Africa/Tunis" ) )  // Instantiate an object representing the current moment with a wall-clock time seed by people in a particular region (time zone). 
    .toString()                                   // Generate a String representing textually that date-time value using standard ISO 8601 format wisely extended to append the name of the time zone in square brackets. 

2018-03-16T01:57:34.233762+01:00[Africa/Tunis]

Details

The Answer by Shailendra is spot-on correct.

In addition, the Date class seen in the Question is part of the troublesome old date-time classes that are now legacy, supplanted entirely by the java.time classes.

The replacement for java.util.Date is java.time.Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Instant::toString ➞ UTC always

When calling the legacy class’ Date::toString method, the unfortunate behavior chosen by its authors is to dynamically apply your JVM’s current default time zone. This creates no end of confusion. Fortunately, the modern class tells the simple truth without adding any time zone: An Instant is always in UTC.

Instant.now().toString()

2018-03-16T00:57:34.233762Z

That strings format is standard ISO 8601 format. The Z on the end is short for Zulu and means UTC.

CEST Zone time

There is no such thing as a time zone named CEST. Such 3-4 letter names are pseudo-zones. They are not standardized. They are not unique(!). Instead use a proper time zone in format of continent/region.

ZoneId z = ZoneId.of( "Europe/Paris" ) ;

You can adjust from UTC to such a time zone by applying a ZoneId to your Instant to get a ZoneDateTime.

Instant instant = Instant.now() ;
ZonedDateTime zdt = instant.atZone( z ) ;

zdt.toString(): 2018-03-16T01:57:34.233762+01:00[Europe/Paris]

Or use the shortcut, ZonedDateTime.now.

ZonedDateTime zdt = ZonedDateTime.now( z ) ;

You can adjust a ZonedDateTime to another time zone as well. Notice that java.time uses immutable objects. So in adjusting we get a new distinct object based on the original but without disturbing the original.

ZoneId zNewYork = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdtNewYork = zdt.withZoneSameInstant( zNewYork ) ;

zdtNewYork.toString(): 2018-03-15T20:57:34.233762-04:00[America/New_York]

Be very clear that instant, zdt, and zdtNewYork are three separate objects that represent the very same moment, the same point on the timeline. Same moment, different wall-clock time.

I have a Java Application running in my Ubuntu Server in USA and configure CEST Time Zone

FYI, generally speaking, the best practice for a server’s default time zone is UTC.

More importantly, the current default time zone of your server OS and JVM should be irrelevant to your Java app.

Rather than rely implicitly on the JVM’s current default time zone, always specify explicitly the desired/expected time zone. Pass the optional ZoneId argument to the various java.time methods as seen in the code above.

(By the way, ditto for Locale - always specify desired/expected locale rather than rely implicitly on current default.)


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154