java 8 datatime parse error - java-8

I am trying to convert a string to LocalDate object. but I get the following error.
private LocalDate getLocalDate(String year) {
String yearFormatted = "2015-01-11";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("YYYY-MM-dd");
LocalDate dateTime = LocalDate.parse(yearFormatted, formatter);
return dateTime;
}
here is the error
Caused by: java.time.format.DateTimeParseException: Text '2015-01-11' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {DayOfMonth=11, WeekBasedYear[WeekFields[SUNDAY,1]]=2015, MonthOfYear=1},ISO of type java.time.format.Parsed
at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920) ~[na:1.8.0_102]
at java.time.format.DateTimeFormatter.parse(DateTimeFormatter.java:1855) ~[na:1.8.0_102]
at java.time.LocalDate.parse(LocalDate.java:400) ~[na:1.8.0_102]

As the documentation says, the capital Y in a format pattern is for week-based-year, that is, the year that the week number belongs to. This is not always the same as the calendar year (though most often it is). Java is smart enough to recognize that it cannot be sure to get a date out of week-based year, month and day-of-month, so it throws the exception instead.
Since the format of your string agrees with the default LocalDate format (ISO 8601), the simplest solution is to drop the formatter completely and just do:
LocalDate dateTime = LocalDate.parse(yearFormatted);
With this change, you method returns a date of 2015-01-11 as I think you had expected. Another fix is to replace YYYY with either lowercase yyyy for year-of-era or uuuu for a signed year (where 0 is 1 BC, -1 is 2BC, etc.).

Related

How to format date string with date-fns without timezone transformation?

I have really simple date as string as ISO const mytDate = '2021-10-24T16:00:00.000Z' and I want to format it like format(new Date(myDate), 'yyyy-MM-dd HH:mm:ss') but new Date() cause that it convert it to my local timezone and I do not want it. I would like to take this string date and just format it as it is.
Is there a solution ?
Cheers!

Using Carbon I got "textual month could not be found" error

In my Laravel 5.8 application, I to convert date in string format like
02 May, 2019 to date time using Carbon. I try like :
setlocale(LC_TIME, 'en');
$filter_check_in_datepicker_till = Carbon::createFromFormat( 'dd MMMM YYY', $filter_check_in_datepicker_till )->locale('en_EN');;
But got error:
"message": "Unexpected data found.\nA textual month could not be found\nData missing",
Which is right way?
Thanks!
The Carbon docs say:
createFromFormat() is mostly a wrapper for the base php function DateTime::createFromFormat.
It isn't entirely clear from the docs, but that means the $format parameter passed to createFromFormat() is a DateTime format, not a Carbon format. So instead of dd MMMM YYY, you should use d, M Y (check the DateTime format reference):
\Carbon\Carbon::createFromFormat('d, M Y', '02, May 2019');
// returns 2019-05-02 12:48:26
For reference, there are several problems in your Carbon format, so even if createFromFormat took a Carbon format string what you have would not work. Checking the Carbon format reference:
dd is actually "Minified day name (from Su to Sa), transatable". You really want DD for the zero-padded day of month;
The date format you are using includes a comma, but your format string is missing that;
YYY is not actually a valid Carbon format string. You really wanted YYYY for 4-digit year;

Parsing a year String to a LocalDate with Java8

With Joda library, you can do
DateTimeFormat.forPattern("yyyy").parseLocalDate("2008")
that creates a LocalDate at Jan 1st, 2008
With Java8, you can try to do
LocalDate.parse("2008",DateTimeFormatter.ofPattern("yyyy"))
but that fails to parse:
Text '2008' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {Year=2008},ISO of type java.time.format.Parsed
Is there any alternative, instead of specifically writing sth like
LocalDate.ofYearDay(Integer.valueOf("2008"), 1)
?
LocalDate parsing requires that all of the year, month and day are specfied.
You can specify default values for the month and day by using a DateTimeFormatterBuilder and using the parseDefaulting methods:
DateTimeFormatter format = new DateTimeFormatterBuilder()
.appendPattern("yyyy")
.parseDefaulting(ChronoField.MONTH_OF_YEAR, 1)
.parseDefaulting(ChronoField.DAY_OF_MONTH, 1)
.toFormatter();
LocalDate.parse("2008", format);
String yearStr = "2008";
Year year = Year.parse(yearStr);
System.out.println(year);
Output:
2008
If what you need is a way to represent a year, then LocalDate is not the correct class for your purpose. java.time includes a Year class exactly for you. Note that we don’t even need an explicit formatter since obviously your year string is in the default format for a year. And if at a later point you want to convert, that’s easy too. To convert into the first day of the year, like Joda-Time would have given you:
LocalDate date = year.atDay(1);
System.out.println(date);
2008-01-01
In case you find the following more readable, use that instead:
LocalDate date = year.atMonth(Month.JANUARY).atDay(1);
The result is the same.
If you do need a LocalDate from the outset, greg449’s answer is correct and the one that you should use.
I didn't get you
but from the title I think you want to parse a String to a localdate so this is how you do it
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("d/MM/yyyy");
String date = "16/08/2016";
//convert String to LocalDate
LocalDate localDate = LocalDate.parse(date, formatter);

Java8 Adding Hours To LocalDateTime Not Working

I tried like below, but in both the cases it is showing same time? What i am doing wrong.
LocalDateTime currentTime = LocalDateTime.now(ZoneId.of("UTC"));
Instant instant = currentTime.toInstant(ZoneOffset.UTC);
Date currentDate = Date.from(instant);
System.out.println("Current Date = " + currentDate);
currentTime.plusHours(12);
Instant instant2 = currentTime.toInstant(ZoneOffset.UTC);
Date expiryDate = Date.from(instant2);
System.out.println("After 12 Hours = " + expiryDate);
"Current Date" Time is showing Same as "After 12 Hours"...
The documentation of LocalDateTime specifies the instance of LocalDateTime is immutable, for example plusHours
public LocalDateTime plusHours(long hours)
Returns a copy of this LocalDateTime with the specified number of
hours added.
This instance is immutable and unaffected by this method call.
Parameters:
hours - the hours to add, may be negative
Returns:
a LocalDateTime based on this date-time with the hours added, not null
Throws:
DateTimeException - if the result exceeds the supported date range
So, you create a new instance of LocalDateTime when you execute plus operation, you need to assign this value as follows:
LocalDateTime nextTime = currentTime.plusHours(12);
Instant instant2 = nextTime.toInstant(ZoneOffset.UTC);
Date expiryDate = Date.from(instant2);
System.out.println("After 12 Hours = " + expiryDate);
I hope it can be helpful for you.
From the java.time package Javadoc (emphasis mine):
The classes defined here represent the principal date-time concepts,
including instants, durations, dates, times, time-zones and periods.
They are based on the ISO calendar system, which is the de facto world
calendar following the proleptic Gregorian rules. All the classes are
immutable and thread-safe.
Since every class in the java.time package is immutable, you need to capture the result:
LocalDateTime after = currentTime.plusHours(12);
...
This is simple, you can use
LocalDateTime's method "plusHours(numberOfHours)
Like This
localDateTime.plusHours(numberOfHours);

How to getHourOfDay from a timestamp using java.time?

From a java.util.Date( a timestamp), how can I get the hour of day?
In joda.time I use getHourOfDay().
There are multiple solutions for this. If you wish to use the Java 8 classes from java.time the following you need to covert a Date to one of the DateTime classes. The following can be used to convert a Date to a ZonedDateTime where you then can get the hour:
Date date = new Date();
// Convert to java 8 ZonedDateTime
Date date = new Date();
final ZonedDateTime dateTime = date.toInstant()
.atZone(ZoneId.systemDefault());
// Get the hour
int hour = dateTime.getHour();
Quite verbose as you have noticed but the simple reason for this is that a Date is sort of an Instant
Despite its name, java.util.Date represents an instant on the time-line, not a "date". The actual data stored within the object is a long count of milliseconds since 1970-01-01T00:00Z (midnight at the start of 1970 GMT/UTC).
Another approach is simply to get the field from a Calendar instance.
final Calendar instance = Calendar.getInstance();
instance.setTime(date);
final int hourOfDay = instance.get(Calendar.HOUR_OF_DAY);

Resources