1

Trying to convert Firestore Timestamp to DateTime in Flutter I'm getting always an error, tried all of the solutions, none worked ( last tried How to print Firestore timestamp as formatted date and time)

Here's my code below;

Code

factory UserModel.fromMap(Map<String, dynamic> map) {
    return UserModel(
      name: map['name'],
      email: map['email'],
      username: map['username'],
      registerDate:
          DateTime.fromMillisecondsSinceEpoch(map['registerDate'] * 1000),
      id: map['id'],
      imageUrl: map['imageUrl'],
      cvUrl: map['cvUrl'],
      phoneNumber: map['phoneNumber'],
      education: Education.fromMap(map['education']),
      location: Location.fromMap(map['location']),
      lookingForIntern: map['lookingForIntern'],
    );
  }

Error

'Timestamp' has no instance method '*'.
Receiver: Instance of 'Timestamp'

Converted DateTime to Timestamp, and changed

registerDate:
              DateTime.fromMillisecondsSinceEpoch(map['registerDate'] * 1000),

to

registerDate:map['registerDate']

now getting error below;

Converting object to an encodable object failed: Instance of 'Timestamp'

but print(map['registerDate']) prints Timestamp(seconds=1632412800, nanoseconds=0)

Emir Kutlugün
  • 349
  • 1
  • 6
  • 18
  • This bug seems out there for a long time, The solution would be having the TimeStamp in model instead of the DateTime. – EngineSense Sep 24 '21 at 06:51
  • @EngineSense Can you please check the [following thread](https://stackoverflow.com/questions/50632217/dart-flutter-converting-timestamp) if it answers your question? – Rajeev Tirumalasetty Sep 24 '21 at 15:26
  • 1
    nope, not related to the issue! thanks – EngineSense Sep 25 '21 at 05:29
  • Does this answer your question? [How do I convert a Firestore Timestamp to a Dart DateTime](https://stackoverflow.com/questions/57153562/how-do-i-convert-a-firestore-timestamp-to-a-dart-datetime) – Rajeev Tirumalasetty Oct 13 '21 at 11:48
  • I switched my DateTime variable to 'dynamic' then converted it to DateTime in my UI using https://pub.dev/packages/date_format this package. But no, you can't convert Timestamp to DateTime directly, really annoying. – Emir Kutlugün Oct 20 '21 at 10:57

4 Answers4

0

Try this package to handle the problem-

https://pub.dev/packages/date_format

import 'package:date_format/date_format.dart';


     DateTime datetime = stamp.toDate();
        var time = formatDate(datetime, [hh, ':', nn, ' ', am]);
Dharman
  • 30,962
  • 25
  • 85
  • 135
Vishal_VE
  • 1,852
  • 1
  • 6
  • 9
0

I have this firebase function that is returning a TimeStamp (admin.firestore.Timestamp) in the field dueDateLatestRental:

 return {
                    data: { 'rental': null, 'hash': null, 'dueDateLatestRental': dueDateLatestRental },
                    status: 403,
                    message: itemStatus

In my flutter code I'm parsing the timestamp like this:

try {
          dynamic dueDateLatestRental = result.data['data']['dueDateLatestRental'];
          final data = Map<String, dynamic>.from(dueDateLatestRental) as Map<String, dynamic>;
          DateTime dueDateLatestRentalString = DateTime.fromMillisecondsSinceEpoch(data['_seconds'] * 1000).toLocal();
          String formattedDueDate = formatDate(dueDateLatestRentalString, [dd, '.', mm, '.', yyyy, ' ', HH, ':', nn]);
          logger.i('addRental result: $formattedDueDate');
            QuickAlert.show(
              context: context,
              type: QuickAlertType.error,
              title: 'Nicht verfügbar',
              text:
              'Das Teil ist bis zum $formattedDueDate ausgeliehen.',
              confirmBtnText: 'Okay',
              onConfirmBtnTap: () async {
                log("Box was not opened");
                Navigator.pop(context);
              },);
            return null;
        } catch (e) {
          logger.e("Error: could not parse the dueDateLatestRental");
          QuickAlert.show(
            context: context,
            type: QuickAlertType.error,
            title: 'Nicht verfügbar',
            text:
            'Das Teil ist bereits ausgeliehen. Bitte warte ein paar Tage.',
            confirmBtnText: 'Okay',
            onConfirmBtnTap: () async {
              log("Box was not opened");
              Navigator.pop(context);
            },
          );
          return null;
        }

I think it's safer to wrap this in a try/catch, because there are many ways how this could brake over time (e.g. me changing something in the database structure)

This is the resulting Alert Dialog:

result

Boommeister
  • 1,591
  • 2
  • 15
  • 54
0

There are different ways this can be achieved based on different scenario, see which of the following code fits your scenario.

  1. map['registerDate'].toDate()
    
  2. (map["registerDate"] as Timestamp).toDate()
    
  3. DateTime.fromMillisecondsSinceEpoch(map['registerDate'].millisecondsSinceEpoch);
    
  4. Timestamp.fromMillisecondsSinceEpoch(map['registerDate'].millisecondsSinceEpoch).toDate();
    
  5. Add the following function in your dart file.

    String formatTimestamp(Timestamp timestamp) {
      var format = new DateFormat('yyyy-MM-dd'); // <- use skeleton here
      return format.format(timestamp.toDate());
    }
    

    call it as formatTimestamp(map['registerDate'])

krishnaacharyaa
  • 14,953
  • 4
  • 49
  • 88
0
  • datetime is to store the current time zone of the server. The timestamp type is to convert the current time of the server to UTC (world time) for storage

  • you can set Firestore document arguments type to int

  @JsonKey(fromJson: timeFromJson, toJson: timeToJson)
  DateTime fileCreateTime;

  static DateTime timeFromJson(int timeMicroseconds) =>
      Timestamp.fromMicrosecondsSinceEpoch(timeMicroseconds).toDate().toLocal();
  static int timeToJson(DateTime date) =>
      Timestamp.fromMillisecondsSinceEpoch(date.toUtc().millisecondsSinceEpoch)
          .microsecondsSinceEpoch;
bakboem
  • 534
  • 4
  • 12