Skip to content

Commit 34f04ac

Browse files
MarcoGorellimliu08
authored andcommitted
CLN Simplify tz / utc arguments (pandas-dev#49863)
Simplify tz / utc arguments Co-authored-by: MarcoGorelli <>
1 parent fd419d8 commit 34f04ac

File tree

4 files changed

+46
-49
lines changed

4 files changed

+46
-49
lines changed

pandas/core/arrays/datetimes.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2134,7 +2134,7 @@ def objects_to_datetime64ns(
21342134
dayfirst : bool
21352135
yearfirst : bool
21362136
utc : bool, default False
2137-
Whether to convert timezone-aware timestamps to UTC.
2137+
Whether to convert/localize timestamps to UTC.
21382138
errors : {'raise', 'ignore', 'coerce'}
21392139
require_iso8601 : bool, default False
21402140
allow_object : bool

pandas/core/tools/datetimes.py

+43-46
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
AnyArrayLike,
3939
ArrayLike,
4040
DateTimeErrorChoices,
41-
Timezone,
4241
npt,
4342
)
4443

@@ -239,7 +238,7 @@ def _maybe_cache(
239238

240239

241240
def _box_as_indexlike(
242-
dt_array: ArrayLike, utc: bool | None = None, name: Hashable = None
241+
dt_array: ArrayLike, utc: bool = False, name: Hashable = None
243242
) -> Index:
244243
"""
245244
Properly boxes the ndarray of datetimes to DatetimeIndex
@@ -249,8 +248,8 @@ def _box_as_indexlike(
249248
----------
250249
dt_array: 1-d array
251250
Array of datetimes to be wrapped in an Index.
252-
tz : object
253-
None or 'utc'
251+
utc : bool
252+
Whether to convert/localize timestamps to UTC.
254253
name : string, default None
255254
Name for a resulting index
256255
@@ -290,10 +289,12 @@ def _convert_and_box_cache(
290289
from pandas import Series
291290

292291
result = Series(arg).map(cache_array)
293-
return _box_as_indexlike(result._values, utc=None, name=name)
292+
return _box_as_indexlike(result._values, utc=False, name=name)
294293

295294

296-
def _return_parsed_timezone_results(result: np.ndarray, timezones, tz, name) -> Index:
295+
def _return_parsed_timezone_results(
296+
result: np.ndarray, timezones, utc: bool, name
297+
) -> Index:
297298
"""
298299
Return results from array_strptime if a %z or %Z directive was passed.
299300
@@ -303,8 +304,8 @@ def _return_parsed_timezone_results(result: np.ndarray, timezones, tz, name) ->
303304
int64 date representations of the dates
304305
timezones : ndarray
305306
pytz timezone objects
306-
tz : object
307-
None or pytz timezone object
307+
utc : bool
308+
Whether to convert/localize timestamps to UTC.
308309
name : string, default None
309310
Name for a DatetimeIndex
310311
@@ -315,9 +316,9 @@ def _return_parsed_timezone_results(result: np.ndarray, timezones, tz, name) ->
315316
tz_results = np.array(
316317
[Timestamp(res).tz_localize(zone) for res, zone in zip(result, timezones)]
317318
)
318-
if tz is not None:
319+
if utc:
319320
# Convert to the same tz
320-
tz_results = np.array([tz_result.tz_convert(tz) for tz_result in tz_results])
321+
tz_results = np.array([tz_result.tz_convert("utc") for tz_result in tz_results])
321322

322323
return Index(tz_results, name=name)
323324

@@ -326,7 +327,7 @@ def _convert_listlike_datetimes(
326327
arg,
327328
format: str | None,
328329
name: Hashable = None,
329-
tz: Timezone | None = None,
330+
utc: bool = False,
330331
unit: str | None = None,
331332
errors: DateTimeErrorChoices = "raise",
332333
infer_datetime_format: bool = False,
@@ -344,8 +345,8 @@ def _convert_listlike_datetimes(
344345
date to be parsed
345346
name : object
346347
None or string for the Index name
347-
tz : object
348-
None or 'utc'
348+
utc : bool
349+
Whether to convert/localize timestamps to UTC.
349350
unit : str
350351
None or string of the frequency of the passed data
351352
errors : str
@@ -368,11 +369,12 @@ def _convert_listlike_datetimes(
368369

369370
arg_dtype = getattr(arg, "dtype", None)
370371
# these are shortcutable
372+
tz = "utc" if utc else None
371373
if is_datetime64tz_dtype(arg_dtype):
372374
if not isinstance(arg, (DatetimeArray, DatetimeIndex)):
373375
return DatetimeIndex(arg, tz=tz, name=name)
374-
if tz == "utc":
375-
arg = arg.tz_convert(None).tz_localize(tz)
376+
if utc:
377+
arg = arg.tz_convert(None).tz_localize("utc")
376378
return arg
377379

378380
elif is_datetime64_ns_dtype(arg_dtype):
@@ -381,16 +383,16 @@ def _convert_listlike_datetimes(
381383
return DatetimeIndex(arg, tz=tz, name=name)
382384
except ValueError:
383385
pass
384-
elif tz:
386+
elif utc:
385387
# DatetimeArray, DatetimeIndex
386-
return arg.tz_localize(tz)
388+
return arg.tz_localize("utc")
387389

388390
return arg
389391

390392
elif unit is not None:
391393
if format is not None:
392394
raise ValueError("cannot specify both format and unit")
393-
return _to_datetime_with_unit(arg, unit, name, tz, errors)
395+
return _to_datetime_with_unit(arg, unit, name, utc, errors)
394396
elif getattr(arg, "ndim", 1) > 1:
395397
raise TypeError(
396398
"arg must be a string, datetime, list, tuple, 1-d array, or Series"
@@ -427,12 +429,11 @@ def _convert_listlike_datetimes(
427429

428430
if format is not None and not require_iso8601:
429431
res = _to_datetime_with_format(
430-
arg, orig_arg, name, tz, format, exact, errors, infer_datetime_format
432+
arg, orig_arg, name, utc, format, exact, errors, infer_datetime_format
431433
)
432434
if res is not None:
433435
return res
434436

435-
utc = tz == "utc"
436437
result, tz_parsed = objects_to_datetime64ns(
437438
arg,
438439
dayfirst=dayfirst,
@@ -451,14 +452,13 @@ def _convert_listlike_datetimes(
451452
dta = DatetimeArray(result, dtype=tz_to_dtype(tz_parsed))
452453
return DatetimeIndex._simple_new(dta, name=name)
453454

454-
utc = tz == "utc"
455455
return _box_as_indexlike(result, utc=utc, name=name)
456456

457457

458458
def _array_strptime_with_fallback(
459459
arg,
460460
name,
461-
tz,
461+
utc: bool,
462462
fmt: str,
463463
exact: bool,
464464
errors: str,
@@ -467,8 +467,6 @@ def _array_strptime_with_fallback(
467467
"""
468468
Call array_strptime, with fallback behavior depending on 'errors'.
469469
"""
470-
utc = tz == "utc"
471-
472470
try:
473471
result, timezones = array_strptime(arg, fmt, exact=exact, errors=errors)
474472
except OutOfBoundsDatetime:
@@ -498,7 +496,7 @@ def _array_strptime_with_fallback(
498496
return None
499497
else:
500498
if "%Z" in fmt or "%z" in fmt:
501-
return _return_parsed_timezone_results(result, timezones, tz, name)
499+
return _return_parsed_timezone_results(result, timezones, utc, name)
502500

503501
return _box_as_indexlike(result, utc=utc, name=name)
504502

@@ -507,7 +505,7 @@ def _to_datetime_with_format(
507505
arg,
508506
orig_arg,
509507
name,
510-
tz,
508+
utc: bool,
511509
fmt: str,
512510
exact: bool,
513511
errors: str,
@@ -531,17 +529,16 @@ def _to_datetime_with_format(
531529
"cannot convert the input to '%Y%m%d' date format"
532530
) from err
533531
if result is not None:
534-
utc = tz == "utc"
535532
return _box_as_indexlike(result, utc=utc, name=name)
536533

537534
# fallback
538535
res = _array_strptime_with_fallback(
539-
arg, name, tz, fmt, exact, errors, infer_datetime_format
536+
arg, name, utc, fmt, exact, errors, infer_datetime_format
540537
)
541538
return res
542539

543540

544-
def _to_datetime_with_unit(arg, unit, name, tz, errors: str) -> Index:
541+
def _to_datetime_with_unit(arg, unit, name, utc: bool, errors: str) -> Index:
545542
"""
546543
to_datetime specalized to the case where a 'unit' is passed.
547544
"""
@@ -570,11 +567,11 @@ def _to_datetime_with_unit(arg, unit, name, tz, errors: str) -> Index:
570567
# result will be naive but in UTC
571568
result = result.tz_localize("UTC").tz_convert(tz_parsed)
572569

573-
if tz is not None:
570+
if utc:
574571
if result.tz is None:
575-
result = result.tz_localize(tz)
572+
result = result.tz_localize("utc")
576573
else:
577-
result = result.tz_convert(tz)
574+
result = result.tz_convert("utc")
578575
return result
579576

580577

@@ -657,7 +654,7 @@ def to_datetime(
657654
errors: DateTimeErrorChoices = ...,
658655
dayfirst: bool = ...,
659656
yearfirst: bool = ...,
660-
utc: bool | None = ...,
657+
utc: bool = ...,
661658
format: str | None = ...,
662659
exact: bool = ...,
663660
unit: str | None = ...,
@@ -674,7 +671,7 @@ def to_datetime(
674671
errors: DateTimeErrorChoices = ...,
675672
dayfirst: bool = ...,
676673
yearfirst: bool = ...,
677-
utc: bool | None = ...,
674+
utc: bool = ...,
678675
format: str | None = ...,
679676
exact: bool = ...,
680677
unit: str | None = ...,
@@ -691,7 +688,7 @@ def to_datetime(
691688
errors: DateTimeErrorChoices = ...,
692689
dayfirst: bool = ...,
693690
yearfirst: bool = ...,
694-
utc: bool | None = ...,
691+
utc: bool = ...,
695692
format: str | None = ...,
696693
exact: bool = ...,
697694
unit: str | None = ...,
@@ -707,7 +704,7 @@ def to_datetime(
707704
errors: DateTimeErrorChoices = "raise",
708705
dayfirst: bool = False,
709706
yearfirst: bool = False,
710-
utc: bool | None = None,
707+
utc: bool = False,
711708
format: str | None = None,
712709
exact: bool = True,
713710
unit: str | None = None,
@@ -756,7 +753,7 @@ def to_datetime(
756753
``yearfirst=True`` is not strict, but will prefer to parse
757754
with year first.
758755
759-
utc : bool, default None
756+
utc : bool, default False
760757
Control timezone-related parsing, localization and conversion.
761758
762759
- If :const:`True`, the function *always* returns a timezone-aware
@@ -1049,10 +1046,9 @@ def to_datetime(
10491046
if origin != "unix":
10501047
arg = _adjust_to_origin(arg, origin, unit)
10511048

1052-
tz = "utc" if utc else None
10531049
convert_listlike = partial(
10541050
_convert_listlike_datetimes,
1055-
tz=tz,
1051+
utc=utc,
10561052
unit=unit,
10571053
dayfirst=dayfirst,
10581054
yearfirst=yearfirst,
@@ -1065,11 +1061,11 @@ def to_datetime(
10651061

10661062
if isinstance(arg, Timestamp):
10671063
result = arg
1068-
if tz is not None:
1064+
if utc:
10691065
if arg.tz is not None:
1070-
result = arg.tz_convert(tz)
1066+
result = arg.tz_convert("utc")
10711067
else:
1072-
result = arg.tz_localize(tz)
1068+
result = arg.tz_localize("utc")
10731069
elif isinstance(arg, ABCSeries):
10741070
cache_array = _maybe_cache(arg, format, cache, convert_listlike)
10751071
if not cache_array.empty:
@@ -1078,7 +1074,7 @@ def to_datetime(
10781074
values = convert_listlike(arg._values, format)
10791075
result = arg._constructor(values, index=arg.index, name=arg.name)
10801076
elif isinstance(arg, (ABCDataFrame, abc.MutableMapping)):
1081-
result = _assemble_from_unit_mappings(arg, errors, tz)
1077+
result = _assemble_from_unit_mappings(arg, errors, utc)
10821078
elif isinstance(arg, Index):
10831079
cache_array = _maybe_cache(arg, format, cache, convert_listlike)
10841080
if not cache_array.empty:
@@ -1145,7 +1141,7 @@ def to_datetime(
11451141
}
11461142

11471143

1148-
def _assemble_from_unit_mappings(arg, errors: DateTimeErrorChoices, tz):
1144+
def _assemble_from_unit_mappings(arg, errors: DateTimeErrorChoices, utc: bool):
11491145
"""
11501146
assemble the unit specified fields from the arg (DataFrame)
11511147
Return a Series for actual parsing
@@ -1158,7 +1154,8 @@ def _assemble_from_unit_mappings(arg, errors: DateTimeErrorChoices, tz):
11581154
- If :const:`'raise'`, then invalid parsing will raise an exception
11591155
- If :const:`'coerce'`, then invalid parsing will be set as :const:`NaT`
11601156
- If :const:`'ignore'`, then invalid parsing will return the input
1161-
tz : None or 'utc'
1157+
utc : bool
1158+
Whether to convert/localize timestamps to UTC.
11621159
11631160
Returns
11641161
-------
@@ -1221,7 +1218,7 @@ def coerce(values):
12211218
+ coerce(arg[unit_rev["day"]])
12221219
)
12231220
try:
1224-
values = to_datetime(values, format="%Y%m%d", errors=errors, utc=tz)
1221+
values = to_datetime(values, format="%Y%m%d", errors=errors, utc=utc)
12251222
except (TypeError, ValueError) as err:
12261223
raise ValueError(f"cannot assemble the datetimes: {err}") from err
12271224

pandas/io/parsers/base_parser.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1115,7 +1115,7 @@ def converter(*date_cols):
11151115
try:
11161116
return tools.to_datetime(
11171117
ensure_object(strs),
1118-
utc=None,
1118+
utc=False,
11191119
dayfirst=dayfirst,
11201120
errors="ignore",
11211121
infer_datetime_format=infer_datetime_format,

pandas/io/sql.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ def _process_parse_dates_argument(parse_dates):
9191

9292

9393
def _handle_date_column(
94-
col, utc: bool | None = None, format: str | dict[str, Any] | None = None
94+
col, utc: bool = False, format: str | dict[str, Any] | None = None
9595
):
9696
if isinstance(format, dict):
9797
# GH35185 Allow custom error values in parse_dates argument of

0 commit comments

Comments
 (0)