I'm receiving a query parameter date, as yyyy-MM-DD (2022-03-08)
.
I want to conver this to java.util.Calendar
/ java.util.GregorianCalendar
formmat.
So my idea is converto: String -> ZonedDateTime -> Calendar.
What I did:
ZonedDateTime parsedDate = ZonedDateTime.parse(date, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
//date = 2022-03-08
even with the correct format, I'm getting:
Text '2022-03-08' could not be parsed: Unable to obtain ZonedDateTime from TemporalAccessor: {},ISO resolved to 2022-03-08 of type java.time.format.Parsed
I found out that this error occurs because my string does not have a TimeZone.
One suggestion was to use LocalDate
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/yyyy");
LocalDate date = LocalDate.parse(fecha, formatter);
but I can't use localDate
as an argument for ZonedDateTime.parse()
.
What else could I try?
I want to conver this to java.util.Calendar / java.util.GregorianCalendar formmat.
That seems silly; Calendar/GregorianCalendar is obsolete, and the API is horrendous. Why use a broken screwdriver when there's a shiny new one right there in the toolbox? Don't do this.
So my idea is converto: String -> ZonedDateTime -> Calendar.
That seems silly. The string does not contain a ZonedDateTime
. It doesn't even contain a LocalDateTime
. It is clearly a LocalDate
. So, convert it to a localdate, and you go from there.
The power of the java.time
package is that each different concept in time has a matching type in the j.t package that is properly named. For example, java.util.Date
is a lie: It is a timestamp, and it has nothing whatsoever to do with dates; asking a Date object for 'what year is it', is broken (try it, you get a warning).
Calendar, similarly, is an utter falsehood. It does not represent a calendar at all; it, too, represents a timestamp.
LocalDate
on the other hand is perfect truth: It represents a date (not a time), and it does not include timezone or other localizing information: It makes sense only as 'locally'.
Each stop should just make sense, on its own:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd");
LocalDate date = LocalDate.parse("2022-10-01", formatter);
So far, so good. I'd just stop there - why lie? Why return a Calendar which is both API wise a lie (that class does not represent calendars), and even if someone knows exactly what Calendar is, it's still a lie: A calendar implies it has exact time and a timezone. You do not have a time, and also don't have a timezone. Why return something that suggests stuff that isn't there?
But, if you MUST, then explicitly add a timezone and a time, and THEN go for it:
ZonedDateTime zdt = someLocalDate.atStartOfDay().atZone(ZoneId.of("Europe/Amsterdam"));
GregorianCalendar gc = GregorianCalendar.from(zdt);
This code is clear and legible: It makes crystal clear that the code picks a time, and picks a zone.
But, again, now you ended up with a horrible, horrible object you should not be using, for anything.