I've figured it out. As you know when we're dealing with Time in Android, we need to pay attention to the different APIs i.e. APIs before API 26 and after that. There are many articles for this topic in Stackoverflow, but generalized, before Android 8 (Oreo, API 26) we need to use the library ThreeTenABP and after Android 8 we need to use java.time.
An implementation looks like this:
private Date getCurrentDate(){
if(Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){
return Date.from(Instant.now());
} else {
AndroidThreeTen.init(this);
return DateTimeUtils.toDate(org.threeten.bp.Instant.now());
}
}
Of course, you can use LocalDateTime
or ZonedDateTime
etc.
Firebase expects Date
object, or you can use the @ServerTimestamp
annotation and provide no parameter in the constructor of your model. Firebase will then create the timestamp when request for saving data comes to it. Like this
//When you provide Date
class SomeClass {
private String someAttribute;
private Date someDate;
...
public SomeClass(String someAttribute, Date someDate, ...){
this.someAttribute = someAttribute;
this.someDate = someDate;
}
}
//When you don't provide Date
class SomeClass {
private String someAttribute;
private @ServerTimestamp Date someDate;
...
public SomeClass(String someAttribute, ...){
this.someAttribute = someAttribute;
...
}
}
(In may case I needed the Date object when I start an activity, but a request to the server may happen even after 2-3 hours. That's why @ServerTimestamp
was inefficient for me.)
The retrieving happens in the same way. Create a model class, or use HashMap
(your choice) but the type must be Date
. It holds almost every kind of information according to date and time (time zone, the time is even up to microseconds etc).
Most of the time, the user wants to see only a date and a time in form of hours:minutes.
You can use DateTimeFormatter
and provide the pattern which you want (there are plenty of standards). In my case I use it in this way:
private String formatDate(Date date){
if(Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.O){
java.time.LocalDateTime ldt = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
java.time.format.DateTimeFormatter dtf = java.time.format.DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
return ldt.format(dtf);
} else {
LocalDateTime ldt = Instant.ofEpochMilli(date.getTime()).atZone(org.threeten.bp.ZoneId.systemDefault()).toLocalDateTime();
DateTimeFormatter dtf = DateTimeFormatter.ofPattern("dd-MM-yyyy HH:mm");
return ldt.format(dtf);
}
}
As you see the method expects a Date
object (what you retrieve from Firebase). Then it will remove most of the irrelevant data (in my case) and return you only the date and the time in the specified format.
(Note: in this post where UPDATE 2020/01/17 is, a colleague points that with Android Studio 4.0 we can use Java 8 in older APIs as well (like in my case - API 21), but I didn't dig into the topic concrete. You can check it also :)