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”
    vs
    1522415925281
  • 在浏览器端,您只需调用
    新日期(“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