Zhelkus Posted November 5, 2009 Posted November 5, 2009 Hiya! I'm building a list of files with their respective dates in order to reorganize my music collection. Foobar can store filetimes in tags and then maintain the library from there. I intend to make use of this by tagging all my MP3s with the correct file times of the dates I obtained my songs (recently switched to fb2k and they're all in random order atm).Well, that's the background of it. What I'm doing is building a script that will read the lines in a filelist that only contains the dates in 14 digit string format and then create a new list with every line read written into a new file with the filetime format (intervals since January 1, 1601).My problem is that I can't find a way to print the $tagFILETIME structure I need to write to the MP3 tags. This is my script (it's pretty short but it doesn't need to do any more):;Date converter for MP3 Database List ;Scans for file with date in year-month-day-hour-minute-second string format and creates a new file with the same dates in Windows time format #include <Date.au3> $srceList = "C:\Users\Zhelkus\Documents\AutoIT Scripts\Date list\The Ultimate List - Dates Only.txt" $inList = FileOpen($srceList, 0) $destList = "C:\Users\Zhelkus\Documents\AutoIT Scripts\Date list\The Ultimate List - Dates Only -> System Converted.txt" $outList = FileOpen($destList, 10) FileClose($outList) $outList = FileOpen($destList, 1) While 1 $line = FileReadLine($inList) If @error Then ExitLoop MsgBox(0,0.5, $line) ;just to see if everything went well $tYear = StringLeft($line, 4) $tMon = StringLeft(StringTrimLeft($line, 4), 2) $tDay = StringLeft(StringTrimLeft($line, 6), 2) $tHour = StringLeft(StringTrimLeft($line, 8), 2) $tMin = StringLeft(StringTrimLeft($line, 10), 2) $tSec = StringLeft(StringTrimLeft($line, 12), 2) ;~ FileWriteLine($outList, _Date_Time_FileTimeToSystemTime($line)) ;just ignore $time = _Date_Time_EncodeFileTime($tMon, $tDay, $tYear, $tHour, $tMin, $tSec) MsgBox(0,0, _Date_Time_FileTimeToStr($time)) ;more testing... damn WEndI'd appreciate any help
Authenticity Posted November 5, 2009 Posted November 5, 2009 FileWrite($outList, DllStructGetData($time, "Hi") * 4294967296 + DllStructGetData($time, "Lo") & @CRLF) Then to get the it into $tagFILETIME: $iTime = DllStructGetData($time, "Hi") * 4294967296 + DllStructGetData($time, "Lo") ; or FileReadLine $tFT = DllStructCreate($tagFILETIME) DllStructSetData($tFT, "Hi", $iTime / 4294967296) DllStructSetData($tFT, "Lo", BitAND($iTime, 0xFFFFFFFF)) MsgBox(0, 0, _Date_Time_FileTimeToStr($tFT)) ;more testing... damn
Zhelkus Posted November 5, 2009 Author Posted November 5, 2009 FileWrite($outList, DllStructGetData($time, "Hi") * 4294967296 + DllStructGetData($time, "Lo") & @CRLF) This is excellent! It's just the string I need! I think I may not know the proper naming after all... I'm curious as to how the new file time was calculated because I spent half an hour going through the help file and I concluded it had to be general knowledge . Now, I just tried it and the timestamp was imported into the library successfully but it was 5 hours delayed... I had this time string: 20090221091755 (original list) changed into this: 128796814750000000 (new list with windows file time) where it should have read this: 2009-02-21 09:17:55 (expected string-"ified" time) wrote this to the tag instead: 2009-02-21 04:17:55 (how it showed in foobar) Any ideas? Should I just go about adding 5 hours to every string I pick up from the source list? If so, how would I make sure that the string remains a valid time string... ??
whim Posted November 5, 2009 Posted November 5, 2009 Any ideas? Should I just go about adding 5 hours to every string I pick up from the source list? If so, how would I make sure that the string remains a valid time string... ??just a long shot, but could this be a timezone problem ?cheers,whim
Authenticity Posted November 5, 2009 Posted November 5, 2009 It shouldn't, it's the time passed since January first 1601 so it's not calculated according to the current date or time zones, etc..#include <Date.au3> Local $iTime = 128796814750000000 Local $tFT = DllStructCreate($tagFILETIME) DllStructSetData($tFT, 1, BitAND($iTime, 0xFFFFFFFF)) DllStructSetData($tFT, 2, $iTime/4294967296) ConsoleWrite(_Date_Time_FileTimeToStr($tFT) & @CRLF)..should output 02/21/2009 09:17:55
Zhelkus Posted November 5, 2009 Author Posted November 5, 2009 just a long shot, but could this be a timezone problem ?cheers,whimIt shouldn't, it's the time passed since January first 1601 so it's not calculated according to the current date or time zones, etc....should output 02/21/2009 09:17:55Actually, I think the script works perfectly. The problem must be in foobar because I am in fact in a -5GMT zone. It's very likely that fb2k is doing the miscount... odd for it to do so tho. Anyway, thanks a lot guys! I'll just add a new line in the script for the missing hours.
GEOSoft Posted November 5, 2009 Posted November 5, 2009 If you do it that way I recommend getting the offset from the registry and using that to do the correction. If you just add the 5 hours then it is only correct in your time zone. George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!"
Zhelkus Posted November 5, 2009 Author Posted November 5, 2009 If you do it that way I recommend getting the offset from the registry and using that to do the correction. If you just add the 5 hours then it is only correct in your time zone.I don't follow... Whose registry value? Foobar's or Windows'?
GEOSoft Posted November 5, 2009 Posted November 5, 2009 I don't follow... Whose registry value? Foobar's or Windows'? Windows ;; return the offset in hours $iOffset = RegRead("HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation", "bias")/60 George Question about decompiling code? Read the decompiling FAQ and don't bother posting the question in the forums.Be sure to read and follow the forum rules. -AKA the AutoIt Reading and Comprehension Skills test.*** The PCRE (Regular Expression) ToolKit for AutoIT - (Updated Oct 20, 2011 ver:3.0.1.13) - Please update your current version before filing any bug reports. The installer now includes both 32 and 64 bit versions. No change in version number. Visit my Blog .. currently not active but it will soon be resplendent with news and views. Also please remove any links you may have to my website. it is soon to be closed and replaced with something else. "Old age and treachery will always overcome youth and skill!"
Zhelkus Posted November 5, 2009 Author Posted November 5, 2009 Windows ;; return the offset in hours $iOffset = RegRead("HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation", "bias")/60 Ooh! Excellent! That automates it even more! Sad thing now is that I'm having foobar problems with this... I've already made a thread on the other side and I'm hoping I'll get assistance fixing it. I'll post back when everything is solved.
Authenticity Posted November 5, 2009 Posted November 5, 2009 If the foobar application is subtracting 5 hours you may want to give it a FILETIME value of 5 hours more: #include <Date.au3> $line1 = "20090221091755" $tYear = StringLeft($line1, 4) $tMon = StringLeft(StringTrimLeft($line1, 4), 2) $tDay = StringLeft(StringTrimLeft($line1, 6), 2) $tHour = StringLeft(StringTrimLeft($line1, 8), 2) $tMin = StringLeft(StringTrimLeft($line1, 10), 2) $tSec = StringLeft(StringTrimLeft($line1, 12), 2) $time = _Date_Time_EncodeFileTime($tMon, $tDay, $tYear, $tHour, $tMin, $tSec) ConsoleWrite(DllStructGetData($time, "Hi") * 4294967296 + DllStructGetData($time, "Lo") & @CRLF) $iTime = DllStructGetData($time, "Hi") * 4294967296 + DllStructGetData($time, "Lo") + 180000000000 ; 10^7*5*60*60. DllStructSetData($time, "Hi", $iTime/4294967296) DllStructSetData($time, "Lo", BitAND($iTime, 0xFFFFFFFF)) ConsoleWrite(_Date_Time_FileTimeToStr($time) & @CRLF)
Zhelkus Posted November 5, 2009 Author Posted November 5, 2009 If the foobar application is subtracting 5 hours you may want to give it a FILETIME value of 5 hours more: #include <Date.au3> $line1 = "20090221091755" $tYear = StringLeft($line1, 4) $tMon = StringLeft(StringTrimLeft($line1, 4), 2) $tDay = StringLeft(StringTrimLeft($line1, 6), 2) $tHour = StringLeft(StringTrimLeft($line1, 8), 2) $tMin = StringLeft(StringTrimLeft($line1, 10), 2) $tSec = StringLeft(StringTrimLeft($line1, 12), 2) $time = _Date_Time_EncodeFileTime($tMon, $tDay, $tYear, $tHour, $tMin, $tSec) ConsoleWrite(DllStructGetData($time, "Hi") * 4294967296 + DllStructGetData($time, "Lo") & @CRLF) $iTime = DllStructGetData($time, "Hi") * 4294967296 + DllStructGetData($time, "Lo") + 180000000000 ; 10^7*5*60*60. DllStructSetData($time, "Hi", $iTime/4294967296) DllStructSetData($time, "Lo", BitAND($iTime, 0xFFFFFFFF)) ConsoleWrite(_Date_Time_FileTimeToStr($time) & @CRLF) Thanks mate, tho I already tried that. The problem I'm having is that fb2k adds the same Added Date to the database for two different filetime strings (one normal and the other 5 hours behind). I made a link in the post prior to this one in case anybody's curious but I doubt it can be fixed with AutoIt, it seems more like a problem with fb2k. So far I haven't gotten any meaningful response. I'll just have to wait it out, most of that community is European so they might log in later.
Zhelkus Posted November 6, 2009 Author Posted November 6, 2009 Well, I managed to fix my problem. It was in fact an issue with Foobar. In the end I was able to reorder my music database and I just wanted to finish this thread by saying thanks. Here's the final draft of my script: expandcollapse popup;Date converter for MP3 Database List ;Reads line in list with date in year-month-day-hour-minute-second string format and creates a new file list with the same dates in Windows time format #include <Date.au3> $srceList = "C:\Users\Zhelkus\Documents\AutoIT Scripts\Date list\The Ultimate List - Dates Only.txt" $inList = FileOpen($srceList, 0) $destList = "C:\Users\Zhelkus\Documents\AutoIT Scripts\Date list\The Ultimate List - Dates Only - System Converted.txt" $outList = FileOpen($destList, 10) FileClose($outList) $tOffset = RegRead("HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation", "bias")/60 Dim $n = 0 $outList = FileOpen($destList, 1) Dim $time1 = 0 ;to compare with previous line in list While 1 $line = FileReadLine($inList) If @error Then ExitLoop $n += 1 ToolTip($n, 0, 0) $line = Number($line) $tYear = StringLeft($line, 4) $tMon = StringLeft(StringTrimLeft($line, 4), 2) $tDay = StringLeft(StringTrimLeft($line, 6), 2) $tHour = StringLeft(StringTrimLeft($line, 8), 2) $tMin = StringLeft(StringTrimLeft($line, 10), 2) $tSec = StringLeft(StringTrimLeft($line, 12), 2) $line = _DateAdd('h', $tOffset, $tYear & "/" & $tMon & "/" & $tDay & " " & $tHour & ":" & $tMin & ":" & $tSec) $tYear = StringLeft($line, 4) $tMon = StringLeft(StringTrimLeft($line, 5), 2) $tDay = StringLeft(StringTrimLeft($line, 8), 2) $tHour = StringLeft(StringTrimLeft($line, 11), 2) $tMin = StringLeft(StringTrimLeft($line, 14), 2) $tSec = StringLeft(StringTrimLeft($line, 17), 2) $iStamp = _Date_Time_EncodeFileTime($tMon, $tDay, $tYear, $tHour, $tMin, $tSec) $time2 = DllStructGetData($iStamp, "Hi") * 4294967296 + DllStructGetData($iStamp, "Lo") While $time2 <= $time1 $time2 += 10000000; to make sure that all lines are different in case files have same dates: +1 second WEnd $time1 = $time2 FileWriteLine($outList, $time2) WEnd It's a bit noobish but it did what I wanted it to do.
bruming Posted March 28, 2014 Posted March 28, 2014 FileWrite($outList, DllStructGetData($time, "Hi") * 4294967296 + DllStructGetData($time, "Lo") & @CRLF) Then to get the it into $tagFILETIME:$iTime = DllStructGetData($time, "Hi") * 4294967296 + DllStructGetData($time, "Lo") ; or FileReadLine $tFT = DllStructCreate($tagFILETIME) DllStructSetData($tFT, "Hi", $iTime / 4294967296) DllStructSetData($tFT, "Lo", BitAND($iTime, 0xFFFFFFFF)) MsgBox(0, 0, _Date_Time_FileTimeToStr($tFT)) ;more testing... damn Hi Authenticity, This code works perfectly for decoding a $tagFILETIME number back into a timestamp. I can't find where the number 4294967296 comes from. Can you explain what this number represents? Thanks.
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now