PlayHardGoPro
PlayHardGoPro

Reputation: 2933

Converting Date String to ZonedDateTime

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?

Upvotes: 4

Views: 6333

Answers (2)

CryptoFool
CryptoFool

Reputation: 23119

There are other ways of getting a ZonedDateTime than just its static parse() method. Here's how to turn a LocalDateTime into a ZonedDateTime:

ZonedDateTime zoned = dateTime.atZone(ZoneId.of( "America/New_York"));

or if you have a LocalDate:

ZonedDateTime zoned = 
          date.atStartOfDay( ZoneId.of( "America/New_York" ));

I would not use java.util.Calendar or Date. They're junk. I'd either stick with LocalDate or use ZonedDateTime depending on if you need to keep track of time zones or not. This should get you where you want to go either way, I guess, as it sounds like you know what you want to do once you have a ZonedDateTime.

UPDATE: I looked up how to convert a ZoneDateTime to a Calendar:

Calendar calendar = GregorianCalendar.from(zoned);

just in case you hadn't gotten that far and really want to go that way.

Upvotes: 3

rzwitserloot
rzwitserloot

Reputation: 103254

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.

Upvotes: 5

Related Questions