Java Date giving different dates
I need my Java Android app to extract and compare dates, but it's all a mess to get the correct date.
TimeZone timeZone = TimeZone.getTimeZone("GMT");
Calendar calendar = Calendar.getInstance(timeZone);
Date currentTime = calendar.getTime();
Log.i(logtag, "Date currentTime="+currentTime);
String tidspunkt = calendar.get(Calendar.YEAR)+ "." + calendar.get(Calendar.MONTH)+"."+calendar.get(Calendar.DAY_OF_MONTH)+" "+calendar.get(Calendar.HOUR_OF_DAY)+":"+calendar.get(Calendar.MINUTE)+":"+calendar.get(Calendar.SECOND);
Log.i(logtag, "calendar.get(Calendar.YEAR)="+tidspunkt);
String tidspunkt2 = currentTime.getYear()+ "." + currentTime.getMonth()+"."+currentTime.getDay()+" "+currentTime.getHours()+":"+currentTime.getMinutes()+":"+currentTime.getSeconds();
Log.i(logtag, "currentTime.getYear()="+tidspunkt2);
currentTime.setYear(calendar.get(Calendar.YEAR));
currentTime.setMonth((calendar.get(Calendar.MONTH)));
currentTime.setDate(calendar.get(Calendar.DAY_OF_MONTH));
currentTime.setHours(calendar.get(Calendar.HOUR_OF_DAY));
currentTime.setMinutes(calendar.get(Calendar.MINUTE));
currentTime.setSeconds(calendar.get(Calendar.SECOND));
Log.i(logtag, "Date currentTime edited="+currentTime);
String tidspunkt3 = currentTime.getYear()+ "." + currentTime.getMonth()+"."+currentTime.getDay()+" "+currentTime.getHours()+":"+currentTime.getMinutes()+":"+currentTime.getSeconds();
Log.i(logtag, "currentTime.getYear() edited="+tidspunkt3);
Actual time when running: Mon 10th of January 2022, 22:29
Results:
- Date currentTime=Mon Jan 10 22:29:53 GMT+01:00 2022 (correct date)
- calendar.get(Calendar.YEAR)=2022.0.10 21:29:53 (wrong month, wrong hour)
- currentTime.getYear()=122.0.1 22:29:53 (wrong year, wrong month, wrong day)
- Date currentTime edited=Tue Jan 10 21:29:53 GMT+01:00 3922 (wrong year, wrong weekday, wrong hour)
- currentTime.getYear() edited=2022.0.2 21:29:53 (wrong month, wrong day, wrong hour)
I need to save old dates as objects, and then be able to pull the correct year, month number, day number etc from those objects. So I need an object which I can both extract dates from, and set to any old date I need.
Solution 1:
This is why java.util.Date
and java.util.Calendar
are terrible APIs that you should replace with java.time
. Have you read the doc on Date.setYear
? Or seen that Calendar.JANUARY
is 0?
You can use java.time
with Android with desugaring.
Solution 2:
Avoid legacy classes
Never use TimeZone, Calendar, Date. Do not waste your time trying to understand their bizarre behavior. Sun, Oracle, and the JCP community gave up on those classes years ago, and do should you. These terrible classes were years ago supplanted by the modern java.time classes defined in JSR 310.
java.time
Capture the current moment as seen in UTC (an offset of zero).
Instant instant = Instant.now() ;
The Instant
class is a basic building block class with limited features. For more flexibility, convert to either OffsetDateTime
or ZonedDateTime
.
OffsetDateTime odt = instant.atOffset( ZoneOffset.UTC ) ;
ZonedDateTime zdt = instant.atZone( ZoneId.of( "Asia/Tokyo" ) ) ;
Note that all three of these objects here, instant
, odt
, & zdt
, all represent the very same simultaneous moment, the same single point on the time line.
To generate text representing a moment, you are working much too hard. Let DateTimeFormatter
do the heavy lifting.
Locale locale = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.LONG ).withLocale( locale ) ;
String output = zdt.format( f ) ;
An implementation of java.time is built into Android 26+. For earlier Android, the latest tooling provides most of the java.time functionality via “API desugaring”. If that does not work for you, use a back-port of java.time, the ThreeTenABP project.