Unable to obtain LocalDate from TemporalAccessor using quarters - java

I am trying to parse some date-string into a date value, however, using the below code, I am getting an exception:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("Q'Q'uuuu - MMM");
String d = "3Q2016 - Aug";
System.out.println(LocalDate.parse(d, formatter));
The exception is below
java.time.format.DateTimeParseException: Text '3Q2016 - Aug' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {MonthOfYear=8, QuarterOfYear=3, Year=2016},ISO of type java.time.format.Parsed
Looking at the exception, I see the correct data, but it is not able to be parsed for some reason.
Other similar topics i see suggest using LocalDate or LocalDateTime, but neither work.

Its because the specified string does not have a specific date to select. You probably need to use YearMonth instead of LocalDateTime and then convert it using YearMonth.atDay(1) to get the first day of the month.

As said in this answer, you need to specify a day to be able to parse to a LocalDate. So one solution is to parse to a YearMonth instead and convert to a LocalDate by specifying a day afterwards.
Or you create a DateTimeFormatter with a fixed day in the first place:
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.appendPattern("Q'Q'uuuu - MMM")
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
.toFormatter(Locale.US);
String d = "3Q2016 - Aug";
System.out.println(LocalDate.parse(d, formatter));
I used toFormatter(Locale.US) to make the example work in all environments. In an environment where the input string matches the current locale, you can use toFormatter() instead.

Try adding a Time part to the date -
String str = "2Q1986 - Apr - 08 T00:00";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("Q'Q'yyyy - MMM - dd 'T'hh:mm");
LocalDate dateTime = LocalDate.parse(str, formatter);

Related

String Month-Year to Local Date

I am trying to parse some date-string into a date value, however, using the below code, I am getting an exception:
My Code
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ofPattern("MMMM-YYYY"))
.toFormatter(Locale.ENGLISH);
LocalDate KFilter = LocalDate.parse("August-2021", formatter);
The error log is
java.time.format.DateTimeParseException: Text 'August-2021' could not be parsed:
Unable to obtain LocalDate from TemporalAccessor: {WeekBasedYear[WeekFields[SUNDAY,1]]=2021, MonthOfYear=8},
ISO of type java.time.format.Parsed
Can you please help me out on the same ?
DateTimeFormatter formatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.append(DateTimeFormatter.ofPattern("MMMM-uuuu"))
.toFormatter(Locale.ENGLISH);
LocalDate kFilter = YearMonth.parse("August-2021", formatter).atDay(1);
System.out.println(kFilter);
Output:
2021-08-01
What went wrong in your code?
There are two problems with your code:
Format pattern strings are case sensitive. Upper case YYYY is for week-based year and only useful with a week number. Use either lower case yyyy or uuuu.
Month and year do not define a date, so you cannot readily parse them into a LocalDate. I suggest you parse into a YearMonth and then convert. In the conversion you need to decise on a day of month. An alternative would be specifying a day of month through DateTimeFormatterBuilder.parseDefaulting().
Links
Related questions:
Difference between year-of-era and week-based-year?
uuuu versus yyyy in DateTimeFormatter formatting pattern codes in Java?
Java DateTimeFormatterBuilder with optional pattern results in DateTimeParseException

How to Parse Any Datetime format to yyyy-MM-dd in java

I have a date field that is populated dynamically, and I need that field in the format yyyy-MM-dd
For a input date of format 1994-08-01 14:37:44 this is giving a Exception
java.time.format.DateTimeParseException: Text '1994-08-01 14:37:44' could not be parsed, unparsed text found at index 10
This is one of the many other ways I tried LocalDateTime.parse("1994-08-01 14:37:44",DateTimeFormatter.ofPattern(yyyy-MM-dd));
Is there a way to convert all date/datetime to yyyy-MM-dd format?
please help
Thanks
You have a date and time component but you're only using a date format to parse it to a LocalDateTime value, this will fail because LocalDateTime needs the time component in order to work
Start by parsing the full text
String input = "1994-08-01 14:37:44";
LocalDateTime ldt = LocalDateTime.parse(input, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
Then use a DateTimeFormatter to format it the way you want
String formatted = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(ldt);
System.out.println(formatted);
which prints
1994-08-01
Depending on your needs, you could also convert the LocalDateTime value to a LocalDate and format it, it's the same result, but you might have need of the LocalDate for other things, who knows...
String formatted = ldt.toLocalDate().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
Try it like this. You can extract the LocalDate part.
LocalDate ldt = LocalDateTime.parse("1994-08-01 14:37:44",
DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
System.out.println(ldt.format(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
Prints
1994-08-01

LocalDate DateTimeFormatter problems

I have read the manuals and I'm completely at a loss as to why this code does not work.
// Date Entered must be valid
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy")
.withResolverStyle(ResolverStyle.STRICT);
try {
String dateEntered = lossDateMonth + "/" + lossDateDay + "/" + lossDateYear; // Slash to match UI
System.out.println(dateEntered);
LocalDate dateParsed = LocalDate.parse(dateEntered, dateTimeFormatter);
The println statement prints: 07/29/2015
The last line throws an exception:
java.time.format.DateTimeParseException: Text '07/29/2015' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {YearOfEra=2015, DayOfMonth=29, MonthOfYear=7},ISO of type java.time.format.Parsed
I read the manual on this and it says this sort of thing happens if you try to resolve a date that does not exist, for example September 31st. Even in the error, the parser seems to understand that I am asking about July 29, 2015, so what am I doing wrong here?
Replace the pattern "MM/dd/yyyy" by "MM/dd/uuuu". Have a look in DateTimeFormatter and IsoChronology. The problem is that when using .withResolverStyle(ResolverStyle.STRICT) the formatter expects an unique identifier to the year which is provided by uuuu where yyyy is the year of era. This is to strictly validate the values. The uniqueness is given by the fact that uuuu can be negative.
Have a look here, here and here for related posts.

"... is not public in org.bp.threeten.format.DateTimeFormatter" error when trying to turn String to LocalDate

I'm trying to turn a String into LocalDate using this code:
String end = sharedPref.getString("endDate", "Not available");
DateTimeFormatter formatter = new DateTimeFormatter("yyyy-MM-dd");
LocalDate endDate = LocalDate.parse(end, formatter);
But it shows the error mentioned in the title. How do I fix it?
If there's a better way I'm open to suggestions
There are no constructor which took a format String, instead you have to call the static method ofPattern like so :
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
You don't need an explicit formatter at all in your case.
LocalDate endDate = LocalDate.parse(end);
Just drop the declaration of formatter. The format that you are trying to parse agrees with ISO 8601. LocalDate parses this format as its default, that is, without the formatter.
For the explanation of what went wrong, see the answer by YCF_L.
Link: ISO 8601.

Getting "parse exception"

I want to change the string into the date formate for that I am using SimpleDateFormat class. I am passing the string as String+Integer.toString(int) from list of strings and SimpleDateFormat pattern as an inputs.
Note: Instead of String+Integer.toString(int) if I pass actual string like "Jan 09 2019" successfully convert string into the date. I tried a lot with different things.
dateList is a list of "MMM dd" formate dates.
Adding year on that formate by doing dateList.get(5)+Integer.toString(year) which is giving me parse exception <<-- Instead of this if I hardcode the date like Jan 09 2019 converting string into the date.
finalDatesInMMMDDYYYYFormat is another list where I am saving the dates in MMM dd yyyy format.
Utils.parseDate is a method I wrote in Utils class where I mentioned try-catch block.
int year = 2019;
private List<String> dateList = new ArrayList<>();
private List<Date> finalDatesInMMMDDYYYYFormat = new ArrayList<>();
final String testString = dateList.get(5)+Integer.toString(year);
finalDatesInMMMDDYYYYFormat.add(Utils.parseDate(testString, new SimpleDateFormat("MMM dd yyyy")));
Expected: Change the string into the date and add it to finalDatesInMMMDDYYYYFormat
Actual: Getting parse exception.
java.time
int year = 2019;
DateTimeFormatter dateFormatter = new DateTimeFormatterBuilder()
.parseCaseInsensitive()
.appendPattern("MMM dd")
.toFormatter(Locale.ENGLISH);
List<LocalDate> finalDatesWithoutFormat = new ArrayList<>();
String dateString = "JAN 09";
MonthDay md = MonthDay.parse(dateString, dateFormatter);
finalDatesWithoutFormat.add(md.atYear(year));
System.out.println(finalDatesWithoutFormat);
The output from this snippet is:
[2019-01-09]
java.time, the modern Java date and time API, includes a class for a date without year, MonthDay, which may serve your purpose better than an ordinary date. My code also shows how to supply a year to obtain a LocalDate (a date without time of day).
I recommend you don’t use Date and SimpleDateFormat. Those classes are poorly designed and long outdated, the latter in particular notoriously troublesome.
What went wrong in your code?
From the information you have provided it’s not possible to tell why your code didn’t work. Possible explanations include the following, but there might be others.
As rockfarkas said in another answer, when concatenating your strings you were not putting any space between day of month and year, but the format string you used for parsing required a space there.
If your month abbreviations are in English, for example, and your JVM’s default locale is not English, parsing will fail (except in the rare cases where the month abbreviation coincides). You should always give your formatter a locale to specify the language used in the string to be parsed (or produced).
As an aside, your variable name finalDatesInMMMDDYYYYFormat was misleading since a Date hasn’t got (cannot have) a format.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Another example of wrong locale causing date parsing to fail: Java - Unparseable date
If you want parse format "MMM dd yyyy", you should add an extra space to your test string like this:
final String testString = dateList.get(5) + ' ' + year;

Categories