mIRC Homepage

$file().mtime granularity in microseconds

Posted By: kap

$file().mtime granularity in microseconds - 04/04/20 02:53 PM

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!

Posted By: maroon

Re: $file().mtime granularity in microseconds - 04/04/20 03:15 PM

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.
Posted By: Wims

Re: $file().mtime granularity in microseconds - 04/04/20 03:38 PM

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.
Posted By: kap

Re: $file().mtime granularity in microseconds - 04/04/20 05:46 PM

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.
Posted By: kap

Re: $file().mtime granularity in microseconds - 04/04/20 06:45 PM

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.
© 2020 mIRC Discussion Forums