我需要绘制一些补丁,这需要我使用 matplotlib mdate 模块(理想情况下)来控制刻度标记。我以前使用过 mdates,但我一生都无法弄清楚为什么我无法返回我期望的 EDT 时间(不使用奇怪的时区)。鉴于下面的代码,我希望看到转换后的值返回我开始时的值。
注意事项:
看代码:
print(f"Start Date: {startDt} TYPE: {type(startDt)}")
print(f"End Date: {endDt} TYPE: {type(endDt)}")
startDt_utc = startDt.tz_convert('UTC')
endDt_utc = endDt.tz_convert('UTC')
print(f'RAW :: start: {startDt:%b-%d:: %I:%M %p %Z}, end: {endDt:%b-%d:: %I:%M %p %Z}')
print(f'UTC :: start: {startDt_utc:%b-%d:: %I:%M %p %Z}, end: {endDt_utc:%b-%d:: %I:%M %p %Z}')
print(f'RAW mdates :: start: {mdates.date2num(startDt)}, end: {mdates.date2num(endDt)}')
print(f'UTC mdates :: start: {mdates.date2num(startDt_utc)}, end: {mdates.date2num(endDt_utc)}')
s,e = mdates.date2num(startDt),mdates.date2num(endDt)
sutc,eutc = mdates.date2num(startDt_utc),mdates.date2num(endDt_utc)
newS,newE = mdates.num2date(s,tz=pytz.timezone('US/Eastern')), mdates.num2date(e,tz=pytz.timezone('US/Eastern'))
newSutc,newEutc = mdates.num2date(sutc,tz=pytz.timezone('US/Eastern')), mdates.num2date(eutc,tz=pytz.timezone('US/Eastern'))
print(f'RAW cvtr :: start: {newS:%b-%d:: %I:%M %p %Z}, end: {newE:%b-%d:: %I:%M %p %Z}')
print(f'UTC cvtr :: start: {newSutc:%b-%d:: %I:%M %p %Z}, end: {newEutc:%b-%d:: %I:%M %p %Z}')
#####
newS,newE = mdates.num2date(s,tz=pytz.timezone('Etc/GMT+8')), mdates.num2date(e,tz=pytz.timezone('Etc/GMT+8'))
print(f'cvtr Random :: start: {newS:%b-%d:: %I:%M %p %Z}, end: {newE:%b-%d:: %I:%M %p %Z}')
产生此输出:
Start Date: 2024-10-31 13:52:01-04:00 TYPE: <class 'pandas._libs.tslibs.timestamps.Timestamp'>
End Date: 2024-11-01 10:51:01-04:00 TYPE: <class 'pandas._libs.tslibs.timestamps.Timestamp'>
RAW :: start: Oct-31:: 01:52 PM UTC-04:00, end: Nov-01:: 10:51 AM UTC-04:00
UTC :: start: Oct-31:: 05:52 PM UTC, end: Nov-01:: 02:51 PM UTC
RAW mdates :: start: 20027.744456018518, end: 20028.618761574075
UTC mdates :: start: 20027.744456018518, end: 20028.618761574075
RAW cvtr :: start: Oct-31:: 05:52 PM EDT, end: Nov-01:: 02:51 PM EDT
UTC cvtr :: start: Oct-31:: 05:52 PM EDT, end: Nov-01:: 02:51 PM EDT
cvtr Random :: start: Oct-31:: 01:52 PM -08, end: Nov-01:: 10:51 AM -08
我期望“RAW cvtr :: ...”行应该与上面的“RAW ::”相同。然而我损失了4个小时。我尝试维护 UTC 输入(以及未显示的特定 np.datetime64 类型),但没有成功。似乎它并不真正关心正确转换为 UTC 或正确使用 tzinfo。
请多指教!
我能够转换单个值,但我不明白为什么 mdates 似乎无法理解如何处理 tzinfo
代码
someTime = dfDeviceStatus['time'][0]
print(f"INIT TIME: {someTime:'%Y-%m-%dT%H:%M:%S%z'}")
utc_dt = someTime.tz_convert('UTC')
print(f"CONVERT TO UTC: {utc_dt:'%Y-%m-%dT%H:%M:%S%z'}")
mplDate = mdates.date2num(utc_dt)
print(f"CONVERT TO mdates num: {mplDate}")
newDT = mdates.num2date(mplDate)
print(f"CONVERT TO mdates date: {newDT:'%Y-%m-%dT%H:%M:%S%z'}")
tzInfo = timedelta(days=-1, seconds=72000)
print(f"TZINFO (from inital known tzinfo): {tzInfo}")
offset = dfDeviceStatus['time'][0].to_pydatetime() - newDT
print(f"offset {offset}")
offDt = newDT + offset + tzInfo
print(f"FINAL DT {offDt:'%Y-%m-%dT%H:%M:%S%z'}")
出
INIT TIME: '2024-10-31T13:52:01-0400'
CONVERT TO UTC: '2024-10-31T17:52:01+0000'
CONVERT TO mdates num: 20027.744456018518
CONVERT TO mdates date: '2024-10-31T21:52:01+0000'
TZINFO (from inital known tzinfo): -1 day, 20:00:00
offset -1 day, 20:00:00
FINAL DT '2024-10-31T13:52:01+0000'
问题似乎与 date2num 和 num2date 如何处理日期时间转换有关。对于那些陷入困境的人(像我一样),我发现提前手动转换似乎是最好的选择。请参阅下面的代码和输出。
代码
someTime = dfDeviceStatus['time'][0]
print(f"INIT TIME: {someTime:'%Y-%m-%dT%H:%M:%S%z'}")
offset = someTime.utcoffset().total_seconds()
convertTime = someTime + timedelta(seconds=offset)
print(f"CONVRT TIME {convertTime}")
mplDate = mdates.date2num(convertTime)
print(f"CONVERT TO mdates num: {mplDate}")
newDT = mdates.num2date(mplDate,tz="US/Eastern")
print(f"CONVERT TO mdates date: {newDT:'%Y-%m-%dT%H:%M:%S%z'}")
输出:
INIT TIME: '2024-10-31T13:52:01-0400'
CONVRT TIME 2024-10-31 09:52:01-04:00
CONVERT TO mdates num: 20027.577789351853
CONVERT TO mdates date: '2024-10-31T13:52:01-0400'
我希望有人可以提供更好的答案,但提前手动转换目前似乎可行