我真的很喜欢正则表达式并且几乎在任何地方都使用它们,但在这种情况下,我不推荐这种方式(除非你想出于学术目的这样做)。
我会使用DateTime.TryParse 或DateTime.TryParseExact。
你可以写的第一件事是:
Console.WriteLine("Enter the date:");
string dateString = Console.ReadLine();
DateTime date;
if(!DateTime.TryParseExact(dateString, "dd/MM/yy", CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
{
throw new InvalidOperationException("Not a valid date");
}
Console.WriteLine(date.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture));
// dateString = "17/04/88" => 17/04/1988
// dateString = "17/04/1988" => "Not a valid date"
.NET Fiddle
很好,但请稍等,如果有人以dd/MM/yyyy 格式输入日期,则会失败。
TryParseExect 方法采用 string[] 重载,您可以在其中指定多种格式
Console.WriteLine("Enter the date (you can write it in the dd/MM/yyyy format):");
string dateString = Console.ReadLine();
DateTime date;
if (!DateTime.TryParseExact(dateString, new string[] { "dd/MM/yyyy", "dd/MM/yy" }, CultureInfo.InvariantCulture, DateTimeStyles.None, out date))
{
throw new InvalidOperationException("Not a valid date");
}
Console.WriteLine(date.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture));
// dateString = "17/04/1988" => "17/04/1988"
// dateString = "17/04/29" => 17/04/2029
// dateString = "17/04/30" => 17/04/1930
.NET Fiddle
很好,但是等等,如果有人出生在17/04/29,它会显示17/04/2029,那是未来! 如果有人在 2029 年以上阅读这篇文章,请注意它是在 2015 年写的。
那是因为Calendar.TwoDigitYearMax Property
此属性允许将 2 位数的年份正确转换为
4 位数年份。例如,如果此属性设置为 2029,则
100 年的范围是从 1930 年到 2029 年。因此,两位数的值 30
被解释为 1930,而 29 的两位数被解释为
2029.
此时属性默认为2029,我不确定到了这个日期会做什么,可能是Year 2029 problem?
你可以再次改进它,但没有魔法,你必须做出选择,因为你已经知道,除非你做出假设,否则 2 位数的年份是不可能解决的。
所以你需要回答以下问题:
1) 我想解析的日期范围是多少 => 从 CurrentYear - 99 到 CurrentYear?
如果是,我们可以这样写:
// Execution date: 18/06/2015
Console.WriteLine("Enter the date (if you want to enter a date from more than 99 years ago, you can enter the date in the dd/MM/yyyy format):");
string dateString = Console.ReadLine();
DateTime date;
CultureInfo ci = (CultureInfo)CultureInfo.InvariantCulture.Clone();
ci.Calendar.TwoDigitYearMax = DateTime.Now.Year;
if(!DateTime.TryParseExact(dateString, new string[] { "dd/MM/yyyy", "dd/MM/yy" }, ci, DateTimeStyles.None, out date))
{
throw new InvalidOperationException("Not a valid date");
}
Console.WriteLine(date.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture));
// dateString = "17/04/15" => 17/04/2015
// dateString = "17/04/16" => 17/04/1916
.NET Fiddle
2) 我们在谈论生日,对吧?
我们真的需要管理不到一岁的人吗?
或者,如果您的出生日期用于您可以说某人不可能小于 16 岁的系统,您可以更改此范围以处理从 CurrentYear - 99 - 16 到 CurrentYear - 16 的日期。
这样您就可以管理 16 到 115 岁的人。
// Execution date: 18/06/2015
Console.WriteLine("Enter your birth date (if you are less than 16 year old you have to wait, if you are very old you can try to enter your birthdate in the dd/MM/yyyy format):");
string dateString = Console.ReadLine();
DateTime date;
CultureInfo ci = (CultureInfo)CultureInfo.InvariantCulture.Clone();
ci.Calendar.TwoDigitYearMax = DateTime.Now.Year - 16;
if (!DateTime.TryParseExact(dateString, new string[] { "dd/MM/yyyy", "dd/MM/yy" }, ci, DateTimeStyles.None, out date))
{
throw new InvalidOperationException("Not a valid date");
}
Console.WriteLine(date.ToString("dd/MM/yyyy", CultureInfo.InvariantCulture));
// dateString = "17/04/99" => 17/04/1999
// dateString = "17/04/16" => 17/04/1900
.NET Fiddle
就这篇文章而言,您可以继续自定义它,例如:
- 能够配置最小年龄
- 添加检查以验证日期不是将来的日期(如果输入
31/12/<TwoDigitYearMax>,使用上述代码仍然有效)