File modification time

From Rosetta Code
(Redirected from File Modification Time)
Task
File modification time
You are encouraged to solve this task according to the task description, using any language you may know.
Task

Get and set the modification time of a file.

Ada[edit]

Ada does not allow you to change the date of a file but you can definitely read it:

with Ada.Directories;          use Ada.Directories;
with Ada.Text_IO;              use Ada.Text_IO;
with Ada.Calendar.Formatting;  use Ada.Calendar.Formatting;
 
procedure File_Time_Test is
begin
   Put_Line (Image (Modification_Time ("file_time_test.adb")));
end File_Time_Test;

ALGOL 68[edit]

Definition of the PROC is lifted from the Algol68 Genie documentation.

PROC get output = (STRING cmd) VOID:
IF STRING sh cmd = " " + cmd + " ; 2>&1";
   STRING output;
   execve output ("/bin/sh", ("sh", "-c", sh cmd), "", output) >= 0
THEN print (output) FI;
get output ("rm -rf WTC_1");				CO Ensure file doesn't exist CO
get output ("touch WTC_1");				CO Create file CO
get output ("ls -l --time-style=full-iso WTC_1");	CO Display its last modified time CO
get output ("touch -t 200109111246.40 WTC_1");		CO Change its last modified time CO
get output ("ls -l --time-style=full-iso WTC_1")	CO Verify it changed CO
Output:
-rw-r--r-- 1 pcl pcl 0 2015-08-10 17:57:50.279854695 +0100 WTC_1
-rw-r--r-- 1 pcl pcl 0 2001-09-11 12:46:40.000000000 +0100 WTC_1

AutoHotkey[edit]

FileGetTime, OutputVar, output.txt
MsgBox % OutputVar
FileSetTime, 20080101, output.txt
FileGetTime, OutputVar, output.txt
MsgBox % OutputVar

AWK[edit]

Works with: gawk
@load "filefuncs"
BEGIN { 

    name = "input.txt"

    # display time
    stat(name, fd)
    printf("%s\t%s\n", name, strftime("%a %b %e %H:%M:%S %Z %Y", fd["mtime"]) )

    # change time
    cmd = "touch -t 201409082359.59 " name
    system(cmd)
    close(cmd)

}

Non-GNU awk's don't have direct access to the filesystem but can execute system-commands.

#!/bin/awk -f
BEGIN {   	          # file modification time on Unix, using stat
   fn ="input.txt"

   cmd="stat " fn
   print "#", cmd
   system(cmd)            # just execute cmd

   cmd="stat -c %Y " fn   # seconds since the epoch
   print "#", cmd
   system(cmd)

   cmd="stat -c %y " fn   # human-readable format
   print "#", cmd
   system(cmd)

   print "##"
   cmd | getline x        # get output from cmd
  #print x
   close(cmd)
   
   n=split(x,stat," ")
  #for (i in stat) { print i, stat[i] }
   print "file:", fn
   print "date:", stat[1], "time:", stat[2]

### change filetime with touch:

   cmd="touch -t 201409082359.59 " fn
   print "#", cmd; system(cmd)
   
   cmd="stat " fn
   print "#", cmd; system(cmd)
}
Output:
# stat input.txt
  File: `input.txt'
  Size: 126       	Blocks: 8          IO Block: 4096   regular file
Device: 700h/1792d	Inode: 2195620     Links: 1
Access: (0644/-rw-r--r--)  Uid: (   48/  apache)   Gid: (   48/  apache)
Access: 2014-11-05 20:18:39.000000000 -0600
Modify: 2014-11-05 20:18:39.000000000 -0600
Change: 2014-11-05 20:18:39.000000000 -0600
# stat -c %Y input.txt
1415240319
# stat -c %y input.txt
2014-11-05 20:18:39.000000000 -0600
##
file: input.txt
date: 2014-11-05 time: 20:18:39.000000000
See also

File modification time#Batch_File, #Run_BASIC, #UNIX_Shell

Batch File[edit]

Works with: Windows NT version 4
for %%f in (file.txt) do echo.%%~tf

The date/time format is dependent on the user's locale, like the contents of the %DATE% and %TIME% built-ins. There is no built-in way of setting a file's modification time.

BBC BASIC[edit]

      DIM ft{dwLowDateTime%, dwHighDateTime%}
      DIM st{wYear{l&,h&}, wMonth{l&,h&}, wDayOfWeek{l&,h&}, \
      \      wDay{l&,h&}, wHour{l&,h&}, wMinute{l&,h&}, \
      \      wSecond{l&,h&}, wMilliseconds{l&,h&} }
      
      REM File is assumed to exist:
      file$ = @tmp$ + "rosetta.tmp"
      
      REM Get and display the modification time:
      file% = OPENIN(file$)
      SYS "GetFileTime", @hfile%(file%), 0, 0, ft{}
      CLOSE #file%
      SYS "FileTimeToSystemTime", ft{}, st{}
      date$ = STRING$(16, CHR$0)
      time$ = STRING$(16, CHR$0)
      SYS "GetDateFormat", 0, 0, st{}, 0, date$, LEN(date$) TO N%
      date$ = LEFT$(date$, N%-1)
      SYS "GetTimeFormat", 0, 0, st{}, 0, time$, LEN(time$) TO N%
      time$ = LEFT$(time$, N%-1)
      PRINT date$ " " time$
      
      REM Set the modification time to the current time:
      SYS "GetSystemTime", st{}
      SYS "SystemTimeToFileTime", st{}, ft{}
      file% = OPENUP(file$)
      SYS "SetFileTime", @hfile%(file%), 0, 0, ft{}
      CLOSE #file%

C[edit]

POSIX utime()[edit]

utime() has a precision of one second. This program would truncate the time to the last second, losing precision if the filesystem is more precise.

Library: POSIX
#include <sys/stat.h>
#include <stdio.h>
#include <time.h>
#include <utime.h>

const char *filename = "input.txt";

int main() {
  struct stat foo;
  time_t mtime;
  struct utimbuf new_times;

  if (stat(filename, &foo) < 0) {
    perror(filename);
    return 1;
  }
  mtime = foo.st_mtime; /* seconds since the epoch */

  new_times.actime = foo.st_atime; /* keep atime unchanged */
  new_times.modtime = time(NULL);    /* set mtime to current time */
  if (utime(filename, &new_times) < 0) {
    perror(filename);
    return 1;
  }

  return 0;
}

BSD utimes()[edit]

With BSD, utime() is obsolete. utimes() has a precision of 1 microsecond (where 1 second = 1000000 microseconds).

Library: BSD libc
#include <sys/stat.h>
#include <sys/time.h>
#include <err.h>

const char *filename = "input.txt";

int main() {
  struct stat foo;
  struct timeval new_times[2];

  if (stat(filename, &foo) < 0)
    err(1, "%s", filename);

  /* keep atime unchanged */
  TIMESPEC_TO_TIMEVAL(&new_times[0], &foo.st_atim);

  /* set mtime to current time */
  gettimeofday(&new_times[1], NULL);

  if (utimes(filename, new_times) < 0)
    err(1, "%s", filename);

  return 0;
}

POSIX utimensat()[edit]

utimensat(2) has a precision of 1 nanosecond (where 1 second = 10**9 nanoseconds). Program needs to be linked with -lrt.

Library: POSIX
Works with: POSIX version -1.2008
#include <sys/stat.h>
#include <sys/time.h>
#include <time.h>
#include <fcntl.h>
#include <stdio.h>

const char *filename = "input.txt";
 
int main() {
  struct stat foo;
  struct timespec new_times[2];
 
  if (stat(filename, &foo) < 0) {
    perror(filename);
    return 1;
  }
 
  /* keep atime unchanged */
  new_times[0] = foo.st_atim;
 
  /* set mtime to current time */
  clock_gettime(CLOCK_REALTIME, &new_times[1]);
 
  if (utimensat(AT_FDCWD, filename, new_times, 0) < 0) {
    perror(filename);
    return 1;
  }
 
  return 0;
}

Windows[edit]

Declare FILETIME modtime; and then use GetFileTime(fh, NULL, NULL, &modtime); to get the file modification time, or SetFileTime(fh, NULL, NULL, &modtime); to set it.

Library: Win32
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#include <wchar.h>

/* Print "message: last Win32 error" to stderr. */
void
oops(const wchar_t *message)
{
	wchar_t *buf;
	DWORD error;

	buf = NULL;
	error = GetLastError();
	FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
	    FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
	    NULL, error, 0, (wchar_t *)&buf, 0, NULL);

	if (buf) {
		fwprintf(stderr, L"%ls: %ls", message, buf);
		LocalFree(buf);
	} else {
		/* FormatMessageW failed. */
		fwprintf(stderr, L"%ls: unknown error 0x%x\n",
		    message, error);
	}
}

int
setmodtime(const wchar_t *path)
{
	FILETIME modtime;
	SYSTEMTIME st;
	HANDLE fh;
	wchar_t date[80], time[80];

	fh = CreateFileW(path, GENERIC_READ | FILE_WRITE_ATTRIBUTES,
	    0, NULL, OPEN_EXISTING, 0, NULL);
	if (fh == INVALID_HANDLE_VALUE) {
		oops(path);
		return 1;
	}

	/*
	 * Use GetFileTime() to get the file modification time.
	 */
	if (GetFileTime(fh, NULL, NULL, &modtime) == 0)
		goto fail;
	FileTimeToSystemTime(&modtime, &st);
	if (GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL,
	    date, sizeof date / sizeof date[0]) == 0 ||
	    GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL,
	    time, sizeof time / sizeof time[0]) == 0)
		goto fail;
	wprintf(L"%ls: Last modified at %s at %s (UTC).\n",
	    path, date, time);

	/*
	 * Use SetFileTime() to change the file modification time
	 * to the current time.
	 */
	GetSystemTime(&st);
	if (GetDateFormatW(LOCALE_USER_DEFAULT, DATE_LONGDATE, &st, NULL,
	    date, sizeof date / sizeof date[0]) == 0 ||
	    GetTimeFormatW(LOCALE_USER_DEFAULT, 0, &st, NULL,
	    time, sizeof time / sizeof time[0]) == 0)
		goto fail;
	SystemTimeToFileTime(&st, &modtime);
	if (SetFileTime(fh, NULL, NULL, &modtime) == 0)
		goto fail;
	wprintf(L"%ls: Changed to %s at %s (UTC).\n", path, date, time);

	CloseHandle(fh);
	return 0;

fail:
	oops(path);
	CloseHandle(fh);
	return 1;
}

/*
 * Show the file modification time, and change it to the current time.
 */
int
main()
{
	int argc, i, r;
	wchar_t **argv;

	/* MinGW never provides wmain(argc, argv). */
	argv = CommandLineToArgvW(GetCommandLineW(), &argc);
	if (argv == NULL) {
		oops(L"CommandLineToArgvW");
		exit(1);
	}

	if (argc < 2) {
		fwprintf(stderr, L"usage: %ls file...\n", argv[0]);
		exit(1);
	}

	r = 0;
	for (i = 1; argv[i] != NULL; i++)
		if (setmodtime(argv[i])) r = 1;
	return r;
}

C#[edit]

using System;
using System.IO;

Console.WriteLine(File.GetLastWriteTime("file.txt"));
File.SetLastWriteTime("file.txt", DateTime.Now);

C++[edit]

compiled with g++ -lboost_filesystem <sourcefile> -o <destination file>

#include <boost/filesystem/operations.hpp>
#include <ctime>
#include <iostream>

int main( int argc , char *argv[ ] ) {
   if ( argc != 2 ) {
      std::cerr << "Error! Syntax: moditime <filename>!\n" ;
      return 1 ;
   }
   boost::filesystem::path p( argv[ 1 ] ) ;
   if ( boost::filesystem::exists( p ) ) {
      std::time_t t = boost::filesystem::last_write_time( p ) ;
      std::cout << "On " << std::ctime( &t ) << " the file " << argv[ 1 ] 
	 << " was modified the last time!\n" ;
      std::cout << "Setting the modification time to now:\n" ;
      std::time_t n = std::time( 0 ) ;
      boost::filesystem::last_write_time( p , n ) ; 
      t = boost::filesystem::last_write_time( p ) ;
      std::cout << "Now the modification time is " << std::ctime( &t ) << std::endl ;
      return 0 ;
   } else {
      std::cout << "Could not find file " << argv[ 1 ] << '\n' ;
      return 2 ;
   }
}

Clojure[edit]

(import '(java.io File)
        '(java.util Date))

(Date. (.lastModified (File. "output.txt")))
(Date. (.lastModified (File. "docs")))

(.setLastModified (File. "output.txt")
                  (.lastModified (File. "docs")))

Common Lisp[edit]

Common Lisp doesn't provide a way to set the modification time. The write date can be accessed, however, using file-write-date:

(file-write-date "input.txt")

Implementations may, in addition, provide other ways of accessing these file attributes, e.g., POSIX bindings:

Works with: SBCL
(1.0.30, OS X, Intel),
Translation of: C

(sb-posix:utime takes an access time and a modification time rather than an array of two times.)

(let* ((filename "input.txt")
       (stat (sb-posix:stat filename))
       (mtime (sb-posix:stat-mtime stat)))
  (sb-posix:utime filename
		  (sb-posix:stat-atime stat)
		  (sb-posix:time)))

D[edit]

import std.stdio;
import std.file: getTimes, setTimes, SysTime;

void main() {
    auto fname = "unixdict.txt";
    SysTime fileAccessTime, fileModificationTime;
    getTimes(fname, fileAccessTime, fileModificationTime);
    writeln(fileAccessTime, "\n", fileModificationTime);
    setTimes(fname, fileAccessTime, fileModificationTime);
}

For Windows systems there is also getTimesWin(), that gives the file creation time too.

Delphi[edit]

function GetModifiedDate(const aFilename: string): TDateTime;
var
  hFile: Integer;
  iDosTime: Integer;
begin
  hFile := FileOpen(aFilename, fmOpenRead);
  iDosTime := FileGetDate(hFile);
  FileClose(hFile);
  if (hFile = -1) or (iDosTime = -1) then raise Exception.Create('Cannot read file: ' + sFilename);
  Result := FileDateToDateTime(iDosTime);
end;

procedure ChangeModifiedDate(const aFilename: string; aDateTime: TDateTime);
begin
  FileSetDate(aFileName, DateTimeToFileDate(aDateTime));
end;

E[edit]

Works with: E-on-Java
Translation of: Java

E follows the Java File interface, except that it replaces boolean success/failure returns with an ejector parameter, so that the default behavior if the client does not handle the case is not to continue ignoring the failure.

def strdate(date) {
  return E.toString(<unsafe:java.util.makeDate>(date))
}

def test(type, file) {
    def t := file.lastModified()
    println(`The following $type called ${file.getPath()} ${
            if (t == 0) { "does not exist." } else { `was modified at ${strdate(t)}` }}`)
    println(`The following $type called ${file.getPath()} ${
            escape ne { file.setLastModified(timer.now(), ne); "was modified to current time." } catch _ { "does not exist." }}`)
    println(`The following $type called ${file.getPath()} ${
            escape ne { file.setLastModified(t, ne); "was modified to previous time." } catch _ { "does not exist." }}`)
}

test("file", <file:output.txt>)
test("directory", <file:docs>)

Elixir[edit]

iex(1)> info = File.stat!("input.txt")
%File.Stat{access: :read_write, atime: {{2015, 10, 29}, {20, 44, 28}},
 ctime: {{2015, 9, 20}, {9, 5, 58}}, gid: 0, inode: 0, links: 1,
 major_device: 3, minor_device: 0, mode: 33206,
 mtime: {{2015, 10, 29}, {20, 44, 28}}, size: 45, type: :regular, uid: 0}
iex(2)> info.mtime
{{2015, 10, 29}, {20, 44, 28}}
iex(3)> File.touch!("input.txt")
:ok
iex(4)> File.stat!("input.txt")
%File.Stat{access: :read_write, atime: {{2016, 3, 7}, {23, 12, 35}},
 ctime: {{2016, 3, 7}, {23, 12, 35}}, gid: 0, inode: 0, links: 1,
 major_device: 3, minor_device: 0, mode: 33206,
 mtime: {{2016, 3, 7}, {23, 12, 35}}, size: 45, type: :regular, uid: 0}

Emacs Lisp[edit]

(nth 5 (file-attributes "input.txt")) ;; mod date+time

(set-file-times "input.txt") ;; to current-time
(set-file-times "input.txt"
                (encode-time 0 0 0  1 1 2014)) ;; to given date+time

set-file-times sets both the access time and modification time of the file. Time values are in the usual Emacs list form. Emacs file name handler magic applies to both file-attributes and set-file-times so they can act on "remote" files too.

File visiting buffers record the modification time of the file so as to guard against changes by another program. set-file-times from within Emacs doesn't update those buffer times and so looks like an external change.

Erlang[edit]

-module( file_modification_time ).

-include_lib("kernel/include/file.hrl").

-export( [task/0] ).

task() ->
       File = "input.txt",
       {ok, File_info} = file:read_file_info( File ),
       io:fwrite( "Modification time ~p~n", [File_info#file_info.mtime] ),
       ok = file:write_file_info( File, File_info#file_info{mtime=calendar:local_time()} ).

F#[edit]

open System
open System.IO

[<EntryPoint>]
let main args =
    Console.WriteLine(File.GetLastWriteTime(args.[0]))
    File.SetLastWriteTime(args.[0], DateTime.Now)
    0

Factor[edit]

"foo.txt" file-info modified>> .

Setting the modified time is not cross-platform, so here's a Unix version.

USE: io.files.info.unix

"foo.txt" now 2 hours time+ set-file-modified-time

Fortran[edit]

No facility. The INQUIRE statement for files has no keywords to ascertain the disc file's creation time, last access time, last modification time, and much else also in a standardised way so there is no way to modify these items either. A particular installation may offer library routines (written in assembler perhaps), or a modified compiler with extra features, but in general, there is no facility - other than performing a file action at the desired time.

FreeBASIC[edit]

' FB 1.05.0 Win64

' This example is taken directly from the FB documentation (see [http://www.freebasic.net/wiki/wikka.php?wakka=KeyPgFiledatetime])

#include "vbcompat.bi"  '' to use Format function

Dim filename As String, d As Double

Print "Enter a filename: "
Line Input filename

If FileExists(filename) Then
  Print "File last modified: ";
  d = FileDateTime( filename )
  Print Format( d, "yyyy-mm-dd hh:mm AM/PM" )
Else
  Print "File not found"
End If

Sleep

Sample input/output:

Output:
Enter a filename:
c:\windows\system32\kernel32.dll
File last modified: 2016-09-07 05:39 AM

Frink[edit]

Frink runs on a Java Virtual Machine (JVM) and can use any of its methods. The underlying code returns the modification time as the number of milliseconds since 1970-01-01 00:00 UTC. The following converts between Frink's human-friendly time systems and the milliseconds since the epoch.

f = newJava["java.io.File", "FileModificationTime.frink"]
epoch = #1970 UTC#
f.setLastModified[(#2022-01-01 5:00 AM# - epoch) / ms]
println[f.lastModified[] ms + epoch]
Output:
AD 2022-01-01 AM 05:00:00.000 (Sat) Mountain Standard Time

Gambas[edit]

' There is no built in command in Gambas to 'set' the modification time of a file
' A shell call to 'touch' would do it

Public Sub Main()
Dim stInfo As Stat = Stat(User.home &/ "Rosetta.txt")

Print "Rosetta.txt was last modified " & Format(stInfo.LastModified, "dd/mm/yyy hh:nn:ss")

End

Output:

Rosetta.txt was last modified 28/05/2017 16:39:39

Go[edit]

package main

import (
    "fmt"
    "os"
    "syscall"
    "time"
)

var filename = "input.txt"

func main() {
    foo, err := os.Stat(filename)
    if err != nil {
        fmt.Println(err)
        return
    }
    fmt.Println("mod time was:", foo.ModTime())
    mtime := time.Now()
    atime := mtime // a default, because os.Chtimes has an atime parameter.
    // but see if there's a real atime that we can preserve.
    if ss, ok := foo.Sys().(*syscall.Stat_t); ok {
        atime = time.Unix(ss.Atim.Sec, ss.Atim.Nsec)
    }
    os.Chtimes(filename, atime, mtime)
    fmt.Println("mod time now:", mtime)
}

GUISS[edit]

In Graphical User Interface Support Script, we can can only use facilities that the underlying user interface provides, so we can display file timestamps, but cannot alter them. In this example, we get the date and timestamp for the file Foobar.txt.

Start,My Documents,Rightclick:Icon:Foobar.txt,Properties

Haskell[edit]

import System.Posix.Files
import System.Posix.Time

do status <- getFileStatus filename
   let atime = accessTime status
       mtime = modificationTime status -- seconds since the epoch
   curTime <- epochTime
   setFileTimes filename atime curTime -- keep atime unchanged
                                       -- set mtime to current time

Alternative (only gets modification time):

import System.Directory
import System.Time

do ct <- getModificationTime filename
   cal <- toCalendarTime ct
   putStrLn (calendarTimeToString cal)

HicEst[edit]

CHARACTER timestamp*18

timestamp = ' ' ! blank timestamp will read:
SYSTEM(FIle="File_modification_time.hic", FileTime=timestamp) ! 20100320141940.525

timestamp = '19991231235950' ! set timestamp to Millenium - 10 seconds
SYSTEM(FIle="File_modification_time.hic", FileTime=timestamp)

Icon and Unicon[edit]

Icon doesn't support 'stat' or 'utime'; however, information can be obtained by use of the system function to access command line.

every dir := !["./","/"] do {
   if i := stat(f := dir || "input.txt") then {
      write("info for ",f ," mtime= ",ctime(i.mtime),", atime=",ctime(i.ctime), ", atime=",ctime(i.atime)) 
      utime(f,i.atime,i.mtime-1024)
      i := stat(f)
      write("update for ",f ," mtime= ",ctime(i.mtime),", atime=",ctime(i.ctime), ", atime=",ctime(i.atime)) 
      }      
   else stop("failure to stat ",f)
   }

Notes:

  • Icon and Unicon accept both / and \ for directory separators.
  • 'ctime' formats an integer representing an epoch time into human readable form
  • 'utime' updates the atime and mtime values

J[edit]

The standard file access library only supports reading the file modification time.

   load 'files'
   fstamp 'input.txt'
2009 8 24 20 34 30

It is possible to set the time but it has to be done through OS specific external calls.

Java[edit]

import java.io.File;
import java.util.Date;
public class FileModificationTimeTest {
   public static void test(String type, File file) {
       long t = file.lastModified();
       System.out.println("The following " + type + " called " + file.getPath() +
            (t == 0 ? " does not exist." : " was modified at " + new Date(t).toString() )
       );
       System.out.println("The following " + type + " called " + file.getPath() + 
            (!file.setLastModified(System.currentTimeMillis()) ? " does not exist." : " was modified to current time." )
       );
       System.out.println("The following " + type + " called " + file.getPath() + 
            (!file.setLastModified(t) ? " does not exist." : " was modified to previous time." )
       );
   }
   public static void main(String args[]) {
       test("file", new File("output.txt"));
       test("directory", new File("docs"));
   }
}

JavaScript[edit]

Works with: JScript

Get only.

var fso = new ActiveXObject("Scripting.FileSystemObject");
var f = fso.GetFile('input.txt');
var mtime = f.DateLastModified;

The following works in all browsers, including IE10.

var file = document.getElementById("fileInput").files.item(0);
var last_modified = file.lastModifiedDate;

Jsish[edit]

Getting the mod time is a builtin. Setting the time is currently not, so touch is used here.

A C extension could provide access to the utime system call if desired.

/* File modification times, in Jsi */

var fileTime = File.mtime('fileModificationTime.jsi');
puts("Last mod time was: ", strftime(fileTime * 1000));

exec('touch fileModificationTime.jsi');

fileTime = File.mtime('fileModificationTime.jsi');
puts("Mod time now: ", strftime(fileTime * 1000));
Output:
prompt$ jsish fileModificationTime.jsi
Last mod time was:  2019-05-08 13:21:10
Mod time now:  2019-05-08 13:23:35

Julia[edit]

using Dates

fname, _ = mktemp()

println("The modification time of $fname is ", Dates.unix2datetime(mtime(fname)))
println("\nTouch this file.")
touch(fname)
println("The modification time of $fname is now ", Dates.unix2datetime(mtime(fname)))

Kotlin[edit]

// version 1.0.6

import java.io.File

fun main(args: Array<String>) {
    val filePath = "input.txt" // or whatever
    val file = File(filePath)
    with (file) {
        println("%tc".format(lastModified()))
        // update to current time, say
        setLastModified(System.currentTimeMillis())
        println("%tc".format(lastModified()))
    }    
}

Lasso[edit]

Note this is retrieve only.

File modification date is updated on save of file.

local(f) = file('input.txt')
handle => { #f->close }
#f->modificationDate->format('%-D %r')
// result: 12/2/2010 11:04:15 PM

Lua[edit]

require "lfs"
local attributes = lfs.attributes("input.txt")
if attributes then
    print(path .. " was last modified " .. os.date("%c", attributes.modification) .. ".")

    -- set access and modification time to now ...
    lfs.touch("input.txt")

    -- ... or set modification time to now, keep original access time
    lfs.touch("input.txt", attributes.access, os.time())
else
    print(path .. " does not exist.")
end

M2000 Interpreter[edit]

Most of the file statements/functions use current directory as path.

Module CheckIt {
      \\ without *for wide output*  we open for ANSI (1 byte per character)
      \\ but here we need it only for the creation of a file
      Open "afile" for output as #f
      Close #f
      Print file.stamp("afile")   'it is a number in VB6 date format.
      \\ day format as for Greece
      Print Str$(File.Stamp("afile"),"hh:nn:ss dd/mm/yyyy") , "utc write time - by default"
      Print Str$(File.Stamp("afile" ,1),"hh:nn:ss dd/mm/yyyy") , "utc write time, 1"
      Print  Str$(File.Stamp("afile" ,-1),"hh:nn:ss dd/mm/yyyy"), "local write time, -1"
      Print Str$(File.Stamp("afile" ,2),"hh:nn:ss dd/mm/yyyy"), "utc creation time, 2"
      Print  Str$(File.Stamp("afile" ,-2),"hh:nn:ss dd/mm/yyyy"), "local creation time, -2"
}
Checkit

Mathematica / Wolfram Language[edit]

Get file modification time:

 FileDate["file","Modification"]

results is returned in format: {year,month,day,hour,minute,second}. Setting file modification time:

 SetFileDate["file",date,"Modification"]

where date is specified as {year,month,day,hour,minute,second}.

MATLAB / Octave[edit]

   f = dir('output.txt');  % struct f contains file information
   f.date     % is string containing modification time 
   f.datenum  % numerical format (number of days) 
   datestr(f.datenum)   % is the same as f.date	
   % see also: stat, lstat

Modifying of file access time can be done through system calls:

  system('touch -t 201002032359.59 output.txt');

MAXScript[edit]

MAXScript has no method to set the mod time

-- Returns a string containing the mod date for the file, e.g. "1/29/99 1:52:05 PM"
getFileModDate "C:\myFile.txt"

Modula-3[edit]

MODULE ModTime EXPORTS Main;

IMPORT IO, Fmt, File, FS, Date, OSError;

TYPE dateArray = ARRAY [0..5] OF TEXT;

VAR 
  file: File.Status;
  date: Date.T;

PROCEDURE DateArray(date: Date.T): dateArray =
  BEGIN
    RETURN 
      dateArray{Fmt.Int(date.year), Fmt.Int(ORD(date.month) + 1), Fmt.Int(date.day),
                Fmt.Int(date.hour), Fmt.Int(date.minute), Fmt.Int(date.second)};
  END DateArray;

BEGIN
  TRY
    file := FS.Status("test.txt");
    date := Date.FromTime(file.modificationTime);
    IO.Put(Fmt.FN("%s-%02s-%02s %02s:%02s:%02s", DateArray(date)));          
    IO.Put("\n");
  EXCEPT
  | OSError.E => IO.Put("Error: Failed to get file status.\n");
  END;
END ModTime.
Output:
2011-07-14 14:12:46

This program sets the modification time to any value we wish:

MODULE SetModTime EXPORTS Main;

IMPORT Date, FS;

<*FATAL ANY*>

VAR 
  date: Date.T;

BEGIN
  (* Set the modification time to January 1st, 1999 *)
  date.year := 1999;
  date.month := Date.Month.Jan;
  date.day := 1;
  date.hour := 0;
  date.minute := 0;
  date.second := 0;
  date.offset := 21601;
  date.zone := "CST";

FS.SetModificationTime("test.txt", Date.ToTime(date));
END SetModTime.

We can see the output with the Unix command stat

Output:
stat test.txt | grep Mod
Modify: 1999-01-01 00:00:01.000000000 -0600

NetRexx[edit]

/* NetRexx */
options replace format comments java crossref symbols binary

runSample(arg)
return

-- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
method runSample(arg) public static
  parse arg fileName
  if fileName = '' then fileName = 'data/tempfile01'
  mfile = File(fileName)
  mtime = mfile.lastModified()
  dtime = Date(mtime).toString()
  say 'File' fileName 'last modified at' dtime
  say
  if mfile.setLastModified(0) then do
    dtime = Date(mfile.lastModified()).toString()
    say 'File modification time altered...'
    say 'File' fileName 'now last modified at' dtime
    say
    say 'Resetting...'
    mfile.setLastModified(mtime)
    dtime = Date(mfile.lastModified()).toString()
    say 'File' fileName 'reset to last modified at' dtime    
    end
  else do
    say 'Unable to modify time for file' fileName
    end
  return
Output:
File data/tempfile01 last modified at Fri May 24 14:45:55 PDT 2013

File modification time altered...
File data/tempfile01 now last modified at Wed Dec 31 16:00:00 PST 1969

Resetting...
File data/tempfile01 reset to last modified at Fri May 24 14:45:55 PDT 2013

NewLISP[edit]

;; print modification time
(println (date (file-info "input.txt" 6)))

;; set modification time to now (Unix)
(! "touch -m input.txt")

Nim[edit]

import os, strutils, times

if paramCount() == 0: quit(QuitSuccess)
let fileName = paramStr(1)

# Get and display last modification time.
var mtime = fileName.getLastModificationTime()
echo "File \"$1\" last modification time: $2".format(fileName, mtime.format("YYYY-MM-dd HH:mm:ss"))

# Change last modification time to current time.
fileName.setLastModificationTime(now().toTime())

Objeck[edit]

Get only

use System.IO.File;

class Program {
  function : Main(args : String[]) ~ Nil {
    File->ModifiedTime("file_mod.obs")->ToString()->PrintLine();
  }
}

Objective-C[edit]

NSFileManager *fm = [NSFileManager defaultManager];

// Pre-OS X 10.5
NSLog(@"%@", [[fm fileAttributesAtPath:@"input.txt" traverseLink:YES] fileModificationDate]);
[fm changeFileAttributes:[NSDictionary dictionaryWithObject:[NSDate date] forKey:NSFileModificationDate]
                  atPath:@"input.txt"];

// OS X 10.5+
NSLog(@"%@", [[fm attributesOfItemAtPath:@"input.txt" error:NULL] fileModificationDate]);
[fm setAttributes:[NSDictionary dictionaryWithObject:[NSDate date] forKey:NSFileModificationDate]
     ofItemAtPath:@"input.txt" error:NULL];

OCaml[edit]

#load "unix.cma";;
open Unix;;
let mtime = (stat filename).st_mtime;; (* seconds since the epoch *)

utimes filename (stat filename).st_atime (time ());;
(* keep atime unchanged
   set mtime to current time *)

Oforth[edit]

Get only :

File new("myfile.txt") modified

OpenEdge/Progress[edit]

The file modified time can only be read.

FILE-INFO:FILE-NAME = 'c:/temp'.
MESSAGE 
   STRING( FILE-INFO:FILE-MOD-TIME, 'HH:MM:SS' )
VIEW-AS ALERT-BOX

Oz[edit]

Getting the modification time:

declare
  [Path] = {Module.link ['x-oz://system/os/Path.ozf']}
  Modified = {Path.mtime "input.txt"} %% posix time
in
  {Show {OsTime.localtime Modified}} %% human readable record

Setting the modification time is not possible, unless implemented as an extension in C or C++.

Pascal[edit]

See Delphi

Perl[edit]

Works with: Perl version 5
my $mtime = (stat($file))[9]; # seconds since the epoch

# you should use the more legible version below:
use File::stat qw(stat);
my $mtime = stat($file)->mtime; # seconds since the epoch

utime(stat($file)->atime, time, $file);
# keep atime unchanged
# set mtime to current time

Phix[edit]

without js -- file i/o
-- (however get as per the JavaScript entry above might be doable if needed)
constant filename = "test.txt"
?get_file_date(filename)
 
include timedate.e
?format_timedate(get_file_date(filename))
bool res = set_file_date(filename)
?format_timedate(get_file_date(filename))
Output:
{2019,5,2,14,46,40}
"2:46pm Thursday May 02nd, 2019"
"12:25pm Wednesday May 08nd, 2019"

PHP[edit]

<?php
$filename = 'input.txt';

$mtime = filemtime($filename); // seconds since the epoch

touch($filename,
      time(), // set mtime to current time
      fileatime($filename)); // keep atime unchanged
?>

PicoLisp[edit]

(let File "test.file"
   (and
      (info File)
      (prinl (stamp (cadr @) (cddr @))) ) # Print date and time in UTC
   (call 'touch File) )                   # Set modification time to "now"
Output:
2010-02-20 15:46:37

Pop11[edit]

;;; Print modification time (seconds since Epoch)
sysmodtime('file') =>

PowerShell[edit]

$modificationTime = (Get-ChildItem file.txt).LastWriteTime
Set-ItemProperty file.txt LastWriteTime (Get-Date)

$LastReadTime = (Get-ChildItem file.txt).LastAccessTime
Set-ItemProperty file.txt LastAccessTime(Get-Date)

$CreationTime = (Get-ChildItem file.txt).CreationTime
Set-ItemProperty file.txt CreationTime(Get-Date)

You can also use alternates to get UTC time: LastWriteTimeUtc LastAccessTimeUtc CreationTimeUtc

PureBasic[edit]

Debug FormatDate("%yyyy/%mm/%dd", GetFileDate("file.txt",#PB_Date_Modified))
  SetFileDate("file.txt",#PB_Date_Modified,Date(1987, 10, 23, 06, 43, 15))
Debug FormatDate("%yyyy/%mm/%dd - %hh:%ii:%ss", GetFileDate("file.txt",#PB_Date_Modified))

Python[edit]

import os

#Get modification time:
modtime = os.path.getmtime('filename')

#Set the access and modification times:
os.utime('path', (actime, mtime))

#Set just the modification time:
os.utime('path', (os.path.getatime('path'), mtime))

#Set the access and modification times to the current time:
os.utime('path', None)

R[edit]

See this R-devel mailing list thread for more information.

# Get the value
file.info(filename)$mtime

#To set the value, we need to rely on shell commands.  The following works under windows.
shell("copy /b /v filename +,,>nul")
# and on Unix (untested)
shell("touch -m filename")

Racket[edit]

#lang racket
(file-or-directory-modify-seconds "foo.rkt")

Raku[edit]

(formerly Perl 6)

Works with: rakudo version 2018.03
use NativeCall;

class utimbuf is repr('CStruct') {
    has int $.actime;
    has int $.modtime;

    submethod BUILD(:$atime, :$mtime) {
        $!actime = $atime;
        $!modtime = $mtime.to-posix[0].round;
    }
}

sub sysutime(Str, utimbuf --> int32) is native is symbol('utime') {*}

sub MAIN (Str $file) {
    my $mtime = $file.IO.modified orelse .die;

    my $ubuff = utimbuf.new(:atime(time),:mtime($mtime));

    sysutime($file, $ubuff);
}

Sets the last access time to now, while restoring the modification time to what it was before.

RapidQ[edit]

name$ = DIR$("input.txt", 0)
PRINT "File date: "; FileRec.Date
PRINT "File time: "; FileRec.Time

REALbasic[edit]

The Date object has properties which correspond to various date formats such as SQLDateTime (YYYY-MM-DD HH:MM:SS), DayOfWeek, DayOfYear, and TotalSeconds since 12:00AM, January 1, 1904, among others.

Function getModDate(f As FolderItem) As Date
  Return f.ModificationDate
End Function

REXX[edit]

Works with: Regina REXX

The REXX language has no facility to update a file's modification time.

/*REXX program obtains and displays a  file's  time of modification.                    */
parse arg $ .                                    /*obtain required argument from the CL.*/
if $==''  then do;  say "***error*** no filename was specified.";   exit 13;   end
q=stream($, 'C', "QUERY TIMESTAMP")              /*get file's modification time info.   */
if q==''  then q="specified file doesn't exist." /*set an error indication message.     */
say 'For file: '  $                              /*display the file ID information.     */
say 'timestamp of last modification: ' q         /*display the modification time info.  */
                                                 /*stick a fork in it,  we're all done. */

output   when using the file ID for this particular REXX program (source file):   FILEMTIME.REX

For file:  FILEMTIM.REX
timestamp of last modification:  2015-05-30 14:22:26

Ring[edit]

load "stdlib.ring"
see GetFileInfo( "test.ring" )

func GetFileInfo cFile
     cOutput = systemcmd("dir /T:W " + cFile )
     aList = str2list(cOutput)
     cLine = aList[6]
     aInfo = split(cLine," ")
     return aInfo

Output:

2017.
08.
27.
10:31
189
test.ring

Ruby[edit]

#Get modification time:
modtime = File.mtime('filename')

#Set the access and modification times:
File.utime(actime, mtime, 'path')

#Set just the modification time:
File.utime(File.atime('path'), mtime, 'path')

#Set the access and modification times to the current time:
File.utime(nil, nil, 'path')

Run BASIC[edit]

files #f, DefaultDir$ + "\*.*"                  ' all files in the default directory
 
print "hasanswer: ";#f HASANSWER()              ' does it exist
print "rowcount: ";#f ROWCOUNT()                ' number of files in the directory
print                                           '  
#f DATEFORMAT("mm/dd/yy")                       ' set format of file date to template given
#f TIMEFORMAT("hh:mm:ss")                       ' set format of file time to template given

for i = 1 to #f rowcount()                      ' loop through the files
if #f hasanswer() then                          '  or loop with while #f hasanswer()
 print "nextfile info: ";#f nextfile$("    ")   ' set the delimiter for nextfile info
 print "name: ";name$                           ' file name                        
 print "size: ";#f SIZE()                       ' file size
 print "date: ";#f DATE$()                      ' file date
 print "time: ";#f TIME$()                      ' file time
 print "isdir: ";#f ISDIR()                     ' is it a directory or file

 name$ = #f NAME$()
 shell$("touch -t 201002032359.59 ";name$;""")  ' shell to os to set date

 print
end if
next

Rust[edit]

use std::fs;

fn main() -> std::io::Result<()> {
    let metadata = fs::metadata("foo.txt")?;

    if let Ok(time) = metadata.accessed() {
        println!("{:?}", time);
    } else {
        println!("Not supported on this platform");
    }
    Ok(())
}

Scala[edit]

Library: Scala
import java.io.File
import java.util.Date

object FileModificationTime extends App {
  def test(file: File) {
    val (t, init) = (file.lastModified(),
      s"The following ${if (file.isDirectory()) "directory" else "file"} called ${file.getPath()}")

    println(init + (if (t == 0) " does not exist." else " was modified at " + new Date(t).toInstant()))
    println(init +
      (if (file.setLastModified(System.currentTimeMillis())) " was modified to current time." else " does not exist."))
    println(init +
      (if (file.setLastModified(t)) " was reset to previous time." else " does not exist."))
  }

  // main
  List(new File("output.txt"), new File("docs")).foreach(test)
}

Seed7[edit]

$ include "seed7_05.s7i";
  include "osfiles.s7i";
  include "time.s7i";

const proc: main is func
  local
    var time: modificationTime is time.value;
  begin
    modificationTime := getMTime("data.txt");
    setMTime("data.txt", modificationTime);
  end func;

Sidef[edit]

var file = File.new(__FILE__);
say file.stat.mtime;            # seconds since the epoch

# keep atime unchanged
# set mtime to current time
file.utime(file.stat.atime, Time.now);

Slate[edit]

Modifying the timestamp value is not currently a built-in feature. This code gets a raw value:

slate[1]> (File newNamed: 'LICENSE') fileInfo modificationTimestamp.
1240349799

Smalltalk[edit]

|a| 
a := File name: 'input.txt'.
(a lastModifyTime) printNl.

Standard ML[edit]

val mtime = OS.FileSys.modTime filename; (* returns a Time.time data structure *)

(* unfortunately it seems like you have to set modification & access times together *)
OS.FileSys.setTime (filename, NONE); (* sets modification & access time to now *)
(* equivalent to: *)
OS.FileSys.setTime (filename, SOME (Time.now ()))

Tcl[edit]

Assuming that the variable filename holds the name of the file...

# Get the modification time:
set timestamp [file mtime $filename]

# Set the modification time to ‘now’:
file mtime $filename [clock seconds]

TUSCRIPT[edit]

TUSCRIPT does not allow to modify/set the timestamp of a file, but it is able to read it:

$$ MODE TUSCRIPT
file="rosetta.txt"
ERROR/STOP OPEN (file,READ,-std-)
modified=MODIFIED (file)
PRINT "file ",file," last modified: ",modified
Output:
file rosetta.txt last modified: 2011-12-14 23:50:48

UNIX Shell[edit]

There are several ways to handle files' timestamps in most *nix systems. For these examples, we'll assume you need to retrieve the timestamp to a variable. These examples use stat and touch from the GNU Core Utilities, under bash, but they should work with any POSIX-compliant implementation under any sh-compatible shell.

For all of these examples, $F is a variable holding the filename to examine, while T (and $T) is the timestamp.

To get the timestamp in seconds since the epoch:

T=`stat -c %Y $F`

To get the timestamp in human-readable format:

T=`stat -c %y $F`

Note that the only difference between the above examples is capital Y vs lower-case y.

In the following examples, the "-c" argument to touch tells it to not create any files that don't already exist.

To set file F to time T, where T is in a human-readable format:

# Note the quotation marks -- very important!
T="2000-01-01 01:02:03.040506070 -0800"
touch -c -d "$T" $F

To set file F to time T, where T is in the format [[CC]YY]MMDDhhmm[.ss] (the square brackets mark optional parts):

T=200102030405.06
touch -c -t $T $F

If the year is left out, the current year is used. If the seconds are left out, 0 (zero) is used. Leaving out the optional parts of the above results in this:

T=02030405
touch -c -t $T $F

If no time is specified, then the timestamp is set to the current time:

touch -c $F

There are, of course, other ways to do both tasks -- for example, one could use ls -l --time-style=full-iso and then process the resulting list with some other tool (e.g. awk or Perl).

Ursa[edit]

Works with: Cygnus/X Ursa
decl java.util.Date d
decl file f

f.open "example.txt"
d.setTime (f.lastmodified)
out d endl console

f.setlastmodified 10

VBScript[edit]

Works with: Windows Script Host version *

VBScript provides no way to set the last modification time. It does allow you to retrieve it, however.

WScript.Echo CreateObject("Scripting.FileSystemObject").GetFile("input.txt").DateLastModified

Vedit macro language[edit]

Display file's last modification time as number of seconds since midnight.

Num_Type(File_Stamp_Time("input.txt"))

Displays file's last modification date and time as a string.

File_Stamp_String(10, "input.txt")
Reg_Type(10)

Vedit Macro Language has Blog in SEO no method to set the modification time

Visual Basic .NET[edit]

Platform: .NET

Works with: Visual Basic .NET version 9.0+
Dim file As New IO.FileInfo("test.txt")

'Creation Time
Dim createTime = file.CreationTime
file.CreationTime = createTime.AddHours(1)

'Write Time
Dim writeTime = file.LastWriteTime
file.LastWriteTime = writeTime.AddHours(1)
 
'Access Time 
Dim accessTime = file.LastAccessTime
file.LastAccessTime = accessTime.AddHours(1)

Wren[edit]

Translation of: C
Library: POSIX
Library: Wren-date

As there is currently no way for Wren-cli to get or set file modification times, we instead use an embedded script so the C host can do this for us.

/* file_mod_time_wren */

import "./date" for Date

foreign class Stat {
    construct new(fileName) {}

    foreign atime
    foreign mtime
}

foreign class Utimbuf {
    construct new(actime, modtime) {}

    foreign utime(fileName)
}

// gets a Date object from a Unix time in seconds
var UT2Date = Fn.new { |ut| Date.unixEpoch.addSeconds(ut) }

Date.default = "yyyy|-|mm|-|dd| |hh|:|MM|:|ss" // default format for printing

var fileName = "temp.txt"
var st = Stat.new(fileName)
System.print("'%(fileName)' was last modified on %(UT2Date.call(st.mtime)).")

var utb = Utimbuf.new(st.atime, 0) // atime unchanged, mtime = current time
if (utb.utime(fileName) < 0) {
    System.print("There was an error changing the file modification time.")
    return
}
st = Stat.new(fileName) // update info
System.print("File modification time changed to %(UT2Date.call(st.mtime)).")


We now embed this in the following C program, build and run it:

/* gcc file_mod_time.c -o file_mod_time -lwren -lm */

#include <sys/stat.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <utime.h>
#include "wren.h"

/* Stat functions */

void Stat_allocate(WrenVM* vm) {
    struct stat *pStat = (struct stat*)wrenSetSlotNewForeign(vm, 0, 0, sizeof(struct stat));
    const char *filename = wrenGetSlotString(vm, 1);
    if (stat(filename, pStat) < 0) {
        perror(filename);
        exit(1);
    }
}

void Stat_atime(WrenVM* vm) {
    struct stat *pStat = (struct stat*)wrenGetSlotForeign(vm, 0);
    wrenSetSlotDouble(vm, 0, (double)pStat->st_atime);
}

void Stat_mtime(WrenVM* vm) {
    struct stat *pStat = (struct stat*)wrenGetSlotForeign(vm, 0);
    wrenSetSlotDouble(vm, 0, (double)pStat->st_mtime);
}

/* Utimbuf functions */

void Utimbuf_allocate(WrenVM* vm) {
    struct utimbuf *pUtimbuf = (struct utimbuf*)wrenSetSlotNewForeign(vm, 0, 0, sizeof(struct utimbuf));
    time_t actime = (time_t)wrenGetSlotDouble(vm, 1);
    if (!actime) actime = time(NULL);
    pUtimbuf->actime = actime;
    time_t modtime = (time_t)wrenGetSlotDouble(vm, 2);
    if (!modtime) modtime = time(NULL);
    pUtimbuf->modtime = modtime;
}

void Utimbuf_utime(WrenVM* vm) {
    const struct utimbuf *pUtimbuf = (const struct utimbuf*)wrenGetSlotForeign(vm, 0);
    const char *filename = wrenGetSlotString(vm, 1);
    int res = utime(filename, pUtimbuf);
    wrenSetSlotDouble(vm, 0, (double)res);
}

WrenForeignClassMethods bindForeignClass(WrenVM* vm, const char* module, const char* className) {
    WrenForeignClassMethods methods;
    methods.allocate = NULL;
    methods.finalize = NULL;
    if (strcmp(module, "main") == 0) {
        if (strcmp(className, "Stat") == 0) {
            methods.allocate = Stat_allocate;
        } else if (strcmp(className, "Utimbuf") == 0) {
            methods.allocate = Utimbuf_allocate;
        }
    }
    return methods;
}

WrenForeignMethodFn bindForeignMethod(
    WrenVM* vm,
    const char* module,
    const char* className,
    bool isStatic,
    const char* signature) {
    if (strcmp(module, "main") == 0) {
        if (strcmp(className, "Stat") == 0) {
            if(!isStatic && strcmp(signature, "atime") == 0) return Stat_atime;
            if(!isStatic && strcmp(signature, "mtime") == 0) return Stat_mtime;
        } else if (strcmp(className, "Utimbuf") == 0) {
            if(!isStatic && strcmp(signature, "utime(_)") == 0) return Utimbuf_utime;
        }
    }
    return NULL;
}

static void writeFn(WrenVM* vm, const char* text) {
    printf("%s", text);
}

void errorFn(WrenVM* vm, WrenErrorType errorType, const char* module, const int line, const char* msg) {
    switch (errorType) {
        case WREN_ERROR_COMPILE:
            printf("[%s line %d] [Error] %s\n", module, line, msg);
            break;
        case WREN_ERROR_STACK_TRACE:
            printf("[%s line %d] in %s\n", module, line, msg);
            break;
        case WREN_ERROR_RUNTIME:
            printf("[Runtime Error] %s\n", msg);
            break;
    }
}

char *readFile(const char *fileName) {
    FILE *f = fopen(fileName, "r");
    fseek(f, 0, SEEK_END);
    long fsize = ftell(f);
    rewind(f);
    char *script = malloc(fsize + 1);
    size_t ret = fread(script, 1, fsize, f);
    if (ret != fsize) printf("Error reading %s\n", fileName);
    fclose(f);
    script[fsize] = 0;
    return script;
}

static void loadModuleComplete(WrenVM* vm, const char* module, WrenLoadModuleResult result) {
    if( result.source) free((void*)result.source);
}

WrenLoadModuleResult loadModule(WrenVM* vm, const char* name) {
    WrenLoadModuleResult result = {0};
    if (strcmp(name, "random") != 0 && strcmp(name, "meta") != 0) {
        result.onComplete = loadModuleComplete;
        char fullName[strlen(name) + 6];
        strcpy(fullName, name);
        strcat(fullName, ".wren");
        result.source = readFile(fullName);
    }
    return result;
}

int main(int argc, char **argv) {
    WrenConfiguration config;
    wrenInitConfiguration(&config);
    config.writeFn = &writeFn;
    config.errorFn = &errorFn;
    config.bindForeignClassFn = &bindForeignClass;
    config.bindForeignMethodFn = &bindForeignMethod;
    config.loadModuleFn = &loadModule;
    WrenVM* vm = wrenNewVM(&config);
    const char* module = "main";
    const char* fileName = "file_mod_time.wren";
    char *script = readFile(fileName);
    WrenInterpretResult result = wrenInterpret(vm, module, script);
    switch (result) {
        case WREN_RESULT_COMPILE_ERROR:
            printf("Compile Error!\n");
            break;
        case WREN_RESULT_RUNTIME_ERROR:
            printf("Runtime Error!\n");
            break;
        case WREN_RESULT_SUCCESS:
            break;
    }
    wrenFreeVM(vm);
    free(script);
    return 0;
}
Output:

Sample output:

'temp.txt' was last modified on 2021-12-05 14:14:30.
File modification time changed to 2021-12-05 14:23:42.

zkl[edit]

info:=File.info("input.txt");
  // -->T(size,last status change time,last mod time,isDir,mode), from stat(2)
info.println();
Time.Date.ctime(info[2]).println();
File.setModTime("input.txt",Time.Clock.mktime(2014,2,1,0,0,0));
File.info("input.txt")[2] : Time.Date.ctime(_).println();
Output:
L(391,1394910932,1394910932,False,33156)
Sat Mar 15 12:15:32 2014
Sat Feb 1 00:00:00 2014