Inconsistency in modified/created/accessed time on mac
Question: I'm having trouble using `os.utime` to correctly set the modification time on
the mac (Mac OS X 10.6.2, running Python 2.6.1 from `/usr/bin/python`). It's
not consistent with the `touch` utility, and it's not consistent with the
properties displayed in the Finder's "get info" window.

Consider the following command sequence. The 'created' and 'modified' times in
the plain text refer to the attributes shown in the "get info" window in the
finder. As a reminder,
[os.utime](http://docs.python.org/library/os.html#os.utime) takes arguments
`(filename, (atime, mtime))`.

    
    
    >>> import os
    >>> open('tempfile','w').close()
    

'created' and 'modified' are both the current time.

    
    
    >>> os.utime('tempfile', (1000000000, 1500000000) )
    

'created' is the current time, 'modified' is July 13, 2017.

    
    
    >>> os.utime('tempfile', (1000000000, 1000000000) )
    

'created' and 'modified' are both September 8, 2001.

    
    
    >>> os.path.getmtime('tempfile')
    1000000000.0
    >>> os.path.getctime('tempfile')
    1269021939.0
    >>> os.path.getatime('tempfile')
    1269021951.0
    

...but the `os.path.get?time` and `os.stat` don't reflect it.

    
    
    >>> os.utime('tempfile', (1500000000, 1000000000) )
    

'created' and 'modified' are _still_ both September 8, 2001.

    
    
    >>> os.utime('tempfile', (1500000000, 1500000000) )
    

'created' is September 8, 2001, 'modified' is July 13, 2017.

I'm not sure if this is a Python problem or a Mac stat problem. When I exit
the Python shell and run

    
    
    touch -a -t 200011221234 tempfile
    

neither the modification nor the creation times are changed, as expected. Then
I run

    
    
    touch -m -t 200011221234 tempfile
    

and both 'created' and 'modified' times are changed.

Does anyone have any idea what's going on? How do I change the modification
and creation times consistently on the mac? (Yes, I am aware that on Unixy
systems there is no "creation time.")

* * *

Result from running Chris Johnsen's script:

    
    
    seth@local:~$ /usr/bin/python timetest.py tempfile 5
    initial:
    (1269631281.0, 1269631281.0, 1269631281.0, 1269631281, 1269631281, 1269631281)
    
    test: (1000000000, 1000000000)
    (1000000000.0, 1000000000.0, 1269631281.0, 1000000000, 1000000000, 1269631281)
    (1269631281.0, 1000000000.0, 1269631281.0, 1269631281, 1000000000, 1269631281)
    
    test: (1000000000, 1500000000)
    (1000000000.0, 1500000000.0, 1269631286.0, 1000000000, 1500000000, 1269631286)
    (1269631286.0, 1500000000.0, 1269631286.0, 1269631286, 1500000000, 1269631286)
    
    test: (1500000000, 1000000000)
    (1500000000.0, 1000000000.0, 1269631291.0, 1500000000, 1000000000, 1269631291)
    (1269631291.0, 1000000000.0, 1269631291.0, 1269631291, 1000000000, 1269631291)
    
    test: (1500000000, 1500000000)
    (1500000000.0, 1500000000.0, 1269631296.0, 1500000000, 1500000000, 1269631296)
    (1269631296.0, 1500000000.0, 1269631296.0, 1269631296, 1500000000, 1269631296)
    

At the end of the exercise, the 'created' date as visible in the finder is
9/8/01 and the 'modified' date is 7/13/17. (The access date, thanks to
presumably spotlight as you suggest and as I've read about, is roughly 'now.')
The created and modified dates visible in the finder still make no sense.


Answer: # POSIX _atime_ , _mtime_ , _ctime_

It might help if you included a full script and its actual and expected
outputs instead of the REPL fragments.

    
    
    import sys, os, stat, time
    
    def get_times(p):
        s = os.stat(p)
        return ( 
            os.path.getatime(p),
            os.path.getmtime(p),
            os.path.getctime(p),
            s[stat.ST_ATIME],
            s[stat.ST_MTIME],
            s[stat.ST_CTIME],
        )
    
    def main(p, delay=1):
        delay = float(delay)
        (a,b) = (1000000000, 1500000000)
    
        open(p,'w').close()
    
        print 'initial:'
        print get_times(p)
    
        for t in [ (a,a), (a,b), (b,a), (b,b) ]:
            print
            print 'test:', t
            os.utime(p,t)
            print get_times(p)
            time.sleep(delay)
            print get_times(p)
    
    main(*sys.argv[1:])
    

I get this on my 10.4 system with `cd "$HOME" && python test.py tempfile 5`
(system default Python 2.3.6 and MacPorts Python 2.6.4 both give the same
result (leaving out the initial times and _ctime_ , of course)):

    
    
    % python /tmp/test.py tempfile 5
    initial:
    (1000000000.0, 1000000000.0, 1269629881.0, 1000000000, 1000000000, 1269629881)
    
    test: (1000000000, 1000000000)
    (1000000000.0, 1000000000.0, 1269629881.0, 1000000000, 1000000000, 1269629881)
    (1000000000.0, 1000000000.0, 1269629881.0, 1000000000, 1000000000, 1269629881)
    
    test: (1000000000, 1500000000)
    (1000000000.0, 1500000000.0, 1269629886.0, 1000000000, 1500000000, 1269629886)
    (1000000000.0, 1500000000.0, 1269629886.0, 1000000000, 1500000000, 1269629886)
    
    test: (1500000000, 1000000000)
    (1500000000.0, 1000000000.0, 1269629891.0, 1500000000, 1000000000, 1269629891)
    (1500000000.0, 1000000000.0, 1269629891.0, 1500000000, 1000000000, 1269629891)
    
    test: (1500000000, 1500000000)
    (1500000000.0, 1500000000.0, 1269629896.0, 1500000000, 1500000000, 1269629896)
    (1500000000.0, 1500000000.0, 1269629896.0, 1500000000, 1500000000, 1269629896)
    

That seems reasonable. I wonder what you get.

I have heard that Spotlight can sometimes aggressively reset _atime_ due to
re-indexing changed files. I would not expect it to re-index a file that has
only undergone utime()/utimes(), but I suppose it is possible. To eliminate
Spotlight as a possible complication use a file in a location that is not
indexed by Spotlight (e.g. /tmp/testfile).

# Date Created in _Finder_

(shown as “Created:” in Get Info windows of Finder)

If you have the Developer tools installed, you can use
`/Developer/Tools/GetFileInfo` to see the HFS creationDate. I added the
following lines after every `print get_times(p)` line:

    
    
    sys.stdout.flush()
    os.system('/Developer/Tools/GetFileInfo ' + p)
    

I also changed the iteration to match your initial description (`[ (a,b),
(a,a), (b,a), (b,b) ]`).

The result now looks like this:

    
    
    % rm /tmp/tempfile; python /tmp/test.py /tmp/tempfile 1
    initial:
    (1269636574.0, 1269636574.0, 1269636574.0, 1269636574, 1269636574, 1269636574)
    file: "/private/tmp/tempfile"
    type: ""
    creator: ""
    attributes: avbstclinmedz
    created: 03/26/2010 15:49:34
    modified: 03/26/2010 15:49:34
    
    test: (1000000000, 1500000000)
    (1000000000.0, 1500000000.0, 1269636574.0, 1000000000, 1500000000, 1269636574)
    file: "/private/tmp/tempfile"
    type: ""
    creator: ""
    attributes: avbstclinmedz
    created: 03/26/2010 15:49:34
    modified: 07/13/2017 21:40:00
    (1000000000.0, 1500000000.0, 1269636574.0, 1000000000, 1500000000, 1269636574)
    file: "/private/tmp/tempfile"
    type: ""
    creator: ""
    attributes: avbstclinmedz
    created: 03/26/2010 15:49:34
    modified: 07/13/2017 21:40:00
    
    test: (1000000000, 1000000000)
    (1000000000.0, 1000000000.0, 1269636576.0, 1000000000, 1000000000, 1269636576)
    file: "/private/tmp/tempfile"
    type: ""
    creator: ""
    attributes: avbstclinmedz
    created: 09/08/2001 20:46:40
    modified: 09/08/2001 20:46:40
    (1000000000.0, 1000000000.0, 1269636576.0, 1000000000, 1000000000, 1269636576)
    file: "/private/tmp/tempfile"
    type: ""
    creator: ""
    attributes: avbstclinmedz
    created: 09/08/2001 20:46:40
    modified: 09/08/2001 20:46:40
    
    test: (1500000000, 1000000000)
    (1500000000.0, 1000000000.0, 1269636577.0, 1500000000, 1000000000, 1269636577)
    file: "/private/tmp/tempfile"
    type: ""
    creator: ""
    attributes: avbstclinmedz
    created: 09/08/2001 20:46:40
    modified: 09/08/2001 20:46:40
    (1500000000.0, 1000000000.0, 1269636577.0, 1500000000, 1000000000, 1269636577)
    file: "/private/tmp/tempfile"
    type: ""
    creator: ""
    attributes: avbstclinmedz
    created: 09/08/2001 20:46:40
    modified: 09/08/2001 20:46:40
    
    test: (1500000000, 1500000000)
    (1500000000.0, 1500000000.0, 1269636578.0, 1500000000, 1500000000, 1269636578)
    file: "/private/tmp/tempfile"
    type: ""
    creator: ""
    attributes: avbstclinmedz
    created: 09/08/2001 20:46:40
    modified: 07/13/2017 21:40:00
    (1500000000.0, 1500000000.0, 1269636578.0, 1500000000, 1500000000, 1269636578)
    file: "/private/tmp/tempfile"
    type: ""
    creator: ""
    attributes: avbstclinmedz
    created: 09/08/2001 20:46:40
    modified: 07/13/2017 21:40:00
    

This seems to be consistent with your observations from your Get Info window
in _Finder_. My interpretation (borne out by other experimentation) is that
the HFS creationDate is updated by utime, but it only ever goes backwards
(never forwards). If you want to update the HFS creationDate to a newer value,
then you probably will have to use a Mac-specific API to do it.

One other note: you may have to switch windows a bit to get the _Get Info_
window to update. On my system, its display does not automatically update
unless I switch windows either to or from the Get Info window.

