Home > Mobile >  Neatly parsing a date in "MMddyy" format along with other formats in dart
Neatly parsing a date in "MMddyy" format along with other formats in dart

Time:05-02

I guess it is not possible to parse a date in "MMddyy" format in dart.

void main() {
  String strcandidate = "031623";
  String format = "MMddyy";
  var originalFormat = DateFormat(format).parse(strcandidate);
}

Output:

Uncaught Error: FormatException: Trying to read dd from 031623 at position 6

The following works fine when parsing a date in "MM-dd-yy" format.

void main() {
  String strcandidate = "03-16-23";
  String format = "MM-dd-yy";
  var originalFormat = DateFormat(format).parse(strcandidate);
}

In the problem, the input date string can be in any format e.g ['yyyy-MM-dd', 'MMM'-yyyy, 'MM/dd/yy']. I am parsing the input string for these formats in a loop as follows.

dateFormatsList = ['yyyy-MM-dd', 'MMM'-yyyy, 'MM/dd/yy'];
        for (String format in dateFormatsList ) {
          try {
            originalFormat = DateFormat(format).parse(strcandidate);
            dateFound = true;
          } catch (e) {}
        }

Adding 'MMddyy' to dateFormatsList is not going to work. But regular expression be used to parse this format. However if all formats are parsed using parse method and one additional format is parsed using regular expression, then the code is not that neat, and cluttered.

To write as much neat and efficient code as possible, if you want, you can share your insights about any possibility for making it efficient and clean while incorporating 'MMddyy'format. Tysm!

CodePudding user response:

I think it's a bit hacky but what about use a regular expression (RegExp) to parse the date divider and then replace it with just ""?

CodePudding user response:

void main() {
   String strcandidate = "031623";
   String strYear = strcandidate.substring(4);
   //Taken 20 as the year like 2023 as year is in 2 digits
   String _newDateTime = '20'   strYear   strcandidate.substring(0, 4);
   var _originalFormat = DateTime.parse(_newDateTime);
   print(_originalFormat);
}

CodePudding user response:

See How do I convert a date/time string to a DateTime object in Dart? for how to parse various date/time strings to DateTime objects.

If you need to mix approaches, you can provide a unified interface. Instead of using a List<String> for your list of formats, you can use a List<DateTime Function(String)>:

import 'package:intl/intl.dart';

/// Parses a [DateTime] from [dateTimeString] using a [RegExp].
///
/// [re] must have named groups with names `year`, `month`, and `day`.
DateTime parseDateFromRegExp(RegExp re, String dateTimeString) {
  var match = re.firstMatch(dateTimeString);
  if (match == null) {
    throw FormatException('Failed to parse: $dateTimeString');
  }

  var yearString = match.namedGroup('year');
  var monthString = match.namedGroup('month');
  var dayString = match.namedGroup('day');

  if (yearString == null || monthString == null || dayString == null) {
    throw ArgumentError('Regular expression is malformed');
  }

  var year = int.parse(yearString);
  var month = int.parse(monthString);
  var day = int.parse(dayString);

  if (year > 0 && year < 100) {
    year  = 1900;
  }

  return DateTime(year, month, day);
}

typedef DateParser = DateTime Function(String);

DateParser dateParserFromRegExp(String rePattern) =>
    (string) => parseDateFromRegExp(RegExp(rePattern), string);

var parserList = [
  DateFormat('yyyy-MM-dd').parse,
  DateFormat('MMM-yyyy').parse,
  DateFormat('MM/dd/yy').parse,
  dateParserFromRegExp(
    r'^(?<month>\d{2})(?<day>\d{2})(?<year>\d{2})$',
  )
];

void main() {
  var strcandidate = '123199';
  DateTime? originalFormat;
  for (var tryParse in parserList) {
    try {
      originalFormat = tryParse(strcandidate);
      break;
    } on Exception {
      // Try the next format.
    }
  }

  print(originalFormat);
}

CodePudding user response:

See How do I convert a date/time string to a DateTime object in Dart? for how to parse various date/time strings to DateTime objects.

If you need to mix approaches, you can provide a unified interface. Instead of using a List<String> for your list of formats, you can use a List<DateTime Function(String)>:

import 'package:intl/intl.dart';

/// Parses a [DateTime] from [dateTimeString] using a [RegExp].
///
/// [re] must have named groups with names `year`, `month`, and `day`.
DateTime parseDateFromRegExp(RegExp re, String dateTimeString) {
  var match = re.firstMatch(dateTimeString);
  if (match == null) {
    throw FormatException('Failed to parse: $dateTimeString');
  }

  var year = match.namedGroup('year');
  var month = match.namedGroup('month');
  var day = match.namedGroup('day');

  if (year == null || month == null || day == null) {
    throw ArgumentError('Regular expression is malformed');
  }

  // In case we're parsing a two-digit year format, instead of
  // parsing the strings ourselves, reparse it with [DateFormat] so that it can
  // apply its -80/ 20 rule.
  //
  // [DateFormat.parse] doesn't work without separators, which is why we
  // can't use directly on the original string.  See:
  // https://github.com/dart-lang/intl/issues/210
  return DateFormat('yy-MM-dd').parse('$year-$month-$day');
}

typedef DateParser = DateTime Function(String);

DateParser dateParserFromRegExp(String rePattern) =>
    (string) => parseDateFromRegExp(RegExp(rePattern), string);

var parserList = [
  DateFormat('yyyy-MM-dd').parse,
  DateFormat('MMM-yyyy').parse,
  DateFormat('MM/dd/yy').parse,
  dateParserFromRegExp(
    r'^(?<month>\d{2})(?<day>\d{2})(?<year>\d{4})$',
  )
];

void main() {
  var strcandidate = '12311776';
  DateTime? originalFormat;
  for (var tryParse in parserList) {
    try {
      originalFormat = tryParse(strcandidate);
      break;
    } on Exception {
      // Try the next format.
    }
  }

  print(originalFormat);
}

CodePudding user response:

add the intl to yaml then write this code:

import 'package:intl/intl.dart';
void main() {
  var strcandidate = DateTime(2023, 3, 16);
  String format = "MMddyy";
  var originalFormat = DateFormat(format).format(strcandidate);
  print(originalFormat);
}
  • Related