如何根据日期时间选择器值将年龄显示为年、月、日。例如:
Datetimepicker value = #1/11/2014#
Today = #1/12/2015#.
最终结果将是“1 Year, 0 Months, 1Day(S)”。但是得到这个结果不仅仅是减去DateTime.Year
值等等。有人知道数学公式或数学计算吗?
如何根据日期时间选择器值将年龄显示为年、月、日。例如:
Datetimepicker value = #1/11/2014#
Today = #1/12/2015#.
最终结果将是“1 Year, 0 Months, 1Day(S)”。但是得到这个结果不仅仅是减去DateTime.Year
值等等。有人知道数学公式或数学计算吗?
这是一个DateTimeSpan
类型,它返回一个对象,例如TimeSpan
表示两个日期之间经过的年、月、日。它循环遍历时间单位以增加它们,直到较小的日期与较大的日期匹配。然后在新DateTimeSpan
对象中返回结果增量。
Public Structure DateTimeSpan
Private _Years As Integer
Public ReadOnly Property Years As Integer
Get
Return _Years
End Get
End Property
Private _Months As Integer
Public ReadOnly Property Months As Integer
Get
Return _Months
End Get
End Property
Private _Days As Integer
Public ReadOnly Property Days As Integer
Get
Return _Days
End Get
End Property
Private _Hours As Integer
Public ReadOnly Property Hours As Integer
Get
Return _Hours
End Get
End Property
Private _Minutes As Integer
Public ReadOnly Property Minutes As Integer
Get
Return _Minutes
End Get
End Property
Private _Seconds As Integer
Public ReadOnly Property Seconds As Integer
Get
Return _Seconds
End Get
End Property
Private _MilliSeconds As Integer
Public ReadOnly Property MilliSeconds As Integer
Get
Return _MilliSeconds
End Get
End Property
' the ctor for the result
Private Sub New(y As Integer, mm As Integer, d As Integer,
h As Integer, m As Integer, s As Integer,
ms As Integer)
_Years = y
_Months = mm
_Days = d
_Hours = h
_Minutes = m
_Seconds = Seconds
_MilliSeconds = ms
End Sub
' private time unit tracker when counting
Private Enum Unit
Year
Month
Day
Complete
End Enum
Public Shared Function DateSpan(dt1 As DateTime,
dt2 As DateTime) As DateTimeSpan
' we dont do negatives
If dt2 < dt1 Then
Dim tmp = dt1
dt1 = dt2
dt2 = tmp
End If
Dim thisDT As DateTime = dt1
Dim years As Integer = 0
Dim months As Integer = 0
Dim days As Integer = 0
Dim level As Unit = Unit.Year
Dim span As New DateTimeSpan()
While level <> Unit.Complete
Select Case level
' add a year until it is larger;
' then change the "level" to month
Case Unit.Year
If thisDT.AddYears(years + 1) > dt2 Then
level = Unit.Month
thisDT = thisDT.AddYears(years)
Else
years += 1
End If
Case Unit.Month
If thisDT.AddMonths(months + 1) > dt2 Then
level = Unit.Day
thisDT = thisDT.AddMonths(months)
Else
months += 1
End If
Case Unit.Day
If thisDT.AddDays(days + 1) > dt2 Then
thisDT = thisDT.AddDays(days)
Dim thisTS = dt2 - thisDT
' create a new DTS from the values caluclated
span = New DateTimeSpan(years, months, days, thisTS.Hours,
thisTS.Minutes, thisTS.Seconds,
thisTS.Milliseconds)
level = Unit.Complete
Else
days += 1
End If
End Select
End While
Return span
End Function
End Structure
Dim dts As DateTimeSpan = DateTimeSpan.DateSpan(#2/11/2010#, #10/21/2013#)
Console.WriteLine("{0} Yrs, {1} Months and {2} Days",
dts.Years.ToString, dts.Months.ToString, dts.Days.ToString)
这将给出相同的结果:
Dim dtStart As DateTime = #2/11/2010#
Dim dtEnd As new DateTime(2013, 10, 21)
' this is NOT a date and wont work:
Dim myDt = "2/11/2010" ' its a string!
Dim dts As DateTimeSpan = DateTimeSpan.DateSpan(dtEnd, dtStart)
结果:3 Yrs, 8 Months and 10 Days
注意:
- 它仅适用于正确的DateTime
类型,不适用于看起来像日期的字符串。使用文字 ( #...#
) 或DateTime
变量。使用 aDateTimePicker
时,使用.Value
not .Text
。
- 它不做负值,所以传递的值的顺序无关紧要
- 计算时,它增加一个DateTime
变量,所以它应该正确考虑闰日
这是基于我很久以前在博客中找到的一些 C# 代码(或者甚至可能来自 SO 答案或问题)。现在找不到引用原文了。
这种方法使用循环来向后工作,但我相信这是唯一准确的方法来做到这一点,并使值始终正确。这是因为它比您想象的要复杂 - 您需要调整闰年等。
''' <summary>
''' Finds the Years Months and Days Span between two dates
''' </summary>
''' <param name="fromDate"></param>
''' <param name="toDate"></param>
''' <returns>A String formatted as i Years j Months k Days</returns>
''' <remarks></remarks>
Public Shared Function GetDateSpanText(ByVal fromDate As DateTime, Optional toDate As DateTime = Nothing) As String
Dim years As Integer = 0, months As Integer = 0, days As Integer = 0
If toDate = Nothing Then toDate = DateTime.Now
Do Until toDate.AddYears(-1) < fromDate
years += 1
toDate = toDate.AddYears(-1)
Loop
Do Until toDate.AddMonths(-1) < fromDate
months += 1
toDate = toDate.AddMonths(-1)
Loop
Do Until toDate.AddDays(-1) < fromDate
days += 1
toDate = toDate.AddDays(-1)
Loop
Return String.Format("{0} Year(s) {1} Month(s) {2} Day(s)", years, months, days)
End Function
用法:
Debug.WriteLine(GetDateSpanText(#1/11/2014#))
印刷:
1 Year(s) 0 Month(s) 1 Day(s)
这种方法非常直接和简单。
不需要创建循环和类属性。
这将适用于真实Date
类型和Strings
日期:
'Date Picker Value
Dim dBirthDate As Date = "#01/11/2014#"
'Today
Dim dToday As Date = "#01/12/2015#"
Dim dBirthDay As Date
Dim sYears As String
Dim sDays As String
Dim sMonths As String
Dim sResults As String
sYears = DateDiff(DateInterval.Year, dBirthDate, dToday)
dBirthDay = dBirthDate.AddYears(sYears)
sMonths = DateDiff(DateInterval.Month, dBirthDay, dToday)
sDays = DateDiff(DateInterval.Day, dBirthDay, dToday)
sResults = sYears & " Year " & sMonths & " Months " & sDays & " Day(s)"
示例结果:1 年 0 个月 1 天
您必须添加它才能获得完整的结果:sDays = (DateDiff(DateInterval.Day, dBirthDay, dToday)) - sMonths * 30