Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 6 additions & 2 deletions bigquery/google/cloud/bigquery/_helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@
from collections import OrderedDict
import datetime

from google.cloud._helpers import UTC
from google.cloud._helpers import _date_from_iso8601_date
from google.cloud._helpers import _datetime_from_microseconds
from google.cloud._helpers import _datetime_to_rfc3339
from google.cloud._helpers import _microseconds_from_datetime
from google.cloud._helpers import _RFC3339_NO_FRACTION
from google.cloud._helpers import _time_from_iso8601_time_naive
from google.cloud._helpers import _to_bytes
Expand Down Expand Up @@ -150,7 +150,11 @@ def _bytes_to_json(value):
def _timestamp_to_json(value):

This comment was marked as spam.

This comment was marked as spam.

"""Coerce 'value' to an JSON-compatible representation."""
if isinstance(value, datetime.datetime):
value = _microseconds_from_datetime(value) / 1.0e6
if value.tzinfo not in (None, UTC):
# Convert to UTC and remove the time zone info.
value = value.replace(tzinfo=None) - value.utcoffset()
value = '%s %s+00:00' % (
value.date().isoformat(), value.time().isoformat())
return value


Expand Down
42 changes: 32 additions & 10 deletions bigquery/unit_tests/test__helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -546,13 +546,35 @@ def _call_fut(self, value):
def test_w_float(self):
self.assertEqual(self._call_fut(1.234567), 1.234567)

def test_w_datetime(self):
def test_w_string(self):
ZULU = '2016-12-20 15:58:27.339328+00:00'
self.assertEqual(self._call_fut(ZULU), ZULU)

def test_w_datetime_wo_zone(self):
import datetime
ZULU = '2016-12-20 15:58:27.339328+00:00'
when = datetime.datetime(2016, 12, 20, 15, 58, 27, 339328)
self.assertEqual(self._call_fut(when), ZULU)

def test_w_datetime_w_non_utc_zone(self):
import datetime

class _Zone(datetime.tzinfo):

def utcoffset(self, _):
return datetime.timedelta(minutes=-240)

ZULU = '2016-12-20 19:58:27.339328+00:00'
when = datetime.datetime(
2016, 12, 20, 15, 58, 27, 339328, tzinfo=_Zone())
self.assertEqual(self._call_fut(when), ZULU)

def test_w_datetime_w_utc_zone(self):
import datetime
from google.cloud._helpers import UTC
from google.cloud._helpers import _microseconds_from_datetime
when = datetime.datetime(2016, 12, 3, 14, 11, 27, tzinfo=UTC)
self.assertEqual(self._call_fut(when),
_microseconds_from_datetime(when) / 1e6)
ZULU = '2016-12-20 15:58:27.339328+00:00'
when = datetime.datetime(2016, 12, 20, 15, 58, 27, 339328, tzinfo=UTC)
self.assertEqual(self._call_fut(when), ZULU)


class Test_datetime_to_json(unittest.TestCase):
Expand Down Expand Up @@ -907,20 +929,20 @@ def test_to_api_repr_w_bool(self):
self.assertEqual(param.to_api_repr(), EXPECTED)

def test_to_api_repr_w_timestamp_datetime(self):
from google.cloud._helpers import UTC
import datetime
from google.cloud._helpers import _microseconds_from_datetime
now = datetime.datetime.utcnow()
seconds = _microseconds_from_datetime(now) / 1.0e6
STAMP = '2016-12-20 15:58:27.339328+00:00'
when = datetime.datetime(2016, 12, 20, 15, 58, 27, 339328, tzinfo=UTC)
EXPECTED = {
'parameterType': {
'type': 'TIMESTAMP',
},
'parameterValue': {
'value': seconds,
'value': STAMP,
},
}
klass = self._get_target_class()
param = klass.positional(type_='TIMESTAMP', value=now)
param = klass.positional(type_='TIMESTAMP', value=when)
self.assertEqual(param.to_api_repr(), EXPECTED)

def test_to_api_repr_w_timestamp_micros(self):
Expand Down
12 changes: 11 additions & 1 deletion system_tests/bigquery.py
Original file line number Diff line number Diff line change
Expand Up @@ -482,9 +482,12 @@ def _job_done(instance):
def test_sync_query_w_standard_sql_types(self):
import datetime
from google.cloud._helpers import UTC
from google.cloud.bigquery._helpers import ScalarQueryParameter
naive = datetime.datetime(2016, 12, 5, 12, 41, 9)
stamp = "%s %s" % (naive.date().isoformat(), naive.time().isoformat())
zoned = naive.replace(tzinfo=UTC)
zoned_param = ScalarQueryParameter(
name='zoned', type_='TIMESTAMP', value=zoned)
EXAMPLES = [
{
'sql': 'SELECT 1',
Expand Down Expand Up @@ -553,9 +556,16 @@ def test_sync_query_w_standard_sql_types(self):
'sql': 'SELECT ARRAY(SELECT STRUCT([1, 2]))',
'expected': [{u'_field_1': [1, 2]}],
},
{
'sql': 'SELECT @zoned',
'expected': zoned,
'query_parameters': [zoned_param],
},
]
for example in EXAMPLES:
query = Config.CLIENT.run_sync_query(example['sql'])
query = Config.CLIENT.run_sync_query(
example['sql'],
query_parameters=example.get('query_parameters', ()))
query.use_legacy_sql = False
query.run()
self.assertEqual(len(query.rows), 1)
Expand Down