How do I get the S3 key's created date with boto?

Answering the old question, just in case others run into the same issue.

Amazon S3 maintains only the last modified date for each object. For example, the Amazon S3 console shows the Last Modified date in the object Properties pane. When you initially create a new object, this date reflects the date the object is created. If you replace the object, the date changes accordingly. So when we use the term creation date, it is synonymous with the term last modified date.

Reference: https://docs.aws.amazon.com/AmazonS3/latest/dev/intro-lifecycle-rules.html


After additional research, it appears that S3 key objects returned from a list() may not include this metadata field!

The Key objects returned by the iterator are obtained by parsing the results of a GET on the bucket, also known as the List Objects request. The XML returned by this request contains only a subset of the information about each key. Certain metadata fields such as Content-Type and user metadata are not available in the XML. Therefore, if you want these additional metadata fields you will have to do a HEAD request on the Key in the bucket. (docs)

In other words, looping through keys:

for key in conn.get_bucket(bucket_name).list():
     print key.date

... does not return the complete key with creation date and some other system metadata. (For example, it's also missing ACL data).

Instead, to retrieve the complete key metadata, use this method:

key = bucket.get_key(key.name)
print key.date

This necessitates an additional HTTP request as the docs clearly state above. (See also my original issue report.)

Additional code details:

import boto

# get connection
conn = boto.connect_s3()

# get first bucket
bucket = conn.get_all_buckets()[0]

# get first key in first bucket
key = list(bucket.list())[0]

# get create date if available
print getattr(key, "date", False)
# (False)

# access key via bucket.get_key instead:
k = bucket.get_key(key.name)

# check again for create_date
getattr(k, "date", False)
# 'Sat, 03 Jan 2015 22:08:13 GMT'
# Wait, that's the current UTC time..?

# Also print last_modified...
print k.last_modified
# 'Fri, 26 Apr 2013 02:41:30 GMT'