I have method to find month end date based on the timezone.
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("CET"));
calendar.set(
Calendar.DAY_OF_MONTH,
calendar.getActualMaximum(Calendar.DAY_OF_MONTH)
);
System.out.println(calendar.getTime());`
It displays output: Thu Aug 30 18:04:54 PDT 2018
.
It should, however, give me an output in CET.
What am I missing?
The
Calendar.getTime()
method returns a Date object, which you then printed in your code. The problem is that theDate
class does not contain any notion of a timezone even though you had specified a timezone with theCalendar.getInstance()
call. Yes, that is indeed confusing.Thus, in order to print a
Date
object in a specific timezone, you have to use the SimpleDateFormat class, where you must callSimpleDateFormat.setTimeZone()
to specify the timezone before you print.Here's an example:
Here is the output on my computer:
This is because Date object doesn't have timezone as part of its state, and
getTime()
actually returns a date which corresponds to the JVM's timezone, instead you need SimpleDateFormat to format and print the date in your required timezone.If you try adding the following line of code, you could see that the timezone in the calendar is actually CET.
tl;dr
java.time
You are using the terrible old
Calendar
class that was supplanted years ago but the modern java.time classes.LocalDate
If you need only a date, use
LocalDate
class. Then the time zone is irrelevant for your output.But time zone is very relevant for determining the current date. For any given moment, the date varies around the globe by zone.
Specify a proper time zone name in the format of
continent/region
, such asAmerica/Montreal
,Africa/Casablanca
, orPacific/Auckland
. Never use the 3-4 letter abbreviation such asCET
orIST
as they are not true time zones, not standardized, and not even unique(!).YearMonth
Get the month for that date. Represent a year-month with, well,
YearMonth
.Or skip the
LocalDate
.Get the end of the month.
ISO 8601
To generate a
String
representing thatLocalDate
object’s value, calltoString
. The default format is taken from the ISO 8601 standard. For a date-only value that will be YYYY-MM-DD such as2018-01-23
.If you need another format, use
DateTimeFormatter
class. Search Stack Overflow for many examples and discussions.Moment
If you need a moment, you can add a time-of-day and time zone to your
LocalDate
to get aZonedDateTime
. Or letZonedDateTime
determine the first moment of the day (which is not always 00:00:00!).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.