Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Terminal command to change files/folders creation/modification date

Hello,


I'm looking for a terminal command that allows me to change files and folders creation and modification date.

I've already tried with:

touch -t YYYYMMDDhhmm.ss [File path]

--to change creation date


or


touch -mt YYYYMMDDhhmm.ss [File path]

--to change modification date

...but the command to change the creation date doesn't work (changes only the modification date) and the other command to the same as the first.

Moreover using touch command I'm not able to change folders' properties.


Any suggest?

Thanks in advance!

Posted on Aug 18, 2014 1:08 AM

Reply
18 replies

Aug 18, 2014 6:16 AM in response to Matteo_999

And if I haven't installed neither Xcode nor the Developer Command-line tools?

Then you do not have a command to change the creation time. Touch can be used to change Modification (mtime) and Access (atime) time values.


The Creation time, which is NOT a Unix concept, and not to be confused with Change Time (ctime), can not be set by the touch command.


It may be possible via Applescript. Google "applescript to change creation time" and you might find something.

Aug 18, 2014 9:47 AM in response to Matteo_999

In Applescript Editor open the Finder's dictionary (via the File menu) to see all the terms & properties it can handle.

Your script isn't using a tell application 'Finder' block so it may not apply, however the creation date is specified as a 'r/o' property - that means READ ONLY.

User uploaded file

It may be the 'Standard Additions' dictionary (or another dictionary) you need to look at, but as already described it is not a standard feature to be able to set this date.


I also have to question your date format…

set d to the creation date of (theFile as alias)

logd

Outputs "Friday, 21 January 2014 11:56:51" in the event log.


I doubt you can make this work - download Xcode if you hope to change the creation dates, it's free after all.

http://www.manpagez.com/man/1/SetFile/

You will also want to use 'GetFileInfo' to verify it was set ('ls' won't show it by default unless you use 'ls -U', or 'stat' instead…).

Aug 18, 2014 10:16 AM in response to Matteo_999

Matteo_999 wrote:


And if I haven't installed neither Xcode nor the Developer Command-line tools?


To change creation date, you must use cocoa framework in a cocoa-Applescript applet, or in (python or ruby) shell.


Here is an example (AppleScript script) :


set tFile to choose file
set tdate to "20140818010101" -- 2014/08/18 01:01:01
my setCreationDate(quoted form of POSIX path of tFile, tdate)

on setCreationDate(f, d)
      do shell script "/usr/bin/env python -c 'import sys
from Foundation import NSFileManager, NSDateFormatter
dm = NSFileManager.defaultManager()
f = sys.argv[1]
df = NSDateFormatter.new()
df.setDateFormat_(\"yyyyMMddHHmmss\")
cdate = df.dateFromString_(sys.argv[2]) 
cDateDict = {\"NSFileCreationDate\": cdate}
b, error = dm.setAttributes_ofItemAtPath_error_(cDateDict , f, None)
if not b: print f' " & f & " " & quoted form of d
end setCreationDate

Aug 18, 2014 12:28 PM in response to Matteo_999

Hello


Here's a rubycocoa script you may use as command line tool.


Recipe:


- Create plain text file named set_file_date.rb with the content listed below and set its mode by, e.g., -


chmod u+x set_file_date.rb




Usage:


- E.g. 1

For *.txt in current directory, set creation date to 2014-08-05 09:00:00 and modification date to 2014-08-15 14:00:00.


./set_file_date.rb -c 201408050900.00 -m 201408151400.00 *.txt



- E.g. 2

For *.txt in current directory, set creation date to 2014-08-05 09:00:00 (if it is not later than the current modification date; otherwise leave creation date unchanged) and leave modification date unchanged.


./set_file_date.rb -c 201408050900.00 *.txt



- E.g. 3

For *.txt in current directory, set modification date to 2014-08-15 14:00:00 and leave creation date unchanged (if it is not later than the specified modification date; otherwise set creation date to the specified modification date as well).


./set_file_date.rb -m 201408151400.00 *.txt




Notes:


- Creation date cannot be later than modification date.


- You may change the date format by changing DATE_PATTERN in script.




set_file_date.rb


#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -w
# 
#     ARGV = options file [file ...]
#     options =
#         -c DATE                          Set creation date to DATE
#         -m DATE                          Set modification date to DATE
#         -h, --help                       Display this help.
#     
#     * date must be in the format DATE_PATTERN defined below
#     * using NSFileManager method
# 
require 'osx/cocoa'
include OSX

# DATE_PATTERN = "yyyy'-'MM'-'dd HH':'mm':'ss Z"    # [1]
DATE_PATTERN = "yyyyMMddHHmm.ss"                    # [1]
# 
#     [1] cf. http://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
# 

def parse_options(argv)
    require 'optparse'
    
    args = {:cdt => nil, :mdt => nil}
    op = OptionParser.new do|o|
        o.banner = "Usage: #{File.basename($0)} options file [file ...]"
        o.on('-c DATE', String, "Set creation date to DATE (#{DATE_PATTERN})") do |t|
            args[:cdt] = t
        end
        o.on('-m DATE', String, "Set modification date to DATE (#{DATE_PATTERN})") do |t|
            args[:mdt] = t
        end
        o.on( '-h', '--help', 'Display this help.' ) do
            $stderr.puts o; exit 1
        end
    end
    begin
        op.parse!(argv)
    rescue => ex
        $stderr.puts "#{ex.class} : #{ex.message}"
        $stderr.puts op.help(); exit 1
    end
    if argv.length == 0 or args.values == [nil, nil]
        $stderr.puts op.help(); exit 1
    end
    args
end

ct, mt = parse_options(ARGV).values_at(:cdt, :mdt)
df = NSDateFormatter.alloc.init
df.setDateFormat(DATE_PATTERN)
cdt, mdt = [ct, mt].map do |t|
    next nil unless t
    dt = df.dateFromString(t) or
        begin
            $stderr.puts "Invalid date string: %s (expected: %s)" % [t, DATE_PATTERN]
            exit 1
        end
end
attrs = []
attrs << { NSFileModificationDate => mdt } if mdt    # [2]
attrs << { NSFileCreationDate     => cdt } if cdt
# 
#     [2] Set modification date first if specified.
#         If cdt > current modification date, creation date cannot be set to cdt even if cdt <= mdt
#         whereas modification date can be set to mdt regardless of current modification date and creation date.
#         (If mdt < current creation date, creation date is set to mdt as well.)
#         Therefore, first setting modification date to mdt and then setting creation date to cdt (<= mdt) is the right order
#         to set both cdt and mdt regardless of current modification date and creation date.
#         (If mdt = nil and cdt > current modification date, creation date will remain as is.)
#         
        
fm = NSFileManager.defaultManager
ARGV.each do |f|
    err = OCObject.new
    attrs.each do |a|
        b = fm.objc_send(
            :setAttributes, a,
            :ofItemAtPath, f,
            :error, err)
        $stderr.puts "Failed to set attribute of %s: %s" % [File.expand_path(f), err.description] unless b
    end
end



Briefly tested under 10.6.8.


Regards,

H

Aug 18, 2014 1:26 PM in response to Hiroto

Oops.


This part:


ARGV.each do |f|
    err = OCObject.new
    attrs.each do |a|
        b = fm.objc_send(
            :setAttributes, a,
            :ofItemAtPath, f,
            :error, err)
        $stderr.puts "Failed to set attribute of %s: %s" % [File.expand_path(f), err.description] unless b
    end
end



should have been this:


ARGV.each do |f|
    attrs.each do |a|
        err = OCObject.new
        b = fm.objc_send(
            :setAttributes, a,
            :ofItemAtPath, f,
            :error, err)
        $stderr.puts "Failed to set attribute of %s: %s" % [File.expand_path(f), err.description] unless b
    end
end




Corrected script is as follows. Sorry for confusion.



#!/System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby -w
# 
#     ARGV = options file [file ...]
#     options =
#         -c DATE                          Set creation date to DATE
#         -m DATE                          Set modification date to DATE
#         -h, --help                       Display this help.
#     
#     * date must be in the format DATE_PATTERN defined below
#     * using NSFileManager method
# 
require 'osx/cocoa'
include OSX

# DATE_PATTERN = "yyyy'-'MM'-'dd HH':'mm':'ss Z"    # [1]
DATE_PATTERN = "yyyyMMddHHmm.ss"                    # [1]
# 
#     [1] cf. http://unicode.org/reports/tr35/tr35-dates.html#Date_Format_Patterns
# 

def parse_options(argv)
    require 'optparse'
    
    args = {:cdt => nil, :mdt => nil}
    op = OptionParser.new do|o|
        o.banner = "Usage: #{File.basename($0)} options file [file ...]"
        o.on('-c DATE', String, "Set creation date to DATE (#{DATE_PATTERN})") do |t|
            args[:cdt] = t
        end
        o.on('-m DATE', String, "Set modification date to DATE (#{DATE_PATTERN})") do |t|
            args[:mdt] = t
        end
        o.on( '-h', '--help', 'Display this help.' ) do
            $stderr.puts o; exit 1
        end
    end
    begin
        op.parse!(argv)
    rescue => ex
        $stderr.puts "#{ex.class} : #{ex.message}"
        $stderr.puts op.help(); exit 1
    end
    if argv.length == 0 or args.values == [nil, nil]
        $stderr.puts op.help(); exit 1
    end
    args
end

ct, mt = parse_options(ARGV).values_at(:cdt, :mdt)
df = NSDateFormatter.alloc.init
df.setDateFormat(DATE_PATTERN)
cdt, mdt = [ct, mt].map do |t|
    next nil unless t
    dt = df.dateFromString(t) or
        begin
            $stderr.puts "Invalid date string: %s (expected: %s)" % [t, DATE_PATTERN]
            exit 1
        end
end
attrs = []
attrs << { NSFileModificationDate => mdt } if mdt    # [2]
attrs << { NSFileCreationDate     => cdt } if cdt
# 
#     [2] Set modification date first if specified.
#         If cdt > current modification date, creation date cannot be set to cdt even if cdt <= mdt
#         whereas modification date can be set to mdt regardless of current modification date and creation date.
#         (If mdt < current creation date, creation date is set to mdt as well.)
#         Therefore, first setting modification date to mdt and then setting creation date to cdt (<= mdt) is the right order
#         to set both cdt and mdt regardless of current modification date and creation date.
#         (If mdt = nil and cdt > current modification date, creation date will be remain as is.)
#         
        
fm = NSFileManager.defaultManager
ARGV.each do |f|
    attrs.each do |a|
        err = OCObject.new
        b = fm.objc_send(
            :setAttributes, a,
            :ofItemAtPath, f,
            :error, err)
        $stderr.puts "Failed to set attribute of %s: %s" % [File.expand_path(f), err.description] unless b
    end
end



Regards,

H

Aug 19, 2014 3:19 AM in response to Matteo_999

No problem.


Just note that both scripts are using the same NSFileManager's method to set date attributes and this method behaves in particular way when setting creation date as stated in the comment in my script, that is it dose not set creation date to any date later than current modification date.


E.g. Given current modificationd date = 2014-08-05 00:00:00, current creation date = 2014-08-01 00:00:00 and target creation date = 2014-08-10 00:00:00, the method will set the creation date to 2014-08-05 00:00:00 instead of 2014-08-10 00:00:00 silently. In order to set the creation date to the target date, you need to first set the modification date to the date and then set the creation date to the date. (at least under OSX 10.6.8)


Just in case,

H

Terminal command to change files/folders creation/modification date

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.