如何检查给定日期在DART中是否存在?

6
如果你将一个不存在或不是真实日期的值,例如:'20181364' (2018/13/64) 传递给DateTime(构造函数或解析方法),则不会抛出异常。相反,将返回计算后的DateTime。
例如: '20181364' --> 2019-03-05 00:00:00.000
如何检查给定的日期是否真实存在或有效?
我尝试使用DartPad进行解决,但没有成功,因此此处不需要Flutter doctor的输出。
void main() {
  var inputs = ['20180101', // -> 2018-01-01 00:00:00.000
                '20181231', // -> 2018-12-31 00:00:00.000
                '20180230', // -> 2018-03-02 00:00:00.000
                '20181301', // -> 2019-01-01 00:00:00.000
                '20181364'];// -> 2019-03-05 00:00:00.000

  inputs.forEach((input) => print(convertToDate(input)));
}

String convertToDate(String input){
  return DateTime.parse(input).toString();
}

如果存在某种方法可以检查给定的日期是否真实存在/有效,那将是非常好的,例如:
  • DateTime中的一个验证函数
  • 另一个库,它不使用DateTime.parse()进行验证
你会如何解决这个问题?

对于其他人来说,这似乎是一个问题,在dartlang存储库中仍然是开放的:https://github.com/dart-lang/sdk/issues/11189 - jdixon04
3个回答

15
你可以将解析后的日期转换为原始格式的字符串,然后比较是否与输入匹配。
void main() {
  var inputs = ['20180101', // -> 2018-01-01 00:00:00.000
                '20181231', // -> 2018-12-31 00:00:00.000
                '20180230', // -> 2018-03-02 00:00:00.000
                '20181301', // -> 2019-01-01 00:00:00.000
                '20181364'];// -> 2019-03-05 00:00:00.000

  inputs.forEach((input) {
    print("$input is valid string: ${isValidDate(input)}");
  });
}

bool isValidDate(String input) {
  final date = DateTime.parse(input);
  final originalFormatString = toOriginalFormatString(date);
  return input == originalFormatString;
}

String toOriginalFormatString(DateTime dateTime) {
  final y = dateTime.year.toString().padLeft(4, '0');
  final m = dateTime.month.toString().padLeft(2, '0');
  final d = dateTime.day.toString().padLeft(2, '0');
  return "$y$m$d";
}

1
有趣的方法! - jdixon04
1
完全同意,非常干净利落的方法 :) 谢谢 :) - Max

3

我验证生日的解决方案是这样的,可以看到其中包含闰年的计算。

class DateHelper{

    /*
    * Is valid date and format
    *
    * Format: dd/MM/yyyy
    * valid:
    *   01/12/1996
    * invalid:
    *   01/13/1996
    *
    * Format: MM/dd/yyyy
    * valid:
    *  12/01/1996
    * invalid
    *  13/01/1996
    * */
    static bool isValidDateBirth(String date, String format) {
        try {
            int day, month, year;

            //Get separator data  10/10/2020, 2020-10-10, 10.10.2020
            String separator = RegExp("([-/.])").firstMatch(date).group(0)[0];

            //Split by separator [mm, dd, yyyy]
            var frSplit = format.split(separator);
            //Split by separtor [10, 10, 2020]
            var dtSplit = date.split(separator);

            for (int i = 0; i < frSplit.length; i++) {
                var frm = frSplit[i].toLowerCase();
                var vl = dtSplit[i];

                if (frm == "dd")
                    day = int.parse(vl);
                else if (frm == "mm")
                    month = int.parse(vl);
                else if (frm == "yyyy")
                    year = int.parse(vl);
            }

            //First date check
            //The dart does not throw an exception for invalid date.
            var now = DateTime.now();
            if(month > 12 || month < 1 || day < 1 || day > daysInMonth(month, year) || year < 1810 || (year > now.year && day > now.day && month > now.month))
                throw Exception("Date birth invalid.");

            return true;
        } catch (e) {
            return false;
        }
    }

    static int daysInMonth(int month, int year) {
        int days = 28 + (month + (month/8).floor()) % 2 + 2 % month + 2 * (1/month).floor();
        return (isLeapYear(year) && month == 2)? 29 : days;
    }

    static bool isLeapYear(int year)
        => (( year % 4 == 0 && year % 100 != 0 ) || year % 400 == 0 );
}

2

这应该是被接受的答案。 - easeccy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接