Sign in to follow this  
Followers 0
Zhelkus

Need newbie help with $tagFILETIME

14 posts in this topic

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
WEnd

I'd appreciate any help :)

Share this post


Link to post
Share on other sites



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

Share this post


Link to post
Share on other sites

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... B) 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... B) ??

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

just a long shot, but could this be a timezone problem ?

cheers,

whim

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..

..should output 02/21/2009 09:17:55

Actually, 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.

Share this post


Link to post
Share on other sites

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!"

Share this post


Link to post
Share on other sites

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'?

Share this post


Link to post
Share on other sites

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!"

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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)

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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:

;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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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 account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0