Videos
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.
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?
- Java SE 8, Java SE 9, and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6 and Java SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android bundle implementations of the java.time classes.
- For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….
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.
Gotcha: passing 2 as month may give you unexpected result: in Calendar API, month is zero-based. 2 actually means March.
I don't know what is an "easy" way that you are looking for as I feel that using Calendar is already easy enough.
Remember to use correct constants for month:
Date date = new GregorianCalendar(2014, Calendar.FEBRUARY, 11).getTime();
Another way is to make use of DateFormat, which I usually have a util like this:
public static Date parseDate(String date) {
try {
return new SimpleDateFormat("yyyy-MM-dd").parse(date);
} catch (ParseException e) {
return null;
}
}
so that I can simply write
Date myDate = parseDate("2014-02-14");
Yet another alternative I prefer: Don't use Java Date/Calendar anymore. Switch to JODA Time or Java Time (aka JSR310, available in JDK 8+). You can use LocalDate to represent a date, which can be easily created by
LocalDate myDate =LocalDate.parse("2014-02-14");
// or
LocalDate myDate2 = new LocalDate(2014, 2, 14);
// or, in JDK 8+ Time
LocalDate myDate3 = LocalDate.of(2014, 2, 14);
tl;dr
LocalDate.of( 2014 , 2 , 11 )
If you insist on using the terrible old java.util.Date class, convert from the modern java.time classes.
java.util.Date // Terrible old legacy class, avoid using. Represents a moment in UTC.
.from( // New conversion method added to old classes for converting between legacy classes and modern classes.
LocalDate // Represents a date-only value, without time-of-day and without time zone.
.of( 2014 , 2 , 11 ) // Specify year-month-day. Notice sane counting, unlike legacy classes: 2014 means year 2014, 1-12 for Jan-Dec.
.atStartOfDay( // Let java.time determine first moment of the day. May *not* start at 00:00:00 because of anomalies such as Daylight Saving Time (DST).
ZoneId.of( "Africa/Tunis" ) // Specify time zone as `Continent/Region`, never the 3-4 letter pseudo-zones like `PST`, `EST`, or `IST`.
) // Returns a `ZonedDateTime`.
.toInstant() // Adjust from zone to UTC. Returns a `Instant` object, always in UTC by definition.
) // Returns a legacy `java.util.Date` object. Beware of possible data-loss as any microseconds or nanoseconds in the `Instant` are truncated to milliseconds in this `Date` object.
Details
If you want "easy", you should be using the new java.time package in Java 8 rather than the notoriously troublesome java.util.Date & .Calendar classes bundled with Java.
java.time
The java.time framework built into Java 8 and later supplants the troublesome old java.util.Date/.Calendar classes.
Date-only

A LocalDate class is offered by java.time to represent a date-only value without any time-of-day or time zone. You do need a time zone to determine a date, as a new day dawns earlier in Paris than in Montréal for example. The ZoneId class is for time zones.
ZoneId zoneId = ZoneId.of( "Asia/Singapore" );
LocalDate today = LocalDate.now( zoneId );
Dump to console:
System.out.println ( "today: " + today + " in zone: " + zoneId );
today: 2015-11-26 in zone: Asia/Singapore
Or use a factory method to specify the year, month, day.
LocalDate localDate = LocalDate.of( 2014 , Month.FEBRUARY , 11 );
localDate: 2014-02-11
Or pass a month number 1-12 rather than a DayOfWeek enum object.
LocalDate localDate = LocalDate.of( 2014 , 2 , 11 );
Time zone

A LocalDate has no real meaning until you adjust it into a time zone. In java.time, we apply a time zone to generate a ZonedDateTime object. That also means a time-of-day, but what time? Usually makes sense to go with first moment of the day. You might think that means the time 00:00:00.000, but not always true because of Daylight Saving Time (DST) and perhaps other anomalies. Instead of assuming that time, we ask java.time to determine the first moment of the day by calling atStartOfDay.
Specify 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(!).
ZoneId zoneId = ZoneId.of( "Asia/Singapore" );
ZonedDateTime zdt = localDate.atStartOfDay( zoneId );
zdt: 2014-02-11T00:00+08:00[Asia/Singapore]
UTC

For back-end work (business logic, database, data storage & exchange) we usually use UTC time zone. In java.time, the Instant class represents a moment on the timeline in UTC. An Instant object can be extracted from a ZonedDateTime by calling toInstant.
Instant instant = zdt.toInstant();
instant: 2014-02-10T16:00:00Z
Convert
You should avoid using java.util.Date class entirely. But if you must interoperate with old code not yet updated for java.time, you can convert back-and-forth. Look to new conversion methods added to the old classes.
java.util.Date d = java.util.from( instant ) ;
…and…
Instant instant = d.toInstant() ;

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.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.
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. Hibernate 5 & JPA 2.2 support java.time.
Where to obtain the java.time classes?
- Java SE 8, Java SE 9, Java SE 10, Java SE 11, and later - Part of the standard Java API with a bundled implementation.
- Java 9 brought some minor features and fixes.
- Java SE 6 and Java SE 7
- Most of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
- Later versions of Android (26+) bundle implementations of the java.time classes.
- For earlier Android (<26), a process known as API desugaring brings a subset of the java.time functionality not originally built into Android.
- If the desugaring does not offer what you need, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above) to Android. See How to use ThreeTenABP….
UPDATE: The Joda-Time library is now in maintenance mode, and advises migration to the java.time classes. I am leaving this section in place for history.
Joda-Time
For one thing, Joda-Time uses sensible numbering so February is 2 not 1. Another thing, a Joda-Time DateTime truly knows its assigned time zone unlike a java.util.Date which seems to have time zone but does not.
And don't forget the time zone. Otherwise you'll be getting the JVM’s default.
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Singapore" );
DateTime dateTimeSingapore = new DateTime( 2014, 2, 11, 0, 0, timeZone );
DateTime dateTimeUtc = dateTimeSingapore.withZone( DateTimeZone.UTC );
java.util.Locale locale = new java.util.Locale( "ms", "SG" ); // Language: Bahasa Melayu (?). Country: Singapore.
String output = DateTimeFormat.forStyle( "FF" ).withLocale( locale ).print( dateTimeSingapore );
Dump to console…
System.out.println( "dateTimeSingapore: " + dateTimeSingapore );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "output: " + output );
When run…
dateTimeSingapore: 2014-02-11T00:00:00.000+08:00
dateTimeUtc: 2014-02-10T16:00:00.000Z
output: Selasa, 2014 Februari 11 00:00:00 SGT
Conversion
If you need to convert to a java.util.Date for use with other classes…
java.util.Date date = dateTimeSingapore.toDate();