The typical pattern here is a class with only private or package default constructors, combined with a factory method that is either a public static method of the class or a method of an accompanying factory class. You get LocalDate objects from many static methods listed in the javadoc.
The typical pattern here is a class with only private or package default constructors, combined with a factory method that is either a public static method of the class or a method of an accompanying factory class. You get LocalDate objects from many static methods listed in the javadoc.
Use
LocalDate d = LocalDate.now();
to create a LocalDate for now. There are more static methods to instantiate a LocalDate. The designers of the API decided to create static methods to instantiate LocalDates because they can have more clear names on what is actually instantiated (like "now()" above to create a LocalDate for the current date).
Videos
Factory methods allow simplifying the constructors - the difference which instance in time is represented by the Object can be separated from the calculation of the instant.
There are lots of factory methods, some doing String parsing, some converting from some other date or time representation, but all that can happen before the Object has to be created (if creating a new Object is even necessary at all - could also be a cached one).
Another big advantage is that factory methods can have descriptive names: the methods for parsing String representations are named e.g. LocalTime.parse - that is not possible with constructors.
It's not always necessary to create a new object when obtaining a value of an immutable type. A factory method may return an object that has already been created while a constructor call always creates a new object.
There are some other advantages to factory methods, but they're not as closely related to immutability and the Date-Time API. For instance, factory methods have names and they may return objects of some subtype.
So I have a dataclass todoItem
data class TodoItem(
var id : Int,
var title: String,
var createdOn : LocalDate,
var dueDate : LocalDate,
var tags : List<String>,
var description : String
){
constructor(): this(
id = 0,
title = "",
createdOn = LocalDate.parse("2020-01-01"),
dueDate = LocalDate.parse("2020-01-01"),
tags = emptyList(),
description = ""
)
}I am adding these todoItems to my cloud Firestore and when getting them back, I want to convert them into this dataclass again
val firestore_data = user?.let {
Firebase.firestore.collection(it.uid).get()
.addOnSuccessListener { documents ->
for (document in documents) {
val todoItem = document.toObject(TodoItem::class.java)
Log.d("TAG", "$todoItem")
}
}
.addOnFailureListener { exception ->
Log.w("TAG", "Error getting documents: ", exception)
}
}But I am getting the following error
Process: com.umang.reminderapp, PID: 2346
java.lang.RuntimeException: Could not deserialize object. Class java.time.LocalDate does not define a no-argument constructor. If you are using ProGuard, make sure these constructors are not stripped (found in field 'dueDate')How do I resolve this ?
If I understand your requirement correctly, have a look at the LocalDate.parse() methods.
Example:
LocalDate date = LocalDate.parse("1990-01-01", DateTimeFormatter.ofPattern("yyyy-MM-dd"));
int year = date.getYear(); // 1990
Parse Each Number Separately
It’s good to see you using the java.time framework rather than the troublesome old date-time classes. The old java.util.Date/.Calendar classes have been supplanted by the new framework.
The DateTimeFormatter class parses any two digit year as being in the 2000s. From class doc:
If the count of letters is two… will parse using the base value of 2000, resulting in a year within the range 2000 to 2099 inclusive.
To override this behavior, see this Answer by assylias. But that issue may be moot in your case. You already have the individual year, month, and date values isolated. So they need not be parsed together.
I suggest you convert each string into a integer. For the year, if less than 100 then add 1900.
String inputYear = "90";
String inputMonth = "12";
String inputDayOfMonth = "6";
int year = Integer.parseInt( inputYear );
int month = Integer.parseInt( inputMonth );
int dayOfMonth = Integer.parseInt( inputDayOfMonth );
if( year < 100 ) { // If two-digit year, assume the 1900s century. Even better: Never generate two-digit year text!
year = ( year + 1900 );
}
LocalDate localDate = LocalDate.of( year , month , dayOfMonth );
It looks to me as if you have imported the wrong class.
The Java 8 java.time.LocalDate class has no public constructors, but it does have a private constructor that takes three int values. I think this class is what you have imported by mistake, when you wanted org.joda.time.LocalDate instead.
I know that this question is old, but you can just write:
LocalDate date = LocalDate.of(int, int, int);
I hope somebody will find this helpfull.