Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make DateTime.parse() more permissive, accept single digit parts. #36067

Closed
ScottS2017 opened this issue Feb 28, 2019 · 5 comments
Closed

Make DateTime.parse() more permissive, accept single digit parts. #36067

ScottS2017 opened this issue Feb 28, 2019 · 5 comments
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-core type-enhancement A request for a change that isn't a bug

Comments

@ScottS2017
Copy link

ScottS2017 commented Feb 28, 2019

I looked at doing a PR on this but there seem to be multiple places it could be addressed and I'm not sure which would be appropriate. So, here it is...

SDK Version:
I'm not sure which version of Dart is actually being used because Flutter is utilizing its own copy of date_time.dart located at flutter\bin\cache\pkg\sky_engine\lib\core , which I believe can, at times, be a version behind the Dart SDK. My Flutter version is 1.2.1 and I'm on Beta.

Problem:
DateTime.parse() fails with an Invalid date format error if you hand it a string that is only one character (it doesn't have leading zeros in the month, day, hour and minute for any value 9 and under).

Compounding Problem:
toString() or string interpolation drops leading zeros. IE:

print(selectedDateTime); // Returns 2019-04-18 06:03:00.000
print(selectedDateTime.hour.toString()); // Returns 6, not 06

Running this code will recreate the issue:

  DateTime testDateTime = DateTime(2019, 4, 18, 6, 5);
  print(testDateTime); // Correctly Prints 2019-04-18 06:03

  print(testDateTime.month.toString()); // Prints 4
  print(testDateTime.day.toString()); // Prints 18
  print(testDateTime.hour.toString()); // Prints 6
  print(testDateTime.minute.toString()); // Prints 5

  DateTime result = DateTime.parse('2019-04-18 06:05'); // Works
  print(result); // Correctly Prints 2019-04-18 06:03

  /// The below results in this Invalid date format error:
  // [ERROR:flutter/lib/ui/ui_dart_state.cc(148)] Unhandled Exception: FormatException: Invalid date format
  // 2019-4-18-6-5
  DateTime reconstructedDateTime = DateTime.parse(
  '2019-${testDateTime.month.toString()}-${testDateTime.day.toString()}-'
  '${testDateTime.hour.toString()}-${testDateTime.minute.toString()}');

A hacky workaround is to use a pad( ), but it would be much better if this were handled in the framework.

Example:
${_datePicked.month.toString().padLeft(2, "0")}

Thanks,
Scott Stoll

@kevmoo kevmoo added area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-core labels Feb 28, 2019
@kevmoo
Copy link
Member

kevmoo commented Feb 28, 2019

@lrhn ?

@lrhn
Copy link
Member

lrhn commented Mar 1, 2019

The input to DateTime.parse has format requirements.
Here you are building a string which doesn't have the required format and passing it to DateTime.parse.

We could loosen those requirements, perhaps by allowing single-digit month and day or <4 digit year, but I'd prefer not to. Since we allow omitting - characters, we could only allow that if there is a -, and it would complicate the parsing for very little gain. The more permissive we are, the more errors we allow to pass through. You shouldn't be building a string from integers to pass to DateTime.parse at all.

Creating a string from integers, and then immediately parsing it, is not required, or even the best way, to create a DateTime from those integers. You should instead use:

var reconstructedTime = DateTime(testDateTime.year, testDateTime.month, testDateTime.day, testDateTime.hour, testDateTime.minute);

I'd even recommend creating the DateTime object and using its toString over building a string manually.

If you want to format a date/time in a particular way, you can use package:intl, which has a date formatter.

(That testDateTime.hour.toString() prints "6" instead of "06" is not something we can change because testDateTime.hour is an int.)

@ScottS2017
Copy link
Author

The reason I filed it as an issue is simply because if you use DateTime.(something).toString( ) to pull something out of DateTime and then try to put it back together by using the parse, it causes an error. Intuitively, since DateTime.parse( ) takes a string, and you got strings out of the DateTime, one expects that reassembling them using parse( ) to be successful.

It might help if this simply had a different error message. Instead of:
Unhandled Exception: FormatException: Invalid date format
perhaps something like this might be more descriptive?
Unhandled Exception: FormatException: Month, Date, Hour and Minute all require two-digit integers

@lrhn lrhn added the type-enhancement A request for a change that isn't a bug label Oct 2, 2020
@lrhn lrhn changed the title Passing DateTime.parse() a .toString() results in Invalid date format Make DateTime.parse() more permissive, accept single digit parts. Oct 2, 2020
@derekpitts28
Copy link

Bump on this.

@lrhn
Copy link
Member

lrhn commented Dec 13, 2023

Still no plan to change the parse behavior.

The DateTime.parse method exists to parse the output of DateTime.toString, it's not intended as a general way to parse any possible way to represent a date.
For that, use package:intl.

@lrhn lrhn closed this as not planned Won't fix, can't repro, duplicate, stale Dec 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-core type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

4 participants