I'm writing an app for android. On the start of it I create a Calendar, filling such containers as YEAR, MONTH, DAY_OF_MONTH, ERA and time zone as GMT.
I get something like this
java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=false,lenient=true,zone=java.util.SimpleTimeZone[id=GMT,offset=0,dstSavings=3600000,useDaylight=false,startYear=0,startMode=0,startMonth=0,startDay=0,startDayOfWeek=0,startTime=0,startTimeMode=0,endMode=0,endMonth=0,endDay=0,endDayOfWeek=0,endTime=0,endTimeMode=0],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2021,MONTH=3,WEEK_OF_YEAR=?,WEEK_OF_MONTH=?,DAY_OF_MONTH=14,DAY_OF_YEAR=?,DAY_OF_WEEK=?,DAY_OF_WEEK_IN_MONTH=?,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=?,ZONE_OFFSET=?,DST_OFFSET=?]
Later on I need to get a string like "14-04-2021", so I create a Date variable using getTimeInMillies for the Calendar before. All the fields of it become filled with zeros.
After parsing a JSON, I need to create a map with Calendar keys. It looks like this.
String key = keys.next();
Date d = dateFormat.parse(key);
String rate = String.valueOf(rates.getJsonObject(key).get(get_curr_inf(get_curr_to_r())));
Double rate_ = Double.parseDouble(rate);
Calendar cal = new GregorianCalendar();
cal.setTime(d);
Calendar tmp = new GregorianCalendar(cal.get(Calendar.YEAR), cal.get(Calendar.MONTH), cal.get(Calendar.DAY_OF_MONTH));
tmp.setTimeZone(TimeZone.getTimeZone("GMT"));
tmp.set(Calendar.ERA, 1);
long f = tmp.getTimeInMillis();
data.put(tmp, rate_);
I do it in such a strange way as it needs to be exactly similar to the previous Calendar, cause i parse map using it.
Is there any way to make it look better?
java.time
The first answer is to change your map to use
LocalDate
as key instead ofCalendar
. TwoLocalDate
objects denoting the same day will always be equal and produce the same hash code, so are ideal as map keys. Follow the answer by Basil Bourque.The second answer, if for some reason you cannot change the type of the map keys, you can still produce an old-fashioned
Calendar
object more nicely using java.time, the modern Java date and time API.I used this formatter:
And output is:
java.util.GregorianCalendar[time=1618358400000,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=2,minimalDaysInFirstWeek=4,ERA=1,YEAR=2021,MONTH=3,WEEK_OF_YEAR=15,WEEK_OF_MONTH=3,DAY_OF_MONTH=14,DAY_OF_YEAR=104,DAY_OF_WEEK=4,DAY_OF_WEEK_IN_MONTH=2,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=0,ZONE_OFFSET=0,DST_OFFSET=0]
It is not completely equal to the result you had, so will not be compatible with
Calendar
objects produced your old way. One difference is that all fields are set. java.time cannot produce aCalendar
with only selected fields set as you had before. The other difference could be eliminated: my time zone is UTC instead of GMT. In practice they are the same. To get GMT, useZoneId.of("GMT")
instead ofZoneOffset.UTC
.So if you can enforce that now all map keys are produced in the new way, I should say that you are set.
Question: Doesn’t java.time require Android API level 26?
java.time works nicely on both older and newer Android devices. It just requires at least Java 6.
org.threeten.bp
with subpackages.Links
java.time
was first described.java.time
to Java 6 and 7 (ThreeTen for JSR-310).