mIRC Home    About    Download    Register    News    Help

Print Thread
$file().mtime granularity in microseconds #267116 04/04/20 02:53 PM
Joined: Feb 2015
Posts: 105
kap Offline OP
Vogon poet
OP Offline
Vogon poet
Joined: Feb 2015
Posts: 105
I've just learned that on Windows NTFS, max time resolution is 100 ns. On FAT is is/was 2 s (https://superuser.com/questions/937380/get-creation-time-of-file-in-milliseconds)

Currently I've a script that queries $file(%file).mtime, but it returns a $ctime value (in seconds) where I would really like it to be more precise.

I could query via COM via WMI CIM_DataFile for the LastModified attribute, but this is too cumbersome. (and I would need some help with this)

Could new props be added to $file for .ctime .mtime and .atime that returns more precise times?

Thanks!



GNU Terry Pratchett
Re: $file().mtime granularity in microseconds [Re: kap] #267117 04/04/20 03:15 PM
Joined: Jan 2004
Posts: 1,388
maroon Offline
Hoopy frood
Offline
Hoopy frood
Joined: Jan 2004
Posts: 1,388
This change could be coordinated with the https://forums.mirc.com/ubbthreads.php/topics/267046/improve-ticks-accuracy or https://forums.mirc.com/ubbthreads.php/topics/266944/ctimems-with-millisecond-decimal-value request.

In addition, the .mtimeMS, or whatever it will be called, could also be expanded to support the new date range which goes back to 1601. If a file's timestamp is changed to be "Jan 1 1970 12:00:00am", the returned value for .mtime or .ctime is $calc( $daylight + $timestamp). However, setting the timestamp as "Dec 31, 1969 11:59:59" and earlier always returns -1, the same as happens for timestamps 1/1/3001 midnight and later - even though $asctime supports years 1601-9999.

Windows has a SystemTimeAsFiletime function which returns a signed int64 with a value equivalent to these millisecond file timestamps. When I call that function from a .dll, it seems to return values changing in increments of 10000, which would be a resolution in millisecs. The QueryPerformanceCounter function can return a benchmarking value with a narrower and more variable increment, but it's also not consistent across Windows versions. Beginning Win10 around release 1809, the QPC value increments 10 million per second for everyone, while earlier versions of Win10 and earlier Windows versions increased per second at a rate somewhere around one thousandth of the cpu's gigahertz speed.

Re: $file().mtime granularity in microseconds [Re: maroon] #267118 04/04/20 03:38 PM
Joined: Jul 2006
Posts: 3,715
W
Wims Offline
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 3,715
Agreed, these kind of changes need to go together, if you get such a value in .mtime but you cannot convert it to a date/time with $asctime, it's not so useful.


Looking for a good help channel about mIRC? Check #mircscripting @ irc.swiftirc.net
Re: $file().mtime granularity in microseconds [Re: maroon] #267119 04/04/20 05:46 PM
Joined: Feb 2015
Posts: 105
kap Offline OP
Vogon poet
OP Offline
Vogon poet
Joined: Feb 2015
Posts: 105
Especially with the advent of SSD drives, file writes are just about instant.

I've got mirc and scripts installed on a SSD on a NTFS file system.

Bit of a simple example, but the following code always returns: File has NOT changed, for me:

Code
alias t1 {
  var %file test.txt

  write -ca %file This is a sample message [1]
  var -s %mtime.1 $file(%file).mtime

  ; <...snip here's a lot of code...>

  write -a %file This is a sample message [2]
  var -s %mtime.2 $file(%file).mtime

  if (%mtime.2 > %mtime.1) echo -ag File ' $+ %file $+ ' has changed.
  else echo -ag File ' $+ %file $+ ' has NOT changed.
}


This because %mtime.1 is equal to %mtime.2 on my system.


GNU Terry Pratchett
Re: $file().mtime granularity in microseconds [Re: kap] #267120 04/04/20 06:45 PM
Joined: Feb 2015
Posts: 105
kap Offline OP
Vogon poet
OP Offline
Vogon poet
Joined: Feb 2015
Posts: 105
Pulled my hair out a bit, but finally got something working:

Code
alias CIM_DataFile {
  .comopen Locator WbemScripting.SWbemLocator
  if ($comerr) {
    .comclose Locator
    return
  }
  .comclose Locator $com(Locator,ConnectServer,3,dispatch* Services)
  if ($comerr) {
    .comclose Services 
    return
  }
  .comclose Services $com(Services,ExecQuery,3,bstr*,Select * from CIM_DataFile where Name = " $+ $replace($1-,\,\\) $+ ",dispatch* CIMDF)
  if ($com(CIMDF)) var %ret $comval(CIMDF,1,$prop)
  :error
  if ($com(Locator)) .comclose Locator
  if ($com(Services)) .comclose Services
  if ($com(CIMDF)) .comclose CIMDF
  return %ret
}


Code
  //echo -ag $CIM_DataFile(C:\Users\acvxq\AppData\Roaming\mIRC\mirc.ini).LastModified


Thus:
Code
alias t1 {
  var -s %file $mircdirtest.txt

  write -ca %file This is a sample message [1]
  var -s %mtime.1 $CIM_DataFile(%file).LastModified

  ; <...snip here's a lot of code...>

  write -a %file This is a sample message [2]
  var -s %mtime.2 $CIM_DataFile(%file).LastModified

  if (%mtime.2 > %mtime.1) echo -ag File ' $+ %file $+ ' has changed.
  else echo -ag File ' $+ %file $+ ' has NOT changed.
}



File has changed.

Last edited by kap; 04/04/20 07:08 PM. Reason: fixed mistake in code and added t1 back in, this time it works!

GNU Terry Pratchett