2

Why does java.util.Date object show date & time with respect to a timezone when in actuality, java.util.Date represents an instant on the time-line, not a "date"? The actual data stored within the object is a long count of milliseconds since 1970-01-01T00:00Z (midnight at the start of 1970 GMT/UTC).

Also in docs, A java.util.Date instance has no concept of time-zone.

If so is the case, why does this snippet print date specifying timezone.

public static void main(String[] args) {
        Date date = new Date();
        System.out.println(date);
    } 

Output : Wed Mar 22 14:58:56 IST 2017

Why is it showing specific timezone in the output? I understand the SOP implements toString() internally. Does toString() effect the timezone?

6
  • 1
    All the ambiguity with Date is a good reason for using the new java.time classes, like LocalDate/LocalTime. Commented Mar 22, 2017 at 9:45
  • 3
    The Javadocs for java.util.Date#toString are quite clear on this, and are arguably the obvious first place to look for answers to questions about java.util.Date#toString. There we find that indeed, as you surmised, toString is wired to use time zone information, when available. Commented Mar 22, 2017 at 9:46
  • 1
    To print a point on the time-line, you have to use some time zone. The designers decided for the local time zone instead of UTC. Commented Mar 22, 2017 at 9:48
  • Back in Java 1.0 when the Date class was designed and there were no plans to make a Calendar class let alone LocalDateTime or ZonedDateTime this probably seemed like a reasonable choice. Commented Mar 22, 2017 at 10:20
  • As commented by Ole V.V.… FYI, the troublesome old date-time classes such as java.util.Date, java.util.Calendar, and java.text.SimpleDateFormat are now legacy, supplanted by the java.time classes built into Java 8 & Java 9. See Tutorial by Oracle. Commented Feb 11, 2018 at 22:37

3 Answers 3

4

Just follow the javadoc, as it says:

public String toString()

Converts this Date object to a String of the form:

dow mon dd hh:mm:ss zzz yyyy

zzz is the time zone (and may reflect daylight saving time).

And when you dive into the source code, that this toString() implementation will at some point use TimeZone.getDefault() ( or to be precise: getDefaultRef()). In other words: the default implementation pulls in the "default" timezone of your JVM.

Sign up to request clarification or add additional context in comments.

1 Comment

Edited to replace "system" with "JVM". The JVM maintains its own current default time zone which may differ from that of the host OS.
3

tl;dr

Current moment in UTC.

Instant.now()    // Capture current moment in UTC.
    .toString()  // Generate String in standard ISO 8601 format.

2018-01-23T01:23:45.677340Z

Current moment in India time zone.

ZonedDateTime.now( 
    ZoneId.of( "Asia/Kolkata" ) 
).toString()    // Generate string in format wisely extended from ISO 8601 standard, adding the time zone name in square brackets.

2018-01-23T06:53:45.677340+05:30[Asia/Kolkata]

Avoid legacy date-time classes

Why does java.util.Date object show date & time with respect to a timezone when in actuality, java.util.Date represents an instant on the time-line, not a "date"?

Because the java.util.Date and related classes (Calendar, SimpleDateFormat, and such) are poorly-designed. While a valiant effort at tackling the tricky subject of date-time handling, they fall short of the goal. They are riddled with poor design choices. You should avoid them, as they are now supplanted by the java.time classes, an enormous improvement.

Specifically to answer your question: The toString method of Date dynamically applies the JVM’s current default time zone while generating a String. So while the Date object itself represents a moment in UTC, the toString creates the false impression that it carries the displayed time zone.

Even worse, there is a time zone buried inside the Date object. That zone is used internally, yet is irrelevant to our discussion here. Confusing? Yes, yet another reason to avoid this class.

A java.util.Date instance has no concept of time-zone.

Not true. A Date represents a specific moment, a point on the timeline, with a resolution of milliseconds, in UTC. As you mention, it is defined as a count of milliseconds since the first moment of 1970 in UTC.

java.time

The java.time classes separate clearly the concepts of UTC, zoned, and unzoned values.

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

Instant instant = Instant.now() ;  // Capture current moment in UTC.

Apply a time zone (ZoneId object) to an Instant and you get a ZonedDateTime object. That class replaces the java.util.Calendar class.

ZoneId z = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;  // Same simultaneous moment as `instant`, but different wall-clock time.

If a value has only an offset-from-UTC but not a full time zone, use the OffsetDateTime class.

For a date only, without time-of-day and without time zone, use the LocalDate class. This class replaces the java.sql.Date class. Ditto for LocalTime replacing java.sql.Time.

LocalDate xmasDate2018 = LocalDate.of( 2018 , Month.DECEMBER , 25 ) ;

If the zone or offset are unknown or indeterminate, such as "Christmas starts at stroke of midnight on December 25, 2018", use the LocalDateTime class. This class does not represent an actual moment, a specific point on the timeline. This class lacks any concept of time zone or offset. So it can only represent potential moments along a range of about 26-27 hours.

LocalDateTime xmasEverywhere2018 = LocalDateTime.of( xmasDate2018 , LocalTime.MIN ) ;

Or…

LocalDateTime xmasEverywhere2018 = LocalDateTime.of( 2018 , Month.DECEMBER , 25 , 0 , 0 , 0 , 0 ) ;

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.

With a JDBC driver complying with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings or 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.

Comments

0

It does have a concept of time zone, but it is always UTC. When it prints the date therefore there is no problem converting it to the time zone of your computer.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.