[英]Unexpected Date Results - Excel VBA - Day Month Year get mixed up
我有两个日期范围,我试图将它们转换为两个字符串OldestDate
和NewestDate
。 但是,今天我遇到了问题,其中一个日期的格式为dd/mm/yyyy
,而另一个日期的格式为mm/dd/yyyy
这是我放在两个单独工作表上的示例数据: 注意,我复制了“日期”格式单元格旁边的单元格内容以供视觉参考,但在我的实际数据中,只有“日期”列。
和
这是我用来转换为字符串和调试输出的代码:
Public Sub Get_Date()
DateHeader = "A"
Set rng = Application.ActiveSheet.Range(DateHeader & "1:" & DateHeader & Cells(Rows.Count, 1).End(xlUp).Offset(1).Row)
OldestDate = Format(WorksheetFunction.min(rng), "dd/mm/yyyy")
Debug.Print OldestDate
NewestDate = Format(WorksheetFunction.Max(rng), "dd/mm/yyyy")
Debug.Print NewestDate
'20200908
'Sept 8, 2020
aDate = Split(OldestDate, "/")
If UBound(aDate) = 2 Then
sDay = aDate(0)
If Len(sDay) = 1 Then
sDay = "0" & sDay
End If
sMonth = aDate(1)
If Len(sMonth) = 1 Then
sMonth = "0" & sMonth
End If
sYear = aDate(2)
End If
OldestDateStr = sYear & sMonth & sDay
Debug.Print OldestDateStr
aDate = Split(NewestDate, "/")
If UBound(aDate) = 2 Then
sDay = aDate(0)
If Len(sDay) = 1 Then
sDay = "0" & sDay
End If
sMonth = aDate(1)
If Len(sMonth) = 1 Then
sMonth = "0" & sMonth
End If
sYear = aDate(2)
End If
NewestDateStr = sYear & sMonth & sDay
Debug.Print NewestDateStr
End Sub
控制台/调试:
7/10/2020 ' This is Correct
8/10/2020 ' This is Correct
20201007 ' This is Correct
20201008 ' This is Correct
8/17/2020 ' Incorrect
8/18/2020 ' Incorrect
20201708 ' Incorrect
20201808 ' Incorrect
我采取了一种解决方法与调试相比,只是刮掉了月/年,然后在第一天硬编码 1 并使用函数EoMonth
来获得最后一天。 这被用来创建一个 URL 以根据日期进行查询,查询将花费更长的时间并有额外的数据,但是对我来说没关系,我宁愿拥有 100% 的可靠性。
这是新代码,阅读起来也不那么复杂:)
Public Sub Get_Date()
DateHeader = "A"
Set rng = Application.ActiveSheet.Range(DateHeader & "1:" & DateHeader & Cells(Rows.Count, 1).End(xlUp).Offset(1).Row)
Dim OldestDate As Date, NewestDate As Date
OldestDate = Format(WorksheetFunction.min(rng), "mm/yyyy")
Debug.Print OldestDate
NewestDate = Format(WorksheetFunction.Max(rng), "mm/yyyy")
Debug.Print NewestDate
'20200908
'Sept 8, 2020
'OldestDate
aDate = Split(OldestDate, "/")
sYear = aDate(2)
sMonth = aDate(0)
If Len(sMonth) = 1 Then
sMonth = "0" & sMonth
End If
sDay = "01"
OldestDateStr = sYear & sMonth & sDay
Debug.Print OldestDateStr
'NewestDate
aDate = Split(NewestDate, "/")
sYear = aDate(2)
sMonth = aDate(0)
If Len(sMonth) = 1 Then
sMonth = "0" & sMonth
End If
sDay = Day(Application.WorksheetFunction.EoMonth(NewestDate , 0))
NewestDateStr = sYear & sMonth & sDay
Debug.Print NewestDateStr
End Sub
调试:(注意我将一个日期更改为 Nov 只是为了测试)
10/1/2020
11/1/2020
20201001
20201130
8/1/2020
8/1/2020
20200801
20200830
Format 将一次性完成此操作:
OldestDateStr = Format(WorksheetFunction.min(rng), "yyyymmdd")
Debug.Print OldestDateStr
NewestDateStr = Format(WorksheetFunction.Max(rng), "yyyymmdd")
Debug.Print NewestDateStr
如果您的单元格值是格式化为“反向”美国格式mm/dd/yyyy 的文本日期,并且您不在美国环境中,则可以使用此函数将这些值转换为真实的日期值:
' Converts a US formatted date/time string to a date value.
'
' Examples:
' 7/6/2016 7:00 PM -> 2016-07-06 19:00:00
' 7/6 7:00 PM -> 2018-07-06 19:00:00 ' Current year is 2018.
' 7/6/46 7:00 PM -> 1946-07-06 19:00:00
' 8/9-1982 9:33 -> 1982-08-09 09:33:00
' 2/29 14:21:56 -> 2039-02-01 14:21:56 ' Month/year.
' 2/39 14:21:56 -> 1939-02-01 14:21:56 ' Month/year.
' 7/6/46 7 -> 1946-07-06 00:00:00 ' Cannot read time.
' 7:32 -> 1899-12-30 07:32:00 ' Time value only.
' 7:32 PM -> 1899-12-30 19:32:00 ' Time value only.
' 7.32 PM -> 1899-12-30 19:32:00 ' Time value only.
' 14:21:56 -> 1899-12-30 14:21:56 ' Time value only.
'
' 2018-03-31. Gustav Brock. Cactus Data ApS, CPH.
'
Public Function CDateUs( _
ByVal Expression As String) _
As Date
Const PartSeparator As String = " "
Const DateSeparator As String = "/"
Const DashSeparator As String = "-"
Const MaxPartCount As Integer = 2
Dim Parts As Variant
Dim DateParts As Variant
Dim DatePart As Date
Dim TimePart As Date
Dim Result As Date
' Split expression into maximum two parts.
Parts = Split(Expression, PartSeparator, MaxPartCount)
If IsDate(Parts(0)) Then
' A date or time part is found.
' Replace dashes with slashes.
Parts(0) = Replace(Parts(0), DashSeparator, DateSeparator)
If InStr(1, Parts(0), DateSeparator) > 1 Then
' A date part is found.
DateParts = Split(Parts(0), DateSeparator)
If UBound(DateParts) = 2 Then
' The date includes year.
DatePart = DateSerial(DateParts(2), DateParts(0), DateParts(1))
Else
If IsDate(CStr(Year(Date)) & DateSeparator & Join(DateParts, DateSeparator)) Then
' Use current year.
DatePart = DateSerial(Year(Date), DateParts(0), DateParts(1))
Else
' Expression contains month/year.
DatePart = CDate(Join(DateParts, DateSeparator))
End If
End If
If UBound(Parts) = 1 Then
If IsDate(Parts(1)) Then
' A time part is found.
TimePart = CDate(Parts(1))
End If
End If
Else
' A time part it must be.
' Concatenate an AM/PM part if present.
TimePart = CDate(Join(Parts, PartSeparator))
End If
End If
Result = DatePart + TimePart
CDateUs = Result
End Function
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.