If you "return date in format dd/MM/yyyy
", it ceases to be a date (a LocalDate
) and becomes a String
. To better understand, below is a - long - explanation.
Dates have no format
A date is just a concept, an idea: it represents a specific point in the calendar.
The date of "March 15, 1990" represents this: the specific point of the calendar, which occurred several years ago, which we agree to call the 15th of March of the year 1990. To express this idea in text form, I can write it in different ways:
- 15/03/1990 (a common format in many countries, including Brazil)
- 3/15/1990 (American format, reversing day and month)
- 1990-03-15 (the format ISO 8601)
- 15 March 1990 (in good Portuguese)
- March 15th, 1990 (in English)
- 1990 年 3 月 15 日 (in Japanese)
- and many others...
Note that each of the above formats is different, but all represent the same date (the same numerical values of the day, month and year).
Similarly, in Java we have the class LocalDate
, implementing the concept of a specific date (a specific day, month and year), and we have the String
, which may contain a text representing a date (any of the above formats, and any other you want).
A LocalDate
, by itself, it has no specific format. Internally, this class has only 3 numerical values: the day, month and year.
When you print one LocalDate
(be it with System.out.println
, with a log API, or even seeing its value in a Debugger), internally is called the method toString()
, which returns the day, month and year values formatted in a String
. In the case of the API java.time
, chose to return this String
in the ISO 8601 format (so the date is shown as 1990-03-15
).
That is, in doing System.out.println(dt1)
, you see the return of the method toString()
, which returns the date values in a specific format (in a String
). But that doesn’t mean that the LocalDate
is in that format. In fact, it is not in any format, because it even has a.
Just to illustrate:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu");
LocalDate dt1 = LocalDate.parse("15/03/1990", formatter);
System.out.println(dt1); // 1990-03-15
LocalDate dt2 = LocalDate.of(1990, 3, 15);
System.out.println(dt2); // 1990-03-15
System.out.println(dt1.equals(dt2)); // true
The first date (dt1
) was created from a String
. Like this String
represents a date in the "day/month/year" format, I used the DateTimeFormatter
with this format and made the parse
to obtain the LocalDate
. So now dt1
corresponds to "March 15, 1990".
But internally dt1
does not have any format. It has only numeric values (day 15, month 3 and year 1990). dt1
does not know that these values came from a String
(who made this match between what was in the String
and the numerical values was the DateTimeFormatter
).
Of course, when printing dt1
, it has to be shown somehow, and your method toString()
ends up showing in the ISO 8601 format. But that doesn’t mean dt1
is in that format.
Already dt2
was created using the numerical values directly. It also has only the values, and has no information as to the format. So much so that dt1
and dt2
are equal (correspond to the same date - same point in the calendar - their numerical values of the day, month and year are equal): see in the last line that dt1.equals(dt2)
prints true
.
Therefore, you must decide what you need at each point of the code.
If the method setInicioMandato
gets a LocalDate
as a parameter, just pass it directly, without worrying about the format (even because the LocalDate
has no format, only the numerical values of the day, month and year).
If you want to show the date in some different format, then it is the case to convert it to String
, using a DateTimeFormatter
.
Bonus
Just to complement, see what happens if the String
has dates such as 31 April or 29 February in non-leap years:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu");
LocalDate dt1 = LocalDate.parse("31/04/2019", formatter);
System.out.println(dt1); // 2019-04-30
LocalDate dt2 = LocalDate.parse("29/02/2019", formatter);
System.out.println(dt2); // 2019-02-28
April 31 is invalid as April only has 30 days. But 31/04/2019
was accepted and adjusted for April 30. Already 29/02/2019
(which is also invalid as 2019 is not leap year) was adjusted to 28 February.
If you want to avoid these situations and accept only valid dates, just change the java.time.format.ResolverStyle
, using the value STRICT
(as suggested in this answer). With this, invalid dates throw an exception:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu")
.withResolverStyle(ResolverStyle.STRICT);
LocalDate dt1 = LocalDate.parse("31/04/2019", formatter);
The code above tries to do the Parsing of an invalid date, but due to ResolverStyle.STRICT
, he throws an exception:
java.time.format.DateTimeParseException: Text '31/04/2019' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {YearOfEra=2019, MonthOfYear=4, DayOfMonth=31},ISO of type java.time.format.Parsed
Another detail - you may have noticed - is to use uuuu
next year instead of yyyy
. In a very concise way, u
works both for current years and for dates A.C. (Before Christ), accepting negative years, while y
needed era (A.C. or B.C.) to decide whether year is Before or After Christ (in the Parsing we do not see these problems because the era is inferred and for current dates works normally).
Perhaps the use of such old dates is not so common in many applications, but anyway, the use of u
instead of y
is recommended. For more details, see this question in Stack Overflow.