Project Nayuki


Windows timestamp accessor library

With help from C#, now Java and Python programs can get and set high-precision Windows file timestamps.

Windows stores timestamps for each file and folder in a file system to the granularity of 100 ns. However, most tools that are not specifically designed for Windows cannot operate at this precision, especially cross-platform file formats and programming languages that have a strong presence in the Unix world. For example, file archive formats might only store timestamps to the granularity of one second, or programming languages might only let you query the modification timestamp but not the creation timestamp. Furthermore, some programming languages don’t provide a way to set any file timestamps at all.

I’ve implemented a standalone Windows C# program that can get and set all the 3 types of file/folder timestamps at the full native precision, and libraries in Java and Python that interface with the C# program so these languages can benefit from the ability to manipulate these timestamps. Unicode paths are supported.

This set of software can be considered a meta-tool – a tool for building application tools. With the library, it’s easy to write programs like these: A tool that adds an offset to a file’s timestamps, a tool to copy timestamps from one file to another, a tool to archive file timestamps to a text file.

Download

Source code:

Binary:

Extras:

The EXE file must be placed in the current working directory when running the Java VM or Python interpreter.

API and examples

Java

API summary:

class WindowsTimestampAccessor {
    public WindowsTimestampAccessor();
    public void dispose();
    
    public long getCreationTime(File f);
    public long getModificationTime(File f);
    public long getAccessTime(File f);
    
    public void setCreationTime(File f, long ticks);
    public void setModificationTime(File f, long ticks);
    public void setAccessTime(File f, long ticks);
    
    public static int[] ticksToDatetime(long ticks);
    public static long datetimeToTicks(int... dt);
}

Usage example:

WindowsTimestampAccessor wt = new WindowsTimestampAccessor();
try {
    long ct = wt.getCreationTime(new File("hello.txt"));
    wt.setCreationTime(new File("goodbye.txt"), ct + 864000000000L);  // One day later
    System.out.println(wt.getCreationTime(new File("你好.png")));  // Supports Unicode
} finally {
    wt.dispose();
}

Notes:

Python

API summary:

class WindowsTimestampAccessor:
    def __init__(self)
    def dispose(self)
    
    def __enter__(self)          # with-statement
    def __exit__(self, t, v, b)  # with-statement
    
    def get_creation_time    (self, path)  # Returns int
    def get_modification_time(self, path)  # Returns int
    def get_access_time      (self, path)  # Returns int
    
    def set_creation_time    (self, path, ticks)  # Returns None
    def set_modification_time(self, path, ticks)  # Returns None
    def set_access_time      (self, path, ticks)  # Returns None

# Module functions
def ticks_to_datetime(ticks)  # Returns datetime.datetime object
def datetime_to_ticks(dt)     # Returns int

Usage example:

import wintimestamp

# Using with-statement (preferred)
with wintimestamp.WindowsTimestampAccessor() as wt:
    t = wt.get_modification_time("myfile.doc")
    print wt.ticks_to_datetime(t)
    print "Ticks: ", t

# Old-style resource management
wt = wintimestamp.WindowsTimestampAccessor()
try:
    # Supports Unicode file names
    wt.set_creation_time(u"\u4F60\u597D.png", 621355968000000000)
finally:
    wt.dispose()

Notes:

C# program’s protocol

Syntax for both standard input and output (stdin, stdout):

Commands:

Usage example:

C:\>WindowsTimestampAccessor.exe
GetModificationTime	C:\
ok	635462611321362140
SetCreationTime	D:\pic.jpg	635463434961076893
ok
GetFoobar
error
GetAccessTime	X:\notexist
error
SetAccessTime	C:\thing.doc	abc123
error

Notes:

Notes