Skip to content
15 changes: 15 additions & 0 deletions google/cloud/storage/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@

import base64
from hashlib import md5
from datetime import datetime
import os

from google.cloud.storage.constants import _DEFAULT_TIMEOUT
Expand Down Expand Up @@ -297,3 +298,17 @@ def _base64_md5hash(buffer_object):
_write_buffer_to_hash(buffer_object, hash_obj)
digest_bytes = hash_obj.digest()
return base64.b64encode(digest_bytes)


def _convert_to_timestamp(value):
"""Convert non-none datetime to timestamp.

:type value: :class:`datetime.datetime`
:param value: The datetime to convert.

:rtype: int
:returns: The timestamp.
"""
utc_naive = value.replace(tzinfo=None) - value.utcoffset()
mtime = (utc_naive - datetime(1970, 1, 1)).total_seconds()
return mtime
8 changes: 6 additions & 2 deletions google/cloud/storage/blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@
from io import BytesIO
import mimetypes
import os
import time
import warnings
import six

from six.moves.urllib.parse import parse_qsl
from six.moves.urllib.parse import quote
Expand All @@ -57,6 +57,7 @@
from google.cloud.storage._helpers import _get_storage_host
from google.cloud.storage._helpers import _PropertyMixin
from google.cloud.storage._helpers import _scalar_property
from google.cloud.storage._helpers import _convert_to_timestamp
from google.cloud.storage._signing import generate_signed_url_v2
from google.cloud.storage._signing import generate_signed_url_v4
from google.cloud.storage.acl import ACL
Expand Down Expand Up @@ -846,7 +847,10 @@ def download_to_filename(

updated = self.updated
if updated is not None:
mtime = time.mktime(updated.timetuple())
if six.PY2:
mtime = _convert_to_timestamp(updated)
else:
mtime = updated.timestamp()
os.utime(file_obj.name, (mtime, mtime))

def download_as_string(self, client=None, start=None, end=None, raw_download=False):
Expand Down
7 changes: 5 additions & 2 deletions tests/unit/test_blob.py
Original file line number Diff line number Diff line change
Expand Up @@ -1060,7 +1060,7 @@ def test_download_to_file_w_chunks_w_raw(self):

def _download_to_filename_helper(self, updated, raw_download):
import os
import time
from google.cloud.storage._helpers import _convert_to_timestamp
from google.cloud._testing import _NamedTemporaryFile

blob_name = "blob-name"
Expand All @@ -1080,7 +1080,10 @@ def _download_to_filename_helper(self, updated, raw_download):
self.assertIsNone(blob.updated)
else:
mtime = os.path.getmtime(temp.name)
updated_time = time.mktime(blob.updated.timetuple())
if six.PY2:
updated_time = _convert_to_timestamp(blob.updated)
else:
updated_time = blob.updated.timestamp()
self.assertEqual(mtime, updated_time)

headers = {"accept-encoding": "gzip"}
Expand Down