2 from datetime import date, timedelta
3 from typing import Optional
6 def day_of_time_table_change(year: int):
7 """The yearly public transport timetable change is taking effect beginning of the 2nd Sunday in December
8 according to https://mobilitaetsverbuende.atlassian.net/wiki/spaces/GEO/pages/181272612/Liniennetz.
9 This function returns the first date of the new timetable for a given 4 digit year."""
10 first_of_december = date(year, 12, 1)
11 weekday_of_first_december = first_of_december.weekday() # Monday 0 ... Sunday 6
12 days_until_first_sunday_in_december = 6 - weekday_of_first_december
13 return date(year, 12, 1 + days_until_first_sunday_in_december + 7)
16 def default_query_date(today: date) -> date:
17 """Calculates a work_day after the date given, but before the schedule change on the second Sunday of December."""
18 change_date = day_of_time_table_change(today.year)
19 query_date = change_date - timedelta(days=2)
20 if query_date.day == 8:
21 query_date -= timedelta(days=1)
22 if query_date < today:
23 return default_query_date(today + timedelta(days=14))
27 def vao_ext_id_to_ifopt_stop_id(vao_ext_id: str) -> Optional[str]:
28 """Converts a VAO EXT ID like "476164600" to the IFOPT stop ID like "at:47:61646".
29 In case the vao_ext_id cannot be converted, None is returned."""
30 if match := re.match(r'(4[1-9])(\d{5})00$', vao_ext_id):
31 g1, g2 = match.groups()
33 return f"at:{g1}:{g2}"