Timestamps in AppleScript

AppleScript is easy for most basic file manipulations on the Mac. For example, I can get a files modification timestamp with the following bit of AppleScript:

set modificationDate to modification date of this_item

where "this_item" is a reference to a file. "modificationDate" now contains a value like "Wednesday, December 21, 2011 7:24:22 PM"

But that's a pretty awkward timestamp if I want to use it to name a file. In AppleScript, reformatting a timestamp is awkward and tedious. I often resort to other options. I have two preferred methods.

AppleScript -> Shell

Embeding a bit of shell script into AppleScript is easy. Here's an AppleScript handler that takes a date like the one above and returns a nicely formatting compact timestamp

on FormatTime(AS_Date)

    return (do shell script "date -j -f '%A, %B %e, %Y %l:%M:%S %p' '" & AS_Date & "' '+%Y%m%d_%H-%M-%S'")

end FormatTime

where "AS_Date" is the native AppleScript timestamp. This works, but it's not very universal. The AS_Date must always be in the format of "Wednesday, December 21, 2011 7:24:22 PM" or the script will throw an error.

So I have another bit of AppleScript that relies on Python to do the hard bit of parsing a date and returning a formatted timestamp

AppleScript -> Shell -> Python

That's right, AppleScript runs a shell command, which in turn calls the Python processor. Now that Python is running within the AppleScript, I have access to some of the best date and time libraries around. Specifically, the dateutil never disappoints.

on pyFormatTime(AS_Date)

set timeFormat to quoted form of "%Y%m%d_%H%M%S"

return (do shell script "/usr/bin/python -c \"import time, dateutil.parser; print dateutil.parser.parse(" & AS_Date & ").strftime(" & timeFormat & "); \"")

end pyFormatTime

In this case, the AppleScript handler can accept any kind of date without knowledge of the format. It can then process the date and return a timestamp in my preferred format. For example all of the following dates will give the same timestamp:

  • "12-21-2011 7:24:22 PM"
  • "12-21-2011 19:24:22"
  • "12/21/2011 7:24:22 PM"
  • "Dec 21, 2011 7:24:22 PM"

If I wanted to get really fancy, I could also use parsedatetime to accept even more awkward date formats and return a specific timestamp. No need to go crazy though.