如何将Firestore时间戳打印为格式化日期和时间

41

我的时间戳在Flutter Firestore快照中返回Timestamp(seconds=1560523991, nanoseconds=286000000)

我希望以正确格式的日期和时间打印它。

我在创建新记录时使用DateTime.now()存储当前日期和时间,并使用Firestore快照检索它,但我无法将其转换为格式化的日期时间。 我正在使用intl.dart库进行格式化。

保存数据的代码:

       d={'amount':amount,
      'desc':desc,
      'user_id':user_id,
      'flie_ref':url.toString(),
      'date':'${user_id}${DateTime.now().day}-${DateTime.now().month}-${DateTime.now().year}',
      'timestamp':DateTime.now()
return Firestore.instance.collection('/data').add(d).then((v){return true;
    }).catchError((onError)=>print(onError));
    });

Accessing with 

    FutureBuilder(
                  future: Firestore.instance
                      .collection('data')
                      .where('user_id', isEqualTo:_user_id)
                      .getDocuments(),
                  builder: (BuildContext context,
                      AsyncSnapshot<QuerySnapshot> snapshot) {
                    if (!snapshot.hasData)
                      return Container(
                          child: Center(child: CircularProgressIndicator()));
                    return ListView.builder(
                        itemCount: snapshot.data.documents.length,
                        itemBuilder: (BuildContext context, int index) {
                          return Column(
                            children: <Widget>[
       Text(DateFormat.yMMMd().add_jm().format(DateTime.parse(snapshot.data.documents[index].data['timestamp'].toString())]);


....

抛出的错误为:

日期格式无效。

我期望的输出是:'2019年1月17日 下午2:19'


1
请参见此处的内容:https://dev59.com/xbPma4cB1Zd3GeqPt6Q0 - Leonard Arnold
4
我需要使用这种方法:snapshot.data.documents[index].data['timestamp'].toDate() - aryan singh
16个回答

49

当我们将DateTime对象推送到Firestore时,它会在内部将其转换为自己的timestamp对象并存储。

从Firestore获取时间戳后将其转换回DateTime的方法:

Firestore的timestamp包含一个名为toDate()的方法,可以将其转换为字符串,然后将该字符串传递给DateTimeparse方法以将其转换回DateTime

DateTime.parse(timestamp.toDate().toString())

16
我认为我们不需要先将timestamp.toDate()转换为字符串再解析字符串以获取实际的DateTime。您可以直接执行timestamp.toDate(),它已经返回了DateTime。 - Ashutosh Singh
“parse”不存在吗?我做了这个 - myDate = DateFormat('dd-MMM-yy ~ HH:mm').format(data['itemDate'].toDate()).toString()。 - Wesley Barnes

26

以下是方法!

Firestore将返回类似于Timestamp(seconds=1560523991, nanoseconds=286000000)的时间戳。

可以解析为

Timestamp t = document['timeFieldName'];
DateTime d = t.toDate();
print(d.toString()); //2019-12-28 18:48:48.364

1
.toDate() 是一个时间戳函数。时间戳是由 Firebase 云 firestore 提供的,而不是默认的 Flutter 材料。您可以尝试通过导入'package:cloud_firestore/cloud_firestore.dart'; 来使用它。 - Bharath
getDateTimeFromTimestamp(int timestampInSeconds) { var date = DateTime.fromMillisecondsSinceEpoch(timestampInSeconds * 1000); return date; } DateTime lastPostedMessageOnDateTime = getDateTimeFromTimestamp(document['timeFieldName'].seconds); 它对我有用。谢谢。 - Kamlesh

9
您可以像这样直接将Firestore时间戳对象转换为DateTime:
DateTime myDateTime = (snapshot.data.documents[index].data['timestamp']).toDate();

这将返回您的Firestore时间戳以dart的DateTime格式。为了转换您的DateTime对象,您可以使用intl包中的DateFormat类。您可以使用获得的DateTime对象来获取所需格式,例如:
DateFormat.yMMMd().add_jm().format(myDateTime);

这段代码会产生如下输出:
Apr 21, 2020 5:33 PM

6

timestamp参数是以秒为单位的时间

String formatTimestamp(int timestamp) {
      var format = new DateFormat('d MMM, hh:mm a');
      var date = new DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
      return format.format(date);
    }

请查看这篇关于intl日期格式的回答,希望对您有所帮助!

为了使formatTimestamp()函数正常运行,我无法获取int类型的数据,而是以Timestamp(seconds=1560523991, nanoseconds=286000000)这种格式获取的数据。 - aryan singh

4

我发现 Ashutosh 的建议提供了更加用户友好的输出。建议使用一个带有静态方法的辅助类来实现这样的功能。

  static convertTimeStamp(Timestamp timestamp) {
    assert(timestamp != null);
    String convertedDate;
    convertedDate = DateFormat.yMMMd().add_jm().format(timestamp.toDate());
    return convertedDate;
  }

Intl 包是使用 DateFormat 必须要的。


2
使用 intl 包:
Timestamp firebaseTimestamp = ...;
var date = firebaseTimestamp.toDate();

var output1 = DateFormat('MM/dd, hh:mm a').format(date); // 12/31, 10:00 PM
var output2 = DateFormat.yMMMd().format(date); // Dec 31, 2000

2

一旦您从Firestore获得了一个时间戳,类似于

Timestamp(seconds=1560523991, nanoseconds=286000000)

您需要将其解析为DateTime类型的对象:

DateTime myDateTime = DateTime.parse(timestamp.toDate().toString());

 print('$myDateTime');

这将会给你一个类似这样的结果:

2020-05-09 15:27:04.074

然后你可以像这样格式化myDateTime:
String formattedDateTime =
          DateFormat('yyyy-MM-dd – kk:mm').format(myDateTime);

print('$formattedDateTime');

这将为您提供:

2020年5月9日 - 15:27


1
Timestamp t = document['time'] // Timestamp(seconds=1624653319,nanoseconds=326000000)
DateTime d = t.toDate();
print(d.toString()); //2021-06-25 18:48:48.364

3
请描述一下您的代码,参考如何回答问题 - a.ak
虽然这段代码可能回答了问题,但是提供关于为什么和/或如何回答问题的额外上下文可以提高其长期价值。 - B001ᛦ

1
即使您向Firestore发送DateTime,也会从Firestore获得Unix时间戳。
您可以使用DateTime.fromMillisecondsSinceEpoch(timestamp * 1000)从Firestore解析DateTime。
DateTime类有两个选项返回字符串。toIso8601String()toString()选择您需要的一个。或者使用例如DateTime.now().hour获取小时并创建自己的输出。
更多信息:请查看https://api.dartlang.org/stable/2.4.0/dart-core/DateTime-class.html

1
我得到的时间戳格式为Timestamp(seconds=1560523991, nanoseconds=286000000),请告诉我如何使用它。 - aryan singh
你试过了吗?我确定我是那样使用它的。不幸的是,我现在无法检查。 - worldpotato
我得到的时间戳是一个对象。 - aryan singh
@aryan singh,请检查我对你的问题的回答。 - CEO tech4lifeapps

1

寻找完美的答案花费了很长时间。 当你从Firestore中获取数据作为时间戳对象并且你确认了这一点,我会建议你使用以下代码:

DateTime fetchedDate = e.data()["deadline"]?.toDate();

使用?.toDate()对我有用,希望对你也有用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接