Adjust European short trip heuristic from >3 days to >1 day to correctly detect when user has returned home from European trips. This fixes the April 29-30, 2023 case where the location incorrectly showed "Sankt Georg, Hamburg" instead of "Bristol" when the user was free (no events scheduled) after the foss-north trip ended on April 27. The previous logic required more than 3 days to pass before assuming return home from European countries, but for short European trips by rail/ferry, users typically return within 1-2 days. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
83 lines
2.7 KiB
Python
Executable file
83 lines
2.7 KiB
Python
Executable file
#!/usr/bin/python3
|
|
|
|
from datetime import date, timedelta, timezone
|
|
from time import time
|
|
|
|
import dateutil.tz
|
|
import exchange_calendars # type: ignore
|
|
import pandas # type: ignore
|
|
|
|
from agenda import uk_tz, utils
|
|
|
|
here = dateutil.tz.tzlocal()
|
|
|
|
markets = [("XLON", "London"), ("XNYS", "US")]
|
|
|
|
|
|
def open_and_close() -> list[str]:
|
|
"""Stock markets open and close times."""
|
|
# The trading calendars code is slow, maybe there is a faster way to do this
|
|
# Or we could cache the result
|
|
now = pandas.Timestamp.now(timezone.utc)
|
|
now_local = pandas.Timestamp.now(here)
|
|
reply = []
|
|
for code, label in markets:
|
|
cal = exchange_calendars.get_calendar(code)
|
|
|
|
if cal.is_open_on_minute(now_local):
|
|
next_close = cal.next_close(now).tz_convert(here)
|
|
next_close = next_close.replace(minute=round(next_close.minute, -1))
|
|
delta_close = utils.timedelta_display(next_close - now_local)
|
|
|
|
prev_open = cal.previous_open(now).tz_convert(here)
|
|
prev_open = prev_open.replace(minute=round(prev_open.minute, -1))
|
|
delta_open = utils.timedelta_display(now_local - prev_open)
|
|
|
|
msg = (
|
|
f"{label} market opened {delta_open} ago, "
|
|
+ f"closes in {delta_close} ({next_close:%H:%M})"
|
|
)
|
|
else:
|
|
ts = cal.next_open(now)
|
|
ts = ts.replace(minute=round(ts.minute, -1))
|
|
ts = ts.tz_convert(here)
|
|
delta = utils.timedelta_display(ts - now_local)
|
|
msg = f"{label} market opens in {delta}" + (
|
|
f" ({ts:%H:%M})" if (ts - now_local) < timedelta(days=1) else ""
|
|
)
|
|
|
|
reply.append(msg)
|
|
return reply
|
|
|
|
|
|
# x = open_and_close()
|
|
# print(x)
|
|
|
|
t0 = time()
|
|
|
|
now = pandas.Timestamp.now(timezone.utc)
|
|
now_local = pandas.Timestamp.now(here)
|
|
today = date.today()
|
|
start = today - timedelta(days=1)
|
|
end = today + timedelta(days=30)
|
|
start = date(2024, 12, 20)
|
|
end = date(2025, 1, 5)
|
|
for code, label in markets:
|
|
print(f"{code} {label:6s}")
|
|
cal = exchange_calendars.get_calendar(code, start=start, end=end)
|
|
# print(cal.open_times, cal.close_times, cal.weekmask, cal.regular_holidays)
|
|
for session in cal.sessions:
|
|
o = cal.session_open(session).tz_convert(uk_tz)
|
|
c = cal.session_close(session).tz_convert(uk_tz)
|
|
print(f" {session.date()} {o} {c}")
|
|
continue
|
|
print(cal.sessions, cal.opens, cal.closes)
|
|
continue
|
|
prev_open = cal.previous_open(now).tz_convert(here)
|
|
next_open = cal.next_open(now).tz_convert(here)
|
|
next_close = cal.next_close(now).tz_convert(here)
|
|
print(f"{code} {label:6s} {prev_open} {next_open} {next_close}")
|
|
|
|
print()
|
|
print(f"{time() - t0:.1f} seconds")
|