【问题标题】:Converting timestamp转换时间戳
【发布时间】:2018-11-10 22:25:15
【问题描述】:

我找不到解决方案,我正在从 firebase 获取数据,其中一个字段是时间戳,看起来像这样 -> 1522129071。如何将其转换为日期?

Swift 示例(有效):

func readTimestamp(timestamp: Int) {
    let now = Date()
    let dateFormatter = DateFormatter()
    let date = Date(timeIntervalSince1970: Double(timestamp))
    let components = Set<Calendar.Component>([.second, .minute, .hour, .day, .weekOfMonth])
    let diff = Calendar.current.dateComponents(components, from: date, to: now)
    var timeText = ""

    dateFormatter.locale = .current
    dateFormatter.dateFormat = "HH:mm a"

    if diff.second! <= 0 || diff.second! > 0 && diff.minute! == 0 || diff.minute! > 0 && diff.hour! == 0 || diff.hour! > 0 && diff.day! == 0 {
        timeText = dateFormatter.string(from: date)
    }
    if diff.day! > 0 && diff.weekOfMonth! == 0 {
        timeText = (diff.day == 1) ? "\(diff.day!) DAY AGO" : "\(diff.day!) DAYS AGO"
    }
    if diff.weekOfMonth! > 0 {
        timeText = (diff.weekOfMonth == 1) ? "\(diff.weekOfMonth!) WEEK AGO" : "\(diff.weekOfMonth!) WEEKS AGO"
    }

    return timeText
}

我对 Dart 的尝试:

String readTimestamp(int timestamp) {
    var now = new DateTime.now();
    var format = new DateFormat('HH:mm a');
    var date = new DateTime.fromMicrosecondsSinceEpoch(timestamp);
    var diff = date.difference(now);
    var time = '';

    if (diff.inSeconds <= 0 || diff.inSeconds > 0 && diff.inMinutes == 0 || diff.inMinutes > 0 && diff.inHours == 0 || diff.inHours > 0 && diff.inDays == 0) {
      time = format.format(date); // Doesn't get called when it should be
    } else {
      time = diff.inDays.toString() + 'DAYS AGO'; // Gets call and it's wrong date
    }

    return time;
}

它会返回 waaaaaaaay 关闭的日期/时间。

更新:

String readTimestamp(int timestamp) {
    var now = new DateTime.now();
    var format = new DateFormat('HH:mm a');
    var date = new DateTime.fromMicrosecondsSinceEpoch(timestamp * 1000);
    var diff = date.difference(now);
    var time = '';

    if (diff.inSeconds <= 0 || diff.inSeconds > 0 && diff.inMinutes == 0 || diff.inMinutes > 0 && diff.inHours == 0 || diff.inHours > 0 && diff.inDays == 0) {
      time = format.format(date);
    } else {
      if (diff.inDays == 1) {
        time = diff.inDays.toString() + 'DAY AGO';
      } else {
        time = diff.inDays.toString() + 'DAYS AGO';
      }
    }

    return time;
  }

【问题讨论】:

  • 我将假设您的时间戳格式错误。您的时间戳 int 数据是什么样的? (这将告诉我们它是以秒为单位的。毫秒或微秒。
  • 我的手机上运行了适用于 ios 的应用程序,它显示了正确的格式化日期。使用来自同一个数据库的相同时间戳,它在 dart/flutter 中给出了奇怪的值。它看起来像这样 -> 1522129071。注意** 由于某种原因,所有时间戳都显示为相同。
  • -> 1522129071
  • 当我从数据库中获取它时,它使用 swift 代码正确显示,但在 dart 中它显示 19:25 PM,它应该显示 15:50 PM,2 周前,4 周前,等等……
  • 你能给我看一下firebase时间戳的截图吗?您是使用时间戳数据类型还是只输入毫秒?

标签: dart flutter


【解决方案1】:

从 Firebase Firestore 将 DateTime、TimeStamp 打印为字符串:

      Timestamp t;
      String s;
      DateTime d;
//Declaring Variables
      snapshots.data.docs[index]['createdAt'] is Timestamp
                                    ? t = snapshots.data.docs[index]['createdAt']
                                    : s =
      snapshots.data.docs[index]['createdAt'].toString();
            
                                //check createdAt field Timestamp or DateTime
      snapshots.data.docs[index]['createdAt'] is Timestamp
                                    ? d = t.toDate()
                                    : s =
                                        snapshots.data.docs[index]['createdAt'].toString();
            
                                print(s.toString()); //Print Date and Time if DateTime
        print(d.toString()); //Print Date and Time if TimeStamp

【讨论】:

    【解决方案2】:

    只需调用此方法,即可在字符串中返回所需的 DateTime 值。

    String parseTimeStamp(int value) {
        var date = DateTime.fromMillisecondsSinceEpoch(value * 1000);
        var d12 = DateFormat('MM-dd-yyyy, hh:mm a').format(date);
        return d12;
    }
    

    例子:如果你传递TimeStamp值1636786003,你会得到结果为

    11-12-2021, 10:46PM
    

    【讨论】:

      【解决方案3】:

      Long num 格式日期转日历格式 from:

      var responseDate = 1637996744;
      var date = DateTime.fromMillisecondsSinceEpoch(responseDate);
      //to format date into different types to display;
      // sample format: MM/dd/yyyy : 11/27/2021
      var dateFormatted = DateFormat('MM/dd/yyyy').format(date);
      // sample format: dd/MM/yyy : 27/11/2021
      var dateFormatted = DateFormat('dd/MM/yyyy').format(date);
      // sample format: dd/MMM/yyyy : 27/Nov/2021
      var dateFormatted = DateFormat('dd/MMM/yyyy').format(date);
      // sample format: dd/MMMM/yyyy : 27/November/2021
      var dateFormatted = DateFormat('dd/MMMM/yyyy').format(date);
      print("Date After Format = $dateFormatted");
      

      【讨论】:

        【解决方案4】:
        • 以毫秒为单位:

          var millis = 978296400000;
          var dt = DateTime.fromMillisecondsSinceEpoch(millis);
          
          // 12 Hour format:
          var d12 = DateFormat('MM/dd/yyyy, hh:mm a').format(dt); // 12/31/2000, 10:00 PM
          
          // 24 Hour format:
          var d24 = DateFormat('dd/MM/yyyy, HH:mm').format(dt); // 31/12/2000, 22:00
          
        • 来自 Firestore:

          Map<String, dynamic> map = docSnapshot.data()!;
          DateTime dt = (map['timestamp'] as Timestamp).toDate();
          
        • 将一种格式转换为另一种格式:

          • 12 小时到 24 小时:

            var input = DateFormat('MM/dd/yyyy, hh:mm a').parse('12/31/2000, 10:00 PM');
            var output = DateFormat('dd/MM/yyyy, HH:mm').format(input); // 31/12/2000, 22:00
            
          • 24 小时到 12 小时:

            var input = DateFormat('dd/MM/yyyy, HH:mm').parse('31/12/2000, 22:00');
            var output = DateFormat('MM/dd/yyyy, hh:mm a').format(input); // 12/31/2000, 10:00 PM
            

        使用intl包(用于格式化)

        【讨论】:

          【解决方案5】:

          Timestamp 有 [toDate] 方法,那么您可以直接将其用作 DateTime。

          timestamp.toDate();
          // return DateTime object
          

          如果你想真正转换它,还有一个愚蠢的方法:

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

          【讨论】:

            【解决方案6】:

            Assuming you have a class

            class Dtime {
              int dt;
              Dtime(this.dt);
            
              String formatYMED() {
                var date = DateTime.fromMillisecondsSinceEpoch(this.dt);
                var formattedDate = DateFormat.yMMMMEEEEd().format(date);
                return formattedDate;
              }
            
              String formatHMA() {
                var time = DateTime.fromMillisecondsSinceEpoch(this.dt * 1000);
                final timeFormat = DateFormat('h:mm a', 'en_US').format(time);
                return timeFormat;
              }
            

            虽然我是初学者,但我希望能奏效。

            【讨论】:

              【解决方案7】:

              如何实施:

              import 'package:intl/intl.dart';
              
              getCustomFormattedDateTime(String givenDateTime, String dateFormat) {
                  // dateFormat = 'MM/dd/yy';
                  final DateTime docDateTime = DateTime.parse(givenDateTime);
                  return DateFormat(dateFormat).format(docDateTime);
              }
              

              如何打电话:

              getCustomFormattedDateTime('2021-02-15T18:42:49.608466Z', 'MM/dd/yy');
              

              结果:

              21 年 2 月 15 日

              以上代码解决了我的问题。我希望,这也会对你有所帮助。感谢您提出这个问题。

              【讨论】:

              • 我正在使用这个。效果很好。有没有办法可以调整它以将 UTC 转换为本地?
              【解决方案8】:

              我测试了这个,它可以工作

              // Map from firestore
              // Using flutterfire package hence the returned data()
              Map<String, dynamic> data = documentSnapshot.data();
              DateTime _timestamp = data['timestamp'].toDate();
              

              测试详情可以在这里找到:https://www.youtube.com/watch?v=W_X8J7uBPNw&feature=youtu.be

              【讨论】:

                【解决方案9】:

                假设timestamp firestore中的字段叫做timestamp,在dart中你可以在返回的map上调用toDate()方法。

                // Map from firestore
                // Using flutterfire package hence the returned data()
                Map<String, dynamic> data = documentSnapshot.data();
                DateTime _timestamp = data['timestamp'].toDate();
                

                【讨论】:

                  【解决方案10】:

                  我不知道这是否会帮助任何人。之前的消息对我有帮助,所以我在这里提出几点建议:

                  import 'package:intl/intl.dart';
                  
                      DateTime convertTimeStampToDateTime(int timeStamp) {
                       var dateToTimeStamp = DateTime.fromMillisecondsSinceEpoch(timeStamp * 1000);
                       return dateToTimeStamp;
                     }
                  
                    String convertTimeStampToHumanDate(int timeStamp) {
                      var dateToTimeStamp = DateTime.fromMillisecondsSinceEpoch(timeStamp * 1000);
                      return DateFormat('dd/MM/yyyy').format(dateToTimeStamp);
                    }
                  
                     String convertTimeStampToHumanHour(int timeStamp) {
                       var dateToTimeStamp = DateTime.fromMillisecondsSinceEpoch(timeStamp * 1000);
                       return DateFormat('HH:mm').format(dateToTimeStamp);
                     }
                  
                     int constructDateAndHourRdvToTimeStamp(DateTime dateTime, TimeOfDay time ) {
                       final constructDateTimeRdv = dateTimeToTimeStamp(DateTime(dateTime.year, dateTime.month, dateTime.day, time.hour, time.minute)) ;
                       return constructDateTimeRdv;
                     }
                  

                  【讨论】:

                    【解决方案11】:

                    如果您在这里只是将时间戳转换为日期时间,

                    Timestamp timestamp = widget.firebaseDocument[timeStampfield];
                    DateTime date = Timestamp.fromMillisecondsSinceEpoch(
                                    timestamp.millisecondsSinceEpoch).toDate();
                    

                    【讨论】:

                      【解决方案12】:

                      要将 Firestore Timestamp 转换为 DateTime 对象,只需使用 .toDate() 方法。

                      例子:

                      Timestamp now = Timestamp.now();
                      DateTime dateNow = now.toDate();
                      

                      正如您在docs 中看到的那样

                      【讨论】:

                        【解决方案13】:

                        您的时间戳格式实际上是秒(Unix 时间戳)而不是微秒。如果是,答案如下:

                        变化:

                        var date = new DateTime.fromMicrosecondsSinceEpoch(timestamp);
                        

                        var date = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
                        

                        【讨论】:

                        • 不,它仍然显示错误的值。例如,它应该显示 15:50 PM 它显示 11:23 AM 相同的值 1527796211
                        • 可能会针对 UTC 进行调整
                        • @MohamedMohamed 你在哪个时区? 1527796211 应该等于 05/31/2018 @ 7:50pm UTC(在我的代码中,如果你将时区设置为 UTC),如果它是 23 分钟,你是否使用毫秒?
                        • 你还有微秒。请注意,Alex 已将其更改为 毫秒
                        • EST (UTC−05:00) 是我的时区。如何将定位设置为该人所在的位置?
                        【解决方案14】:

                        只要确保乘以正确的因子:

                        微:乘以 1000000(即 10 的 6 次方)

                        Milli:乘以 1000(即 10 的 3 次方)

                        这就是它在 Dart 中的样子:

                        var date = new DateTime.fromMicrosecondsSinceEpoch(timestamp * 1000000);
                        

                        或者

                        var date = new DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
                        

                        【讨论】:

                        【解决方案15】:

                        如果有人来这里转换 firebase Timestamp 这里会有所帮助

                        Timestamp time;
                        DateTime.fromMicrosecondsSinceEpoch(time.microsecondsSinceEpoch)
                        

                        【讨论】:

                        • 非常感谢。正是需要的。注意:如果有人正在使用模拟器进行调试,请确保它与您的系统日期时间匹配,否则将无法生成准确的时间
                        【解决方案16】:

                        以上所有方法都可以使用,但要快速轻松地修复,您可以使用 time_formatter 包。

                        使用这个包,您可以将纪元转换为人类可读的时间。

                        String convertTimeStamp(timeStamp){
                        //Pass the epoch server time and the it will format it for you 
                           String formatted = formatTime(timeStamp).toString();
                           return formatted;
                        }
                        //Then you can display it
                        Text(convertTimeStamp['createdTimeStamp'])//< 1 second : "Just now" up to < 730 days : "1 year"
                        

                        您可以在此处检查将要显示的输出格式:Formats

                        【讨论】:

                          【解决方案17】:

                          任何需要的人的完整代码:

                          String readTimestamp(int timestamp) {
                              var now = DateTime.now();
                              var format = DateFormat('HH:mm a');
                              var date = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
                              var diff = now.difference(date);
                              var time = '';
                          
                              if (diff.inSeconds <= 0 || diff.inSeconds > 0 && diff.inMinutes == 0 || diff.inMinutes > 0 && diff.inHours == 0 || diff.inHours > 0 && diff.inDays == 0) {
                                time = format.format(date);
                              } else if (diff.inDays > 0 && diff.inDays < 7) {
                                if (diff.inDays == 1) {
                                  time = diff.inDays.toString() + ' DAY AGO';
                                } else {
                                  time = diff.inDays.toString() + ' DAYS AGO';
                                }
                              } else {
                                if (diff.inDays == 7) {
                                  time = (diff.inDays / 7).floor().toString() + ' WEEK AGO';
                                } else {
                          
                                  time = (diff.inDays / 7).floor().toString() + ' WEEKS AGO';
                                }
                              }
                          
                              return time;
                            }
                          

                          感谢 Alex Haslam 的帮助!

                          【讨论】:

                            【解决方案18】:

                            如果您使用的是 Firestore(而不仅仅是将时间戳存储为字符串),文档中的日期字段将返回时间戳。 Timestamp 对象包含一个toDate() 方法。

                            使用 timeago 您可以非常简单地创建一个相对时间:

                            _ago(Timestamp t) {
                              return timeago.format(t.toDate(), 'en_short');
                            }
                            
                            build() {
                              return  Text(_ago(document['mytimestamp'])));
                            }
                            

                            确保将_firestore.settings(timestampsInSnapshotsEnabled: true); 设置为返回时间戳而不是日期对象。

                            【讨论】:

                              【解决方案19】:

                              嗯,只需使用https://github.com/andresaraujo/timeago.dart 库;它为您完成所有繁重的工作。

                              编辑:

                              从您的问题来看,您似乎想要相对时间转换,而 timeago 库使您能够在 1 行代码中完成此操作。转换日期不是我自己选择实现的,因为有很多边缘情况,而且它很快就会变得很糟糕,特别是如果你将来需要支持不同的语言环境。您编写的代码越多 = 您需要测试的代码越多。

                              import 'package:timeago/timeago.dart' as timeago;
                              
                              final fifteenAgo = DateTime.now().subtract(new Duration(minutes: 15));
                              print(timeago.format(fifteenAgo)); // 15 minutes ago
                              print(timeago.format(fifteenAgo, locale: 'en_short')); // 15m
                              print(timeago.format(fifteenAgo, locale: 'es'));
                              
                              // Add a new locale messages
                              timeago.setLocaleMessages('fr', timeago.FrMessages());
                              
                              // Override a locale message
                              timeago.setLocaleMessages('en', CustomMessages());
                              
                              print(timeago.format(fifteenAgo)); // 15 min ago
                              print(timeago.format(fifteenAgo, locale: 'fr')); // environ 15 minutes
                              

                              要将 epochMS 转换为 DateTime,只需使用...

                              final DateTime timeStamp = DateTime.fromMillisecondsSinceEpoch(1546553448639);
                              

                              【讨论】:

                              • 如果我有“2021-01-03T18:42:49.608466Z”时间戳,如何转换日期?请提出建议。
                              • 我没试过,你需要使用精确的日期格式,但它可能会变成这样......final dt = DateFormat("yyyy-MM-dd'T'HH:mm:ss.ssssssZ").parse("2021-01-03T18:42:49.608466Z");
                              • DateTime.now() 具有 subtract 比较其他 DateTime 类型值的功能帮助我比较了 2 个日期时间。谢谢。
                              猜你喜欢
                              • 1970-01-01
                              • 1970-01-01
                              • 1970-01-01
                              • 2022-07-20
                              • 2011-07-07
                              • 2012-12-14
                              • 2012-09-22
                              • 1970-01-01
                              相关资源
                              最近更新 更多