|
26 | 26 | import nose
|
27 | 27 | import warnings
|
28 | 28 | import numpy as np
|
| 29 | +import pandas as pd |
29 | 30 |
|
30 | 31 | from datetime import datetime, date, time
|
31 | 32 |
|
32 | 33 | from pandas import DataFrame, Series, Index, MultiIndex, isnull, concat
|
33 | 34 | from pandas import date_range, to_datetime, to_timedelta, Timestamp
|
34 | 35 | import pandas.compat as compat
|
35 | 36 | from pandas.compat import StringIO, range, lrange, string_types
|
| 37 | +from pandas.core import common as com |
36 | 38 | from pandas.core.datetools import format as date_format
|
37 | 39 |
|
38 | 40 | import pandas.io.sql as sql
|
@@ -1248,6 +1250,66 @@ def test_default_date_load(self):
|
1248 | 1250 | self.assertTrue(issubclass(df.DateCol.dtype.type, np.datetime64),
|
1249 | 1251 | "DateCol loaded with incorrect type")
|
1250 | 1252 |
|
| 1253 | + def test_datetime_with_timezone(self): |
| 1254 | + # edge case that converts postgresql datetime with time zone types |
| 1255 | + # to datetime64[ns,psycopg2.tz.FixedOffsetTimezone..], which is ok |
| 1256 | + # but should be more natural, so coerce to datetime64[ns] for now |
| 1257 | + |
| 1258 | + def check(col): |
| 1259 | + # check that a column is either datetime64[ns] |
| 1260 | + # or datetime64[ns, UTC] |
| 1261 | + if com.is_datetime64_dtype(col.dtype): |
| 1262 | + |
| 1263 | + # "2000-01-01 00:00:00-08:00" should convert to "2000-01-01 08:00:00" |
| 1264 | + self.assertEqual(col[0], Timestamp('2000-01-01 08:00:00')) |
| 1265 | + |
| 1266 | + # "2000-06-01 00:00:00-07:00" should convert to "2000-06-01 07:00:00" |
| 1267 | + self.assertEqual(col[1], Timestamp('2000-06-01 07:00:00')) |
| 1268 | + |
| 1269 | + elif com.is_datetime64tz_dtype(col.dtype): |
| 1270 | + self.assertTrue(str(col.dt.tz) == 'UTC') |
| 1271 | + |
| 1272 | + # "2000-01-01 00:00:00-08:00" should convert to "2000-01-01 08:00:00" |
| 1273 | + self.assertEqual(col[0], Timestamp('2000-01-01 08:00:00', tz='UTC')) |
| 1274 | + |
| 1275 | + # "2000-06-01 00:00:00-07:00" should convert to "2000-06-01 07:00:00" |
| 1276 | + self.assertEqual(col[1], Timestamp('2000-06-01 07:00:00', tz='UTC')) |
| 1277 | + |
| 1278 | + else: |
| 1279 | + raise AssertionError("DateCol loaded with incorrect type -> {0}".format(col.dtype)) |
| 1280 | + |
| 1281 | + # GH11216 |
| 1282 | + df = pd.read_sql_query("select * from types_test_data", self.conn) |
| 1283 | + if not hasattr(df,'DateColWithTz'): |
| 1284 | + raise nose.SkipTest("no column with datetime with time zone") |
| 1285 | + |
| 1286 | + # this is parsed on Travis (linux), but not on macosx for some reason |
| 1287 | + # even with the same versions of psycopg2 & sqlalchemy, possibly a Postgrsql server |
| 1288 | + # version difference |
| 1289 | + col = df.DateColWithTz |
| 1290 | + self.assertTrue(com.is_object_dtype(col.dtype) or com.is_datetime64_dtype(col.dtype) \ |
| 1291 | + or com.is_datetime64tz_dtype(col.dtype), |
| 1292 | + "DateCol loaded with incorrect type -> {0}".format(col.dtype)) |
| 1293 | + |
| 1294 | + df = pd.read_sql_query("select * from types_test_data", self.conn, parse_dates=['DateColWithTz']) |
| 1295 | + if not hasattr(df,'DateColWithTz'): |
| 1296 | + raise nose.SkipTest("no column with datetime with time zone") |
| 1297 | + check(df.DateColWithTz) |
| 1298 | + |
| 1299 | + df = pd.concat(list(pd.read_sql_query("select * from types_test_data", |
| 1300 | + self.conn,chunksize=1)),ignore_index=True) |
| 1301 | + col = df.DateColWithTz |
| 1302 | + self.assertTrue(com.is_datetime64tz_dtype(col.dtype), |
| 1303 | + "DateCol loaded with incorrect type -> {0}".format(col.dtype)) |
| 1304 | + self.assertTrue(str(col.dt.tz) == 'UTC') |
| 1305 | + expected = sql.read_sql_table("types_test_data", self.conn) |
| 1306 | + tm.assert_series_equal(df.DateColWithTz, expected.DateColWithTz.astype('datetime64[ns, UTC]')) |
| 1307 | + |
| 1308 | + # xref #7139 |
| 1309 | + # this might or might not be converted depending on the postgres driver |
| 1310 | + df = sql.read_sql_table("types_test_data", self.conn) |
| 1311 | + check(df.DateColWithTz) |
| 1312 | + |
1251 | 1313 | def test_date_parsing(self):
|
1252 | 1314 | # No Parsing
|
1253 | 1315 | df = sql.read_sql_table("types_test_data", self.conn)
|
@@ -1746,23 +1808,6 @@ def test_schema_support(self):
|
1746 | 1808 | res2 = pdsql.read_table('test_schema_other2')
|
1747 | 1809 | tm.assert_frame_equal(res1, res2)
|
1748 | 1810 |
|
1749 |
| - def test_datetime_with_time_zone(self): |
1750 |
| - |
1751 |
| - # Test to see if we read the date column with timezones that |
1752 |
| - # the timezone information is converted to utc and into a |
1753 |
| - # np.datetime64 (GH #7139) |
1754 |
| - |
1755 |
| - df = sql.read_sql_table("types_test_data", self.conn) |
1756 |
| - self.assertTrue(issubclass(df.DateColWithTz.dtype.type, np.datetime64), |
1757 |
| - "DateColWithTz loaded with incorrect type -> {0}".format(df.DateColWithTz.dtype)) |
1758 |
| - |
1759 |
| - # "2000-01-01 00:00:00-08:00" should convert to "2000-01-01 08:00:00" |
1760 |
| - self.assertEqual(df.DateColWithTz[0], Timestamp('2000-01-01 08:00:00')) |
1761 |
| - |
1762 |
| - # "2000-06-01 00:00:00-07:00" should convert to "2000-06-01 07:00:00" |
1763 |
| - self.assertEqual(df.DateColWithTz[1], Timestamp('2000-06-01 07:00:00')) |
1764 |
| - |
1765 |
| - |
1766 | 1811 | class TestMySQLAlchemy(_TestMySQLAlchemy, _TestSQLAlchemy):
|
1767 | 1812 | pass
|
1768 | 1813 |
|
|
0 commit comments