Skip to content

Commit 48b9ece

Browse files
committed
Normalize more dates to user-requested timezone
Some times were in UTC, some were in the TWS timezone, and some were using request client defaults. Now all timezones get normalized to user defaults setting timezone (if provided), otherwise falls back to tws or default timezone. Fixes #181 (if you use the IBDefaults timezone system)
1 parent 3147b77 commit 48b9ece

1 file changed

Lines changed: 15 additions & 3 deletions

File tree

ib_async/wrapper.py

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
from dataclasses import dataclass, field
99
from datetime import datetime
1010
from typing import TYPE_CHECKING, Any, Final, TypeAlias, cast
11+
from zoneinfo import ZoneInfo
1112

1213
from ib_async.contract import (
1314
Contract,
@@ -367,6 +368,17 @@ def connectionClosed(self):
367368
globalErrorEvent.emit(error)
368369
self.reset()
369370

371+
def _normalizeDatetime(self, value: datetime | Any) -> datetime | Any:
372+
"""Convert datetime values to the configured default timezone."""
373+
if not isinstance(value, datetime):
374+
return value
375+
376+
if value.tzinfo is None:
377+
tz = ZoneInfo(str(self.ib.TimezoneTWS)) if self.ib.TimezoneTWS else None
378+
value = value.replace(tzinfo=tz or self.defaultTimezone)
379+
380+
return value.astimezone(self.defaultTimezone)
381+
370382
def startReq(self, key, contract=None, container=None):
371383
"""
372384
Start a new request and return the future that is associated
@@ -914,7 +926,7 @@ def realtimeBar(
914926
def historicalData(self, reqId: int, bar: BarData):
915927
results = self._results.get(reqId)
916928
if results is not None:
917-
bar.date = parseIBDatetime(bar.date) # type: ignore
929+
bar.date = self._normalizeDatetime(parseIBDatetime(bar.date)) # type: ignore[arg-type]
918930
results.append(bar)
919931

920932
def historicalDataEnd(self, reqId, _start: str, _end: str):
@@ -925,7 +937,7 @@ def historicalDataUpdate(self, reqId: int, bar: BarData):
925937
if not bars:
926938
return
927939

928-
bar.date = parseIBDatetime(bar.date) # type: ignore
940+
bar.date = self._normalizeDatetime(parseIBDatetime(bar.date)) # type: ignore[arg-type]
929941
lastDate = bars[-1].date
930942
if bar.date < lastDate:
931943
return
@@ -943,7 +955,7 @@ def historicalDataUpdate(self, reqId: int, bar: BarData):
943955

944956
def headTimestamp(self, reqId: int, headTimestamp: str):
945957
try:
946-
dt = parseIBDatetime(headTimestamp)
958+
dt = self._normalizeDatetime(parseIBDatetime(headTimestamp))
947959
self._endReq(reqId, dt)
948960
except ValueError as exc:
949961
self._endReq(reqId, exc, False)

0 commit comments

Comments
 (0)