Skip to content

Commit 1186b79

Browse files
author
Chang She
committed
BUG: FixedOffsetTimeZone #1922
1 parent 601cfd6 commit 1186b79

File tree

2 files changed

+38
-5
lines changed

2 files changed

+38
-5
lines changed

pandas/src/datetime.pyx

+13-4
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,12 @@ cdef class _TSObject:
525525
def __get__(self):
526526
return self.value
527527

528+
cpdef _get_utcoffset(tzinfo):
529+
try:
530+
return tzinfo._utcoffset
531+
except AttributeError:
532+
return tzinfo.utcoffset(None)
533+
528534
# helper to extract datetime and int64 from several different possibilities
529535
cpdef convert_to_tsobject(object ts, object tz=None):
530536
"""
@@ -565,7 +571,7 @@ cpdef convert_to_tsobject(object ts, object tz=None):
565571
elif tz is not pytz.utc:
566572
ts = tz.localize(ts)
567573
obj.value = _pydatetime_to_dts(ts, &obj.dts)
568-
obj.value -= _delta_to_nanoseconds(ts.tzinfo._utcoffset)
574+
obj.value -= _delta_to_nanoseconds(_get_utcoffset(ts.tzinfo))
569575
obj.tzinfo = ts.tzinfo
570576
else:
571577
# UTC
@@ -575,7 +581,7 @@ cpdef convert_to_tsobject(object ts, object tz=None):
575581
obj.value = _pydatetime_to_dts(ts, &obj.dts)
576582
obj.tzinfo = ts.tzinfo
577583
if obj.tzinfo is not None and not _is_utc(obj.tzinfo):
578-
obj.value -= _delta_to_nanoseconds(obj.tzinfo._utcoffset)
584+
obj.value -= _delta_to_nanoseconds(_get_utcoffset(obj.tzinfo))
579585
_check_dts_bounds(obj.value, &obj.dts)
580586
return obj
581587
elif PyDate_Check(ts):
@@ -616,7 +622,10 @@ cdef inline object _get_zone(object tz):
616622
if _is_utc(tz):
617623
return 'UTC'
618624
else:
619-
return tz.zone
625+
try:
626+
return tz.zone
627+
except AttributeError:
628+
return tz
620629

621630
cdef int64_t _NS_LOWER_BOUND = -9223285636854775809LL
622631
cdef int64_t _NS_UPPER_BOUND = -9223372036854775807LL
@@ -1009,7 +1018,7 @@ def _get_deltas(tz):
10091018
utc_offset_cache[tz] = _unbox_utcoffsets(tz._transition_info)
10101019
else:
10111020
# static tzinfo
1012-
num = int(total_seconds(tz._utcoffset)) * 1000000000
1021+
num = int(total_seconds(_get_utcoffset(tz))) * 1000000000
10131022
utc_offset_cache[tz] = np.array([num], dtype=np.int64)
10141023
return utc_offset_cache[tz]
10151024

pandas/tseries/tests/test_timezones.py

+25-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# pylint: disable-msg=E1101,W0612
22
from __future__ import with_statement # for Python 2.5
3-
from datetime import datetime, time, timedelta
3+
from datetime import datetime, time, timedelta, tzinfo
44
import sys
55
import os
66
import unittest
@@ -44,6 +44,23 @@ def _skip_if_no_pytz():
4444
except ImportError:
4545
pass
4646

47+
class FixedOffset(tzinfo):
48+
"""Fixed offset in minutes east from UTC."""
49+
50+
def __init__(self, offset, name):
51+
self.__offset = timedelta(minutes = offset)
52+
self.__name = name
53+
54+
def utcoffset(self, dt):
55+
return self.__offset
56+
57+
def tzname(self, dt):
58+
return self.__name
59+
60+
def dst(self, dt):
61+
return timedelta(0)
62+
63+
fixed_off = FixedOffset(-4200, '-07:00')
4764

4865
class TestTimeZoneSupport(unittest.TestCase):
4966

@@ -353,6 +370,13 @@ def test_string_index_alias_tz_aware(self):
353370
result = ts['1/3/2000']
354371
self.assertAlmostEqual(result, ts[2])
355372

373+
def test_fixed_offset(self):
374+
dates = [datetime(2000, 1, 1, tzinfo=fixed_off),
375+
datetime(2000, 1, 2, tzinfo=fixed_off),
376+
datetime(2000, 1, 3, tzinfo=fixed_off)]
377+
result = to_datetime(dates)
378+
self.assert_(result.tz == fixed_off)
379+
356380
def test_convert_tz_aware_datetime_datetime(self):
357381
# #1581
358382

0 commit comments

Comments
 (0)