FYI, results may have unicode hidden characters. I think the reason has to do with this:
https://devblogs.microsoft.com/oldnewthing/20150506-00/?p=44924 . You may need to strip the hidden characters depending on what you are doing.
I was trying to get the "Last Saved Date" of a file then convert that value to YYYYMMDDHH24MISS. My eventual intention was to use the converted value to set the created or modified date. I tried using (the American version) of this
https://autohotkey.com/board/topic/18760-date-parser-convert-any-date-format-to-yyyymmddhh24miss/ . However, I kept getting YYYYMMDDHH24MISS for the current local date and time, not the last saved date. I found I needed to first convert the "Last Saved Date" to ascii, per
https://autohotkey.com/board/topic/92405-is-it-possible-to-remove-all-unicode-characters/ . Then I could date parse it to YYYYMMDDHH24MISS.
I haven't bothered to test that my problem was indeed hidden unicode characters, such as a U+202A at the beginning of the Last Saved Date property, I just know converting to ascii worked for me and thought it might help someone else.
Code: Select all
FileSelectFile, FilePath
datelastsaved := FGP_Value(FilePath,154)
; RegExReplace(datelastsaved,"[^0-9/APM:\s]+") also works
datelastsavedfix := RegExReplace(datelastsaved,"[^[:ascii:]]")
datelastparsed := DateParse(datelastsavedfix)
msgbox % datelastparsed
FGP_Init() {
static PropTable
if (!PropTable) {
PropTable := {Name: {}, Num: {}}, Gap := 0
oShell := ComObjCreate("Shell.Application")
oFolder := oShell.NameSpace(0)
while (Gap < 11)
if (PropName := oFolder.GetDetailsOf(0, A_Index - 1)) {
PropTable.Name[PropName] := A_Index - 1
PropTable.Num[A_Index - 1] := PropName
Gap := 0
}
else
Gap++
}
return PropTable
}
FGP_Value(FilePath, Property) {
static PropTable := FGP_Init()
if ((PropNum := PropTable.Name[Property] != "" ? PropTable.Name[Property]
: PropTable.Num[Property] ? Property : "") != "") {
SplitPath, FilePath, FileName, DirPath
oShell := ComObjCreate("Shell.Application")
oFolder := oShell.NameSpace(DirPath)
oFolderItem := oFolder.ParseName(FileName)
if (PropVal := oFolder.GetDetailsOf(oFolderItem, PropNum))
return PropVal
return 0
}
return -1
}
DateParse(str, americanOrder=1) {
static monthNames := "(?:Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\w*"
, dayAndMonth := "(?:(\d{1,2}|" . monthNames . ")[\s\.\-\/,]+)?(\d{1,2}|" . monthNames . ")"
If RegExMatch(str, "i)^\s*(?:(\d{4})([\s\-:\/])(\d{1,2})\2(\d{1,2}))?"
. "(?:\s*[T\s](\d{1,2})([\s\-:\/])(\d{1,2})(?:\6(\d{1,2})\s*(?:(Z)|(\+|\-)?"
. "(\d{1,2})\6(\d{1,2})(?:\6(\d{1,2}))?)?)?)?\s*$", i) ;ISO 8601 timestamps
year := i1, month := i3, day := i4, t1 := i5, t2 := i7, t3 := i8
Else If !RegExMatch(str, "^\W*(\d{1,2}+)(\d{2})\W*$", t){
RegExMatch(str, "i)(\d{1,2})" ;hours
. "\s*:\s*(\d{1,2})" ;minutes
. "(?:\s*:\s*(\d{1,2}))?" ;seconds
. "(?:\s*([ap]m))?", t) ;am/pm
StringReplace, str, str, %t%
If Regexmatch(str, "i)(\d{4})[\s\.\-\/,]+" . dayAndMonth, d) ;2004/22/03
year := d1, month := d3, day := d2
Else If Regexmatch(str, "i)" . dayAndMonth . "[\s\.\-\/,]+(\d{2,4})", d) ;22/03/2004 or 22/03/04
year := d3, month := d2, day := d1
If (RegExMatch(day, monthNames) or americanOrder and !RegExMatch(month, monthNames)) ;try to infer day/month order
tmp := month, month := day, day := tmp
}
f = %A_FormatFloat%
SetFormat, Float, 02.0
d := (StrLen(year) == 2 ? "20" . year : (year ? year : A_YYYY))
. ((month := month + 0 ? month : InStr(monthNames, SubStr(month, 1, 3)) // 4 ) > 0 ? month + 0.0 : A_MM)
. ((day += 0.0) ? day : A_DD)
. t1 + (t1 == 12 ? t4 = "am" ? -12.0 : 0.0 : t4 = "pm" ? 12.0 : 0.0)
. t2 + 0.0 . t3 + 0.0
SetFormat, Float, %f%
return, d
}