Java 在Firebase中保存和检索日期
我有一个具有以下结构的模型Java 在Firebase中保存和检索日期,java,android,date,firebase,Java,Android,Date,Firebase,我有一个具有以下结构的模型 public class OfferModel { private String mImageUrl; private String mOfferCode; private String mOfferTitle; private String mOfferDescription; private boolean mIsRunning; private String mCreatorUid; private Dat
public class OfferModel {
private String mImageUrl;
private String mOfferCode;
private String mOfferTitle;
private String mOfferDescription;
private boolean mIsRunning;
private String mCreatorUid;
private Date mStartDate;
}
其他一切都能很好地节省开支。它在Firebase实时数据库中保存为
startDate
date: 22
day: 3
hours: 23
minutes: 20
month: 5
seconds: 50
time: 1466617850476
timezoneOffset: -330
year: 116
但当我试图检索它时,日期给出了以下错误-
java.lang.ClassCastException: java.util.HashMap cannot be cast to java.util.Date
at com.localvine.models.OfferModel.<init>(OfferModel.java:37)
at com.localvine.managers.OfferManager$1.onDataChange(OfferManager.java:62)
at com.google.android.gms.internal.zzafp.zza(Unknown Source)
at com.google.android.gms.internal.zzagp.zzSu(Unknown Source)
at com.google.android.gms.internal.zzags$1.run(Unknown Source)
at android.os.Handler.handleCallback(Handler.java:615)
java.lang.ClassCastException:java.util.HashMap不能强制转换为java.util.Date
位于com.localvine.models.OfferModel(OfferModel.java:37)
位于com.localvine.managers.OfferManager$1.onDataChange(OfferManager.java:62)
位于com.google.android.gms.internal.zzafp.zza(未知来源)
位于com.google.android.gms.internal.zzagp.zzSu(未知来源)
位于com.google.android.gms.internal.zzags$1.run(未知来源)
位于android.os.Handler.handleCallback(Handler.java:615)
我知道Firebase不支持Java日期对象,但既然它将它们保存在地图中,我如何从地图中获取日期?Firebase Android中是否有合适的保存和检索日期的方法?您可以将日期存储为纪元日期。使用系统时间
system.currentTimeMillis()可以获得很长的一段时间
或使用Firebase服务器时间及其ServerValue.TIMESTAMP
。第一个选项的问题是,它随时区和系统设置而变化。因此,如果将日期存储为long,只需将OfferModel
字段mStartDate
更改为long
,然后使用新日期(long)
在检索对象时获取相应的日期。这就是我如何在Firebase上存储日期的方法,方法是使用SimpleDataFormat将日期转换为没有秒、小时或毫秒的日期
public void storeDatetoFirebase() {
handler = new Handler();
runnable = new Runnable() {
@Override
public void run() {
handler.postDelayed(this, 1000);
try {
Date date = new Date();
Date newDate = new Date(date.getTime() + (604800000L * 2) + (24 * 60 * 60));
SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd");
String stringdate = dt.format(newDate);
System.out.println("Submission Date: " + stringdate);
DatabaseReference databaseReference = FirebaseDatabase.getInstance().getReference().child("My_Date");
databaseReference.child("init_date").setValue(stringdate);
} catch (Exception e) {
e.printStackTrace();
}
}
};
handler.postDelayed(runnable, 1 * 1000);
}
这就是它在Firebase上的显示方式:
希望对您有所帮助。您可以在Firebase上设置日期对象
yourReference.setValue(new Date());
它是有效的,但是
我注意到了日期的另一个问题,当我从数据库中手动更改月份时,当检索它时,值保持与以前一样尽管firebase支持日期格式数据类型,但我更喜欢以字符串格式保存日期时间,因为将其存储为字符串后,检索它变得非常容易
将当前系统日期时间存储为代码下方的字符串格式即可
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
String strDate = dateFormat.format(date).toString();
myRef.child("datetime").setValue(strDate);
现在,您可以使用strDate存储在firebase中,或者使用该字符串执行任何操作。使用:
SimpleDateFormat ISO_8601_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:sss'Z'");
String now = ISO_8601_FORMAT.format(new Date());
将日期
表示为字符串
有两个更大的优点:
- 它是人类可读的(
“2018-03-30T13:18:39.516Z”
vs1522415925281
)
- 在浏览器端,您只需调用
新日期(“2018-03-30T13:18:39.516Z”)
如果Android和浏览器都使用Firebase数据,这将非常有用 实际上,epoch time是自1970年1月1日UTC以来的秒数;你的建议是使用毫秒数来达到这个目的!但这并不是对这篇文章的回答,而是你们可以评论它:)最干净的方式!他信在我的例子中,模式似乎是yyyy-MM-dd'T'HH:MM:ss.SSS'Z'
请注意,如果这样做,您将禁用执行范围查询的权限。许多数据库将日期存储为毫秒时间格式是有原因的。@OliverDixon,如果我们将时间存储为ISO字符串,您确定范围查询会被禁用吗?我认为它们只是字符串,如果我们将它们视为字符串,它们就具有按正确顺序排序的正确特性。我一直在对ISO日期字符串进行排序,并假设它没有问题。尚未尝试对其进行数据库范围查询,但有限制吗?从API 16开始,数据(java.lang.String)已被弃用。它给了我一个致命的例外:java.lang.IllegalArgumentException位于java.util.Date.parse(Date.java:638)处java.util.Date.(Date.java:274)
!使用ISO日期格式更好,因此与其他系统等进行交互操作将更加轻松。例如2018-12-16T23:03:53Z