47
47
# versioning attribute
48
48
_version = '0.15.2'
49
49
50
+ ### encoding ###
50
51
# PY3 encoding if we don't specify
51
52
_default_encoding = 'UTF-8'
52
53
@@ -64,22 +65,8 @@ def _ensure_encoding(encoding):
64
65
encoding = _default_encoding
65
66
return encoding
66
67
67
- def _set_tz (values , tz , preserve_UTC = False ):
68
- """ set the timezone if values are an Index """
69
- if tz is not None and isinstance (values , Index ):
70
- tz = _ensure_decoded (tz )
71
- if values .tz is None :
72
- values = values .tz_localize ('UTC' ).tz_convert (tz )
73
- if preserve_UTC :
74
- if tslib .get_timezone (tz ) == 'UTC' :
75
- values = list (values )
76
-
77
- return values
78
-
79
-
80
68
Term = Expr
81
69
82
-
83
70
def _ensure_term (where , scope_level ):
84
71
"""
85
72
ensure that the where is a Term or a list of Term
@@ -1947,14 +1934,11 @@ def set_atom_datetime64tz(self, block, info, values=None):
1947
1934
if values is None :
1948
1935
values = block .values
1949
1936
1950
- # convert this column to datetime64[ns] utc , and save the tz
1951
- values = values .tz_convert ( 'UTC' ). values . view ( 'i8' ) .reshape (block .shape )
1937
+ # convert this column to i8 in UTC , and save the tz
1938
+ values = values .asi8 .reshape (block .shape )
1952
1939
1953
1940
# store a converted timezone
1954
- zone = tslib .get_timezone (block .values .tz )
1955
- if zone is None :
1956
- zone = tslib .tot_seconds (block .values .tz .utcoffset ())
1957
- self .tz = zone
1941
+ self .tz = _get_tz (block .values .tz )
1958
1942
self .update_info (info )
1959
1943
1960
1944
self .kind = 'datetime64'
@@ -2015,18 +1999,9 @@ def convert(self, values, nan_rep, encoding):
2015
1999
2016
2000
# reverse converts
2017
2001
if dtype == u ('datetime64' ):
2018
- # recreate the timezone
2019
- if self .tz is not None :
2020
-
2021
- # data should be 2-dim here
2022
- # we stored as utc, so just set the tz
2023
2002
2024
- index = DatetimeIndex (
2025
- self .data .ravel (), tz = 'UTC' ).tz_convert (tslib .maybe_get_tz (self .tz ))
2026
- self .data = index
2027
-
2028
- else :
2029
- self .data = np .asarray (self .data , dtype = 'M8[ns]' )
2003
+ # recreate with tz if indicated
2004
+ self .data = _set_tz (self .data , self .tz , coerce = True )
2030
2005
2031
2006
elif dtype == u ('timedelta64' ):
2032
2007
self .data = np .asarray (self .data , dtype = 'm8[ns]' )
@@ -2347,7 +2322,10 @@ def read_array(self, key):
2347
2322
ret = data
2348
2323
2349
2324
if dtype == u ('datetime64' ):
2350
- ret = np .asarray (ret , dtype = 'M8[ns]' )
2325
+
2326
+ # reconstruct a timezone if indicated
2327
+ ret = _set_tz (ret , getattr (attrs , 'tz' , None ), coerce = True )
2328
+
2351
2329
elif dtype == u ('timedelta64' ):
2352
2330
ret = np .asarray (ret , dtype = 'm8[ns]' )
2353
2331
@@ -2397,10 +2375,7 @@ def write_index(self, key, index):
2397
2375
node ._v_attrs .freq = index .freq
2398
2376
2399
2377
if hasattr (index , 'tz' ) and index .tz is not None :
2400
- zone = tslib .get_timezone (index .tz )
2401
- if zone is None :
2402
- zone = tslib .tot_seconds (index .tz .utcoffset ())
2403
- node ._v_attrs .tz = zone
2378
+ node ._v_attrs .tz = _get_tz (index .tz )
2404
2379
2405
2380
def write_block_index (self , key , index ):
2406
2381
self .write_array ('%s_blocs' % key , index .blocs )
@@ -2574,11 +2549,20 @@ def write_array(self, key, value, items=None):
2574
2549
if empty_array :
2575
2550
self .write_array_empty (key , value )
2576
2551
else :
2577
- if value .dtype . type == np . datetime64 :
2552
+ if com . is_datetime64_dtype ( value .dtype ) :
2578
2553
self ._handle .create_array (self .group , key , value .view ('i8' ))
2579
2554
getattr (
2580
2555
self .group , key )._v_attrs .value_type = 'datetime64'
2581
- elif value .dtype .type == np .timedelta64 :
2556
+ elif com .is_datetime64tz_dtype (value .dtype ):
2557
+ # store as UTC
2558
+ # with a zone
2559
+ self ._handle .create_array (self .group , key ,
2560
+ value .asi8 )
2561
+
2562
+ node = getattr (self .group , key )
2563
+ node ._v_attrs .tz = _get_tz (value .tz )
2564
+ node ._v_attrs .value_type = 'datetime64'
2565
+ elif com .is_timedelta64_dtype (value .dtype ):
2582
2566
self ._handle .create_array (self .group , key , value .view ('i8' ))
2583
2567
getattr (
2584
2568
self .group , key )._v_attrs .value_type = 'timedelta64'
@@ -4248,6 +4232,40 @@ def _get_info(info, name):
4248
4232
idx = info [name ] = dict ()
4249
4233
return idx
4250
4234
4235
+ ### tz to/from coercion ###
4236
+ def _get_tz (tz ):
4237
+ """ for a tz-aware type, return an encoded zone """
4238
+ zone = tslib .get_timezone (tz )
4239
+ if zone is None :
4240
+ zone = tslib .tot_seconds (tz .utcoffset ())
4241
+ return zone
4242
+
4243
+ def _set_tz (values , tz , preserve_UTC = False , coerce = False ):
4244
+ """
4245
+ coerce the values to a DatetimeIndex if tz is set
4246
+ preserve the input shape if possible
4247
+
4248
+ Parameters
4249
+ ----------
4250
+ values : ndarray
4251
+ tz : string/pickled tz object
4252
+ preserve_UTC : boolean,
4253
+ preserve the UTC of the result
4254
+ coerce : if we do not have a passed timezone, coerce to M8[ns] ndarray
4255
+ """
4256
+ if tz is not None :
4257
+ values = values .ravel ()
4258
+ tz = tslib .get_timezone (_ensure_decoded (tz ))
4259
+ values = DatetimeIndex (values )
4260
+ if values .tz is None :
4261
+ values = values .tz_localize ('UTC' ).tz_convert (tz )
4262
+ if preserve_UTC :
4263
+ if tz == 'UTC' :
4264
+ values = list (values )
4265
+ elif coerce :
4266
+ values = np .asarray (values , dtype = 'M8[ns]' )
4267
+
4268
+ return values
4251
4269
4252
4270
def _convert_index (index , encoding = None , format_type = None ):
4253
4271
index_name = getattr (index , 'name' , None )
0 commit comments