这个问题源自一个会计软件包,它会发出基于文本的报告,其中的数据行具有无效日期,例如2月31日 st 或9月31日 st 。
报告使用空格和单倍间距字体进行格式化。我的目标是解析所需的数据并生成更正式的报告(SSRS)。
我对修复感兴趣的是日期无效且无法直接转换为DateTime
结构的情况。报告中的日期格式为MMM-dd-yy
(例如Feb-30-10
)。 我想将无效日期字符串转换为同月最接近的有效DateTime
,然后在正式报告中显示它们。在我作为开发人员的时候,我已经看到过两种方式,两者都非常糟糕,所以我想想出一个简单的方法(如果没有我不知道的内置方式)
我见过的第一个糟糕的方法(我简直不敢相信我甚至会向你展示!):
Dim month As Integer = <Parse out the month from the bad date string>
Dim day As Integer = <Parse out the day from the bad date string>
Dim year As Integer = <Parse out the year from the bad date string>
Dim validDate As DateTime
While True
Try
validDate = New DateTime(year, month, day)
Exit While
Catch ex As ArgumentOutOfRangeException
day -= 1
End Try
End While
我希望我不必解释我不喜欢这种方法。
第二种不好的方法:
Dim badDateString As String = <Current date string from text report>
Dim validDate As DateTime
If DateTime.TryParseExact(badDateString, "MMM-dd-yy", Nothing, Globalization.DateTimeStyles.None, validDate) Then
Return validDate
End If
badDateString = badDateString.Replace("31", "30")
' ... try the parse again, if still not valid, replace "30" with "29"
' ... try the parse again, if still not valid, replace "29" with "28"
这些令人伤心的代码和我是一个悲伤的开发人员。
我一直在努力想出一种更有效的方法。有什么想法吗?
修改:
我找到了解决方案并发布了它,但我更喜欢Guffa的回答。
答案 0 :(得分:6)
阅读上一段代码,最后一段代码就是我要提出的建议。
以下是代码的变体:
Return New DateTime(year, month, Math.Min(day, DateTime.DaysInMonth(year, month)))
答案 1 :(得分:0)
这是我在Guffa回答之前发现的解决方案。它采用日期(月,日,年)的部分,使用特定月/年组合中的天数来验证传入的日期部分,并在构建新的DateTime
之前根据需要进行调整。
Dim validDate As DateTime
Dim dayMax As Integer = DateTime.DaysInMonth(year, month)
Dim newDay = day
If day > dayMax OrElse day < 1 Then
newDay = dayMax
End If
validDate = new DateTime(year, month, newDay)
Return validDate