venky
venky

Reputation: 422

Why does the Date class object prints today's date instead of reference of Date class

When we create an object, the object will have the reference of the data members and methods of a class.

 For Eg: TestObject obj = new TestObject();
         System.out.println("Test Object is:"+obj);

As per my knowledge, what new operator does is, it creates/ allocates the memory blocks for the specified class(variables and methods) and assigns that reference to the left hand variable (obj). So, the above print statement prints the reference of the TestObject class.

But, my question is, when we create an object for Date class and print the object, it prints the today's date.

 For eg: Date date = new Date();
         System.out.println("Date Object is:"+date);

The above code prints the today's date. why and how it is printing the date instead of Date class reference. Please help me.

Am sorry, if this is a silly question. Even this is silly, I don't have the answer for this question.

Brief explanation would be appreciable.

Upvotes: 1

Views: 220

Answers (4)

Basil Bourque
Basil Bourque

Reputation: 338604

As the other answers correctly stated, all classes in Java have a toString method inherited from the super-parent class Object.

Every Class Should Override "toString"

If the programmer of a particular class chooses to not override the toString method with her own implementation, her class inherits the default implementation. That default implementation outputs the variable reference information you described. As the Object class doc states, you effectively get this…

getClass().getName() + '@' + Integer.toHexString(hashCode())

What exactly should go into an override implementation of toString? The Sun/Oracle documentation says…

In general, the toString method returns a string that "textually represents" this object. The result should be a concise but informative representation that is easy for a person to read. It is recommended that all subclasses override this method.

The Debate

Many programmers have debated what exactly should be implemented in toString. The catch is that toString is used in various contexts. When programming, we call that method with System.out.println to dump values to the console for debugging. Another context is logging, recording values during extended testing. Or we might do such logging during production. Yet another context is generating a string for display in the user interface for messages or error reporting.

Some programmers have argued that objects should have multiple such methods, to suit each of these various purposes. But in Java, all we have built-in to every object is the single such method, toString. Do with it what you want.

java.util.Date — The Wrong Way to Implement "toString"

The designers of the java.util.Date class decided their implementation of toString would take the value of a Date, which actually has no time zone information, then apply the JVM’s default time zone to output the date-time in a wacky awkward format.

One of the bad things about that format is the use of a three-letter time zone code. Unfortunately such codes are neither standardized nor unique, there are common duplicates such as IST for Irish Standard Time and Indian Standard Time. Avoid these 3-letter codes, and instead use proper time zone names.

The worst thing about java.util.Date's toString is that it creates the very confusing impression that a Date has a time zone when if fact it does not. This confusion creates an endless stream of duplicate questions here on StackOverflow and elsewhere. So java.util.Date is a great case-study in how to not write a toString implementation.

Fortunately, after a very long wait, the old java.util.Date & java.util.Calendar classes will be supplanted by the new java.time.* package in Java 8. This package is defined by JSR 310 and inspired by Joda-Time.

Joda-Time – The Right Way to Implement "toString"

Joda-Time is a popular replacement for the bundled java.util.Date/Calendar classes. Joda-Time as an open-source free-of-cost library.

The implementation of a DateTime object in Joda-Time uses a built-in formatter based on the ISO 8601 format. That ISO format is a good one for many reasons. One reason is that the standard is clear and precise. Another is that the format is intuitive, where regardless of cultural norms anyone around the globe can determine its meaning. Another nicety is that being a single continuous string with no spaces makes handling and parsing it in programming easier, though technically the "T" in the middle is optional (but strongly encouraged). The time zone information is included, but using an unambiguous offset of hours and minutes rather than a 3-letter code.

All in all, this is a very good example of how to implement toString.

Example Code in Joda-Time 2.3

java.util.Date date = new java.util.Date();

Generally better to specify a time zone than rely on default.

DateTimeZone timeZone = DateTimeZone.forID( "Asia/Kolkata" ); // Formerly known as Calcutta, India. 

Convert that Date object to a Joda-Time DateTime object. Or you could create a fresh DateTim from scratch.

DateTime dateTime_India = new DateTime( date, timeZone ); // Or… new DateTime( timeZone );

If need be, you can convert to UTC/GMT (no time zone offset) by creating another instance based on the first instance. Joda-Time generally follows the immutable object design. Generate a new object, similar to the original but adjusting some aspect such as the time zone offset.

DateTime dateTime_UtcGmt = dateTime_India.toDateTime( DateTimeZone.UTC ); 

Dump to console, using default implementation of "toString" that uses a built-in formatter using ISO 8601 format. Know that Joda-Time offers rich facilities for outputting many different formats of string representations of date-times, but the point here is the default, the implementation of "toString". Each of these println lines implicitly calls the object's toString method.

System.out.println( "date: " + date );
System.out.println( "timeZone: " + timeZone );
System.out.println( "dateTime_India: " + dateTime_India );
System.out.println( "dateTime_UtcGmt: " + dateTime_UtcGmt );

When run…

date: Thu Feb 06 00:17:19 PST 2014
timeZone: Asia/Kolkata
dateTime_India: 2014-02-06T13:47:19.796+05:30
dateTime_UtcGmt: 2014-02-06T08:17:19.796Z

Upvotes: 1

Abimaran Kugathasan
Abimaran Kugathasan

Reputation: 32468

When you use a reference of an instance to print, internally, it's called toString() method of the class. In Date class, toString() method return whatever the date it contains.

Date api's toString() methods says,

Converts this Date object to a String of the form:
 dow mon dd hh:mm:ss zzz yyyy

If you override the toString() method in your class meaningfully, whatever return from that will be printed instead of reference memory value.

Upvotes: 4

user180100
user180100

Reputation:

Because of the toString() implementation in Date, check out java.util.Date source code (link to openjdk7 implementation)

Javadoc quote:

Converts this Date object to a String of the form:

dow mon dd hh:mm:ss zzz yyyy

Upvotes: 2

Ruchira Gayan Ranaweera
Ruchira Gayan Ranaweera

Reputation: 35557

Because of the toString() of Date() class.

  public String toString() {
    // "EEE MMM dd HH:mm:ss zzz yyyy";
    BaseCalendar.Date date = normalize();
    StringBuilder sb = new StringBuilder(28);
    int index = date.getDayOfWeek();
    if (index == gcal.SUNDAY) {
        index = 8;
    }
    convertToAbbr(sb, wtb[index]).append(' ');                        // EEE
    convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' ');  // MMM
    CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd

    CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':');   // HH
    CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
    CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
    TimeZone zi = date.getZone();
    if (zi != null) {
        sb.append(zi.getDisplayName(date.isDaylightTime(), zi.SHORT,Locale.US)); 
       // zzz
    } else {
        sb.append("GMT");
    }
    sb.append(' ').append(date.getYear());  // yyyy
    return sb.toString();
}

Upvotes: 1

Related Questions