0

I would like to have my DateTime always save in the following format: yMMMd

I.e. March 30, 2021

Problem:

When I format my DateTime, it formats as a String. When I try to parse this back into DateTime I get errors and no success.

I'm having issues chasing down a good solution to doing this.

Is this possible or do I have to settle for saving as a String?

EDIT

Tried everything that has been recommended and I tried many other methods which didn't work either. I wonder if the Intl package date format has trouble being parsed back to DateTime? That could be my issue. Anyone?

Please have a look at my print statements and errors to see what is successful and what isn't.

My date selector where I'm trying this:

  Future<void> _selectDate(BuildContext context) async {
    final DateTime picked = await showDatePicker(
        context: context,
        initialDate: DateTime.now(),
        firstDate: DateTime(2015, 8),
        lastDate: DateTime(2101));
    if (picked != null)
      setState(() {
        print('------ Picked date: $picked');
        var dateString = '';
        final formattedDate = DateFormat.yMMMd().format(picked);
        var parsedDate = DateTime.parse(formattedDate);           // Does not work...
        print('------- Parsed date: $parsedDate');
        dateString = formattedDate;
        print('------ String date: $dateString');
        expenseDate = formattedDate as DateTime;
        print('------ Formatted date: ${formattedDate.toString()}');
      });
  }

Error:

flutter: ------ Picked date: 2021-03-31 00:00:00.000
[VERBOSE-2:ui_dart_state.cc(186)] Unhandled Exception: FormatException: Invalid date format
Mar 31, 2021
#0      DateTime.parse (dart:core/date_time.dart:322:7)
#1      _AddExpenseButtonState._selectDate.<anonymous closure> (package:fp_provider_demo_one/widgets/add_expense_button.dart:48:35)
#2      State.setState (package:flutter/src/widgets/framework.dart:1267:30)
#3      _AddExpenseButtonState._selectDate (package:fp_provider_demo_one/widgets/add_expense_button.dart:44:7)
<asynchronous suspension>
Hamed
  • 5,867
  • 4
  • 32
  • 56
RobbB
  • 1,214
  • 11
  • 39
  • 2
    You didn't try to *parse* the `DateTime` string at all; you instead tried to cast it (i.e., pretend that the `String` is a `DateTime` object, which it isn't). If you want to actually parse it, see [convert datetime string to datetime object in dart?](https://stackoverflow.com/questions/49385303/convert-datetime-string-to-datetime-object-in-dart) – jamesdlin Mar 17 '21 at 06:26
  • I’ll check this out tonight, for some reason I believe I was having issues doing this also- hence the seemingly redundant post. I will edit my post to be more detailed as to what I could not do – RobbB Mar 17 '21 at 13:56
  • Tried parse, no go. Could this be an issue trying to parse intl formatted string to DateTime? – RobbB Mar 18 '21 at 00:22
  • 1
    As mentioned in my answer to the linked question, `DateTime.parse` handles only a small set of date/time formats. Since you formatted the `DateTime` to a string using `DateFormat`, you should parse it back with `DateFormat` too: `DateFormat.yMMMd().parse(formattedDate)`. – jamesdlin Mar 18 '21 at 00:35
  • @jamesdlin I tried your last solution. It does work and led me to my solution. When I format back to DateTime with DateFormat it appends the time again (which I don't want...) So that does in fact point out to me that I should not be doing all this monkey business of parsing the date in the picker but should do it just when displaying it in a widget... Unless you know a better way that I can have a CUSTOM formatted dateTime as above in my question. – RobbB Mar 18 '21 at 00:37
  • 1
    `DateTime` by definition stores both a date and a time. You're free to ignore the time portion, but you will need to use `DateFormat` whenever you want to convert it to a `String` (or back). You could make your own `Date` class that internally stores a `DateTime` and whose `toString()` method uses `DateFormat`. – jamesdlin Mar 18 '21 at 00:47
  • And that is the precise and accurate answer to my question. I may in fact figure something like that out. Thank you for the help. If you’re interested in upvote feel free to post an answer :) – RobbB Mar 18 '21 at 00:50

2 Answers2

1

So you want to format your datetime and later want to parse it back to a DateTime instance

Try out Jiffy package, might help. See below

Example of a picked time from your time picker

DateTime picked = DateTime(2021, 3, 21); // just a random datetime

To format try below

final formattedDate = Jiffy.parseFromDateTime(picked).yMMMd; // Mar 21, 2021

Parse it back to DateTime

var parsedDate = Jiffy.parse(formattedDate, pattern: "MMM dd, yyyy").dateTime; // 2021-03-21 00:00:00.000

Jiffy runs on top of Intl, you can also do a lot of cool things with it, try it out

Jama Mohamed
  • 3,057
  • 4
  • 29
  • 43
0

Use the parse method to get back a DateTime from the string.

final df = DateFormat.yMMMd();
final dateString = df.format(picked);

final expenseDate = df.parse(dateString);

https://pub.dev/documentation/intl/latest/intl/DateFormat/parse.html

Navaneeth P
  • 1,428
  • 7
  • 13
  • I’ll try this tonight, I think that for some weird reason I could not access the .parse method. Which seems weird. I guess I should have included that I’m my original post. I’ll update it when I have another look. – RobbB Mar 17 '21 at 13:57
  • Parsing didn't work, please see edit. Thanks. – RobbB Mar 18 '21 at 00:23