I have dates in an Excel workbook with the format of
Thu Feb 7 09:38:41 UTC+10 2019
They are formatted as general/text. Need to convert into an actual Excel date/time to sort.
Tried parsing and splitting but doesn't always works and is very clunky
Parsing seems the only sensible approach. Looks like a job for a regular expression though.
This function requires referencing the VBScript_RegEp_55
type library:
Public Function ParseUtcDate(ByVal value As String, Optional ByVal utcOffset As Double = 0) As Date
Const pattern As String = "(\w+) (\w+) (\d+) (\d\d:\d\d:\d\d) UTC((\+|\-)\d+) (\d\d\d\d)"
With New RegExp
.IgnoreCase = True
.Global = True
.pattern = pattern
Dim mc As MatchCollection
Set mc = .Execute(value)
End With
Dim m As Match
Set m = mc(0)
Dim monthNamePart As String
monthNamePart = m.SubMatches(1)
Dim dayOfMonthPart As String
dayOfMonthPart = m.SubMatches(2)
Dim timePart As String
timePart = m.SubMatches(3)
Dim utcOffsetPart As String
utcOffsetPart = m.SubMatches(4)
Dim yearPart As String
yearPart = m.SubMatches(6)
Dim dateParts As Variant
dateParts = VBA.Array(monthNamePart, dayOfMonthPart, yearPart, timePart)
Dim formattedDate As String
formattedDate = VBA.Join(dateParts, " ")
Dim offset As Double
offset = CDbl(utcOffsetPart)
Dim offsetHours As Double
offsetHours = offset / 24
Dim targetOffset As Double
targetOffset = utcOffset / 24
ParseUtcDate = CDate(formattedDate) - offsetHours + targetOffset
End Function
Usage:
?ParseUtcDate("Thu Feb 7 09:38:41 UTC+10 2019", 10)
2/7/2019 9:38:41 AM
?ParseUtcDate("Thu Feb 7 09:38:41 UTC+10 2019")
2/6/2019 11:38:41 PM
?ParseUtcDate("Thu Feb 7 09:38:41 UTC+10 2019", -5)
2/6/2019 6:38:41 PM
Also, out of interest, if you have Excel 2016+ with the TEXTJOIN
function, you can parse the segments with FILTERXML
and then create a date/time string which Excel will interpret as a real date:
Local time
=TEXTJOIN(" ",TRUE,INDEX(FILTERXML("<t><s>" & SUBSTITUTE(A2," ","</s><s>")& "</s></t>","//s"),N(IF(1,{3,2,6}))))
+FILTERXML("<t><s>" & SUBSTITUTE(A2," ","</s><s>")& "</s></t>","//s[4]")
UTC Time
=TEXTJOIN(" ",TRUE,INDEX(FILTERXML("<t><s>" & SUBSTITUTE(A2," ","</s><s>")& "</s></t>","//s"),N(IF(1,{3,2,6}))))
+FILTERXML("<t><s>" & SUBSTITUTE(A2," ","</s><s>")& "</s></t>","//s[4]")
-SUBSTITUTE(FILTERXML("<t><s>" & SUBSTITUTE(A2," ","</s><s>")& "</s></t>","//s[5]"),"UTC","")/24
I don't have any 'clunky' VBA code but I'e worked up a worksheet formula.
'for localized date/time
=SUM(DATEVALUE(TRIM(MID(REPLACE(A2, FIND(" ", A2, 9), 16, ", "), 4, LEN(A2)))),
TIMEVALUE(MID(A2, FIND(" ", A2, 9)+1, 8)))
'for UTC date time
=SUM(DATEVALUE(TRIM(MID(REPLACE(A2, FIND(" ", A2, 9), 16, ", "), 4, LEN(A2)))),
TIMEVALUE(MID(A2, FIND(" ", A2, 9)+1, 8)),
-PRODUCT(VALUE(MID(A2, FIND("UTC", A2)+3, 3)), TIME(1, 0, 0)))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.