133

I couldn't find a solution to this, I'm grabbing data from firebase and one of the fields is a timestamp which looks like this -> 1522129071. How to convert it to a date?

Swift example (works) :

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
}

My attempt at 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;
}

And it returns dates/times that are waaaaaaay off.

UPDATE:

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;
  }
DarkBee
  • 15,492
  • 5
  • 46
  • 56
Mohamed Mohamed
  • 3,213
  • 3
  • 19
  • 39
  • I'm going to assume your timestamp is in the wrong format. What does your timestamp int data look like? (This will tell us if its in seconds. Milliseconds or Microseconds. – Alex Haslam May 31 '18 at 20:29
  • I have the app for ios running on my phone and it shows the correct formatted date. Using the same timestamp from the same database it's giving weird values in dart/flutter. It looks like this -> 1522129071. NOTE** All the timestamps are for some reason showing as the same. – Mohamed Mohamed May 31 '18 at 20:31
  • When I grab that from the database it shows correctly with the swift code, but in dart it shows 19:25 PM where it should be showing 15:50 PM, 2 weeks ago, 4 weeks ago, etc... – Mohamed Mohamed May 31 '18 at 20:33
  • canyou show me screenshot of firebase timestamp? are you using timestamp data type or you just putting miliseconds? – Tree May 31 '18 at 20:44
  • there is timestamp option in firestore. you would just pass DateTime as as data in your query. – Tree May 31 '18 at 20:44
  • 1527796211 is what it generally looks like. An int value from firebase. – Mohamed Mohamed May 31 '18 at 20:45
  • Using the Realtime Database, not Firestore. – Mohamed Mohamed May 31 '18 at 20:45
  • For reference, the function `firebaseTimestamp.toDate()` will also convert it to DateTime. – Adam Oct 28 '19 at 05:14

19 Answers19

226

Your timestamp format is in fact in Seconds (Unix timestamp) as opposed to microseconds. If so the answer is as follows:

Change:

var date = new DateTime.fromMicrosecondsSinceEpoch(timestamp);

to

var date = DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
Mahesh Jamdade
  • 11,710
  • 4
  • 79
  • 97
Alex Haslam
  • 2,677
  • 1
  • 11
  • 19
  • 3
    Nope, it's still showing wrong values. For example where it should be showing 15:50 PM it's showing 11:23 AM for the same value of 1527796211 – Mohamed Mohamed May 31 '18 at 20:40
  • maybe adjust for UTC – Tree May 31 '18 at 20:48
  • @MohamedMohamed What time zone are you in? 1527796211 should equate to 05/31/2018 @ 7:50pm UTC (Which in my code if you set time zone to UTC to does), also if its 23 mins, did you use Milliseconds? – Alex Haslam May 31 '18 at 20:50
  • 3
    You still have Microseconds. Note that Alex has changed it to **Milliseconds** – Richard Heap May 31 '18 at 20:50
  • 1
    EST (UTC−05:00) is my timezone. How can I set the locate to where the person is? – Mohamed Mohamed May 31 '18 at 20:52
  • @MohamedMohamed Dart should do that automatically. Can we see your code now? – Alex Haslam May 31 '18 at 20:55
  • Also where it should be calling the else part it's not. It's all showing the in the HH:mm a format. Where it should be saying 2 weeks ago it says 10:59 AM – Mohamed Mohamed May 31 '18 at 21:04
  • @MohamedMohamed Should be `fromMillisecondsSinceEpoch` NOT `fromMicrosecondsSinceEpoch` – Alex Haslam May 31 '18 at 21:04
  • AH THAT WORKED! Aha, didn't see that lol. But it's all coming out as "HH:mm a" format Some of the days are older so I want to show as Days ago, weeks ago, month ago etc. – Mohamed Mohamed May 31 '18 at 21:06
  • @MohamedMohamed based on your rules only a time in the future would meet the else condition. `diff.inSeconds <= 0` AKA anything in the past. Walk through your rules as if you were the computer and decide what would happen. – Alex Haslam May 31 '18 at 21:14
  • I don't get it, I have the same if/else condition in swift and it works fine why is it different in Dart? – Mohamed Mohamed May 31 '18 at 21:18
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/172184/discussion-between-alex-haslam-and-mohamed-mohamed). – Alex Haslam May 31 '18 at 21:19
  • My guess is that you are using diffrence in the opisite order to what you want to? Try swap var diff = date.difference(now); with var diff = now.difference(date); – Alex Haslam May 31 '18 at 21:39
  • This did not work for me. Got an error " 'int' is not a subtype of type 'DateTime'" . This one worked https://stackoverflow.com/questions/52996707/flutter-app-error-type-timestamp-is-not-a-subtype-of-type-datetime – giorgio79 Jun 24 '20 at 12:07
  • DateTime.fromMillisecondsSinceEpoch(firebasetimestampfieldname.seconds * 1000) will solve your problem. Thanks for asking this question. – Kamlesh Jun 15 '21 at 18:00
  • `firebasetimestampfieldname.seconds` should be integer. – Kamlesh Jun 15 '21 at 18:00
56
  • From milliseconds:

    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
    
  • From Firestore:

    Map<String, dynamic> map = docSnapshot.data()!;
    DateTime dt = (map['timestamp'] as Timestamp).toDate();
    
  • Converting one format to other:

    • 12 Hour to 24 Hour:

      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 Hour to 12 Hour:

      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
      

Use intl package (for formatting)

CopsOnRoad
  • 175,842
  • 51
  • 533
  • 380
37

Full code for anyone who needs it:

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;
  }

Thank you Alex Haslam for the help!

Stefan
  • 232
  • 2
  • 14
Mohamed Mohamed
  • 3,213
  • 3
  • 19
  • 39
16

If you are using firestore (and not just storing the timestamp as a string) a date field in a document will return a Timestamp. The Timestamp object contains a toDate() method.

Using timeago you can create a relative time quite simply:

_ago(Timestamp t) {
  return timeago.format(t.toDate(), 'en_short');
}

build() {
  return  Text(_ago(document['mytimestamp'])));
}

Make sure to set _firestore.settings(timestampsInSnapshotsEnabled: true); to return a Timestamp instead of a Date object.

Jordan Whitfield
  • 1,204
  • 15
  • 17
16

if anyone come here to convert firebase Timestamp here this will help

Timestamp time;
DateTime.fromMicrosecondsSinceEpoch(time.microsecondsSinceEpoch)
Bawantha
  • 2,605
  • 3
  • 19
  • 25
  • Thank you very much. Just what was needed. Note: If someone is debugging using an emulator, please be sure that it matches your system datetime else accurate time would not be produced – Zujaj Misbah Khan Sep 05 '20 at 09:51
10

To convert Firestore Timestamp to DateTime object just use .toDate() method.

Example:

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

As you can see in docs

Paulo Belo
  • 2,309
  • 18
  • 16
8

meh, just use https://github.com/andresaraujo/timeago.dart library; it does all the heavy-lifting for you.

EDIT:

From your question, it seems you wanted relative time conversions, and the timeago library enables you to do this in 1 line of code. Converting Dates isn't something I'd choose to implement myself, as there are a lot of edge cases & it gets fugly quickly, especially if you need to support different locales in the future. More code you write = more you have to test.

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

to convert epochMS to DateTime, just use...

final DateTime timeStamp = DateTime.fromMillisecondsSinceEpoch(1546553448639);
wooldridgetm
  • 2,400
  • 1
  • 15
  • 20
  • how can i convert date if i have "2021-01-03T18:42:49.608466Z" timestamp? Please suggest. – Kamlesh Feb 20 '21 at 04:53
  • I haven't tried it, and you'll need to play with exact date format, but it'll probably go something like this... `final dt = DateFormat("yyyy-MM-dd'T'HH:mm:ss.ssssssZ").parse("2021-01-03T18:42:49.608466Z");` – wooldridgetm Feb 22 '21 at 16:06
  • [Convert String to Date in Dart](https://stackoverflow.com/questions/49385303/convert-datetime-string-to-datetime-object-in-dart) – wooldridgetm Feb 22 '21 at 16:06
  • `DateTime.now()` has `subtract` function to compare other `DateTime` typed value helped me to compare 2 datetimes. Thanks. – Kamlesh Jul 02 '21 at 05:48
7

Just make sure to multiply by the right factor:

Micro: multiply by 1000000 (which is 10 power 6)

Milli: multiply by 1000 (which is 10 power 3)

This is what it should look like in Dart:

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

Or

var date = new DateTime.fromMillisecondsSinceEpoch(timestamp * 1000);
Merouane T.
  • 327
  • 1
  • 6
  • 9
  • I have "Timestamp(seconds=1623775912, nanoseconds=94580000)" how to convert it to DateTime? Please suggest. Thanks – Kamlesh Jun 15 '21 at 16:57
  • From the documentation there is a method toDateTime(). check here: https://pub.dev/documentation/sembast/latest/sembast_timestamp/Timestamp-class.html – Merouane T. Jun 15 '21 at 18:19
  • Yes dear, thanks - https://pub.dev/documentation/sembast/latest/sembast_timestamp/Timestamp/toDateTime.html – Kamlesh Jun 15 '21 at 19:55
6

How to implement:

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);
}

How to call:

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

Result:

02/15/21

Above code solved my problem. I hope, this will also help you. Thanks for asking this question.

Kamlesh
  • 3,828
  • 30
  • 37
  • I’m using this. works great. Is there a way we can tweak this to convert from UTC to local? – onexf Oct 28 '21 at 12:47
5

Assuming the field in timestamp firestore is called timestamp, in dart you could call the toDate() method on the returned map.

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

I don't know if this will help anyone. The previous messages have helped me so I'm here to suggest a few things:

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;
   }
LordBaltus
  • 41
  • 4
2

If you are here to just convert Timestamp into DateTime,

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

I tested this one and it works

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

Test details can be found here: https://www.youtube.com/watch?v=W_X8J7uBPNw&feature=youtu.be

Emin Laletovic
  • 3,394
  • 1
  • 11
  • 21
2

Simply call this method to return your desired DateTime value in String.

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

Example: if you pass the TimeStamp value 1636786003, you will get the result as

11-12-2021, 10:46PM
marc_s
  • 704,970
  • 168
  • 1,303
  • 1,425
Rahul Kushwaha
  • 3,752
  • 2
  • 21
  • 22
1

All of that above can work but for a quick and easy fix you can use the time_formatter package.

Using this package you can convert the epoch to human-readable time.

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"

Here you can check the format of the output that is going to be displayed: Formats

Sludge
  • 4,593
  • 5
  • 26
  • 37
Abel Tilahun
  • 1,333
  • 1
  • 10
  • 22
1

Timestamp has [toDate] method then you can use it directly as an DateTime.

timestamp.toDate();
// return DateTime object

Also there is an stupid way if you want really convert it:

DateTime.parse(timestamp.toDate().toString())
Navid Shad
  • 423
  • 5
  • 12
1

Print DateTime, TimeStamp as string from Firebase Firestore:

      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
marc_s
  • 704,970
  • 168
  • 1,303
  • 1,425
Rahul Raj
  • 190
  • 2
  • 6
0

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;
  }

I am a beginner though, I hope that works.

0

Long num format date into Calender format 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");
marc_s
  • 704,970
  • 168
  • 1,303
  • 1,425
Suresh B B
  • 655
  • 5
  • 8