Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

potentially wrong handling of GTFS Time values #10

Closed
derhuerst opened this issue Jun 3, 2023 · 2 comments
Closed

potentially wrong handling of GTFS Time values #10

derhuerst opened this issue Jun 3, 2023 · 2 comments

Comments

@derhuerst
Copy link

GTFS Time is not defined relative to midnight, but relative to noon - 12h. While that makes "writing" GTFS feeds easier, it makes processing a lot harder.

Expected functionality

As explained in my note about GTFS Time values, with the Europe/Berlin time zone (+1h standard time to +2 DST shift occurs at 2021-03-28T02:00+01:00), I expect

  • the departure_time of 00:30 of a trip running on 2021-03-28 to happen at 1616884200/2021-03-28T00:30+02:00, not at 1616887800/2021-03-28T00:30+01:00;
  • the departure_time of 06:30 of a trip running on 2021-03-28 to happen at 1616905800/2021-03-28T06:30+02:00, not at 1616909400/2021-03-28T06:30+01:00.

Describe the bug

I'm not familiar with this code base, but it seems that timetable_kit is affected by this problem on those days that the DST <-> standard time switch occurs on. I assume that wrong departure times will be generated.

I tried to find some places in the code base:

  • stop_tz = stop_df.iloc[0].stop_timezone
    zonediff = text_presentation.get_zonediff(
    stop_tz, agency_tz, reference_date
    )
    # Get the day change for the reference stop (format is explained in text_presentation)
    departure = text_presentation.explode_timestr(
    timepoint.departure_time, zonediff
    )
    offset = departure.day
    # Finally, get the calendar (must be unique)
    calendar = today_feed.calendar[
    today_feed.calendar.service_id == my_trip.service_id
    ]
    # And fill in the actual string
    daystring = text_presentation.day_string(
    calendar, offset=offset
    )
  • def explode_timestr(timestr: str, zonediff: int = 0) -> TimeTuple:
    """
    Given a GTFS timestr, return a TimeTuple.
    TimeTuple is a namedtuple giving 'day', 'pm', 'hour' (12 hour), 'hour24' ,'min', 'sec'.
    zonediff is the number of hours to adjust to convert to local time before exploding.
    """
    try:
    longhours, mins, secs = [int(x) for x in timestr.split(":")]
    longhours += zonediff # this is the timezone adjustment
    except:
    # Winnipeg-Churchill timetable has NaNs -- don't let it get here!
    raise GTFSError("Timestr didn't parse right", timestr)
    # Return all-zeroes to identify where it happened
    # return TimeTuple(day=0,pm=0,hour=0,hour24=0,min=0,sec=0)
    # Note: the following does the right thing for negative hours
    # (which can be created by the timezone adjustment)
    # It will give -1 days and positive hours24.
    [days, hours24] = divmod(longhours, 24)
    [pm, hours] = divmod(hours24, 12)
    my_time = TimeTuple(day=days, pm=pm, hour=hours, hour24=hours24, min=mins, sec=secs)
    # could do as dict, but seems cleaner this way
    return my_time

related: https://gist.github.com/derhuerst/574edc94981a21ef0ce90713f1cff7f6
related: google/transit#15

@neroden
Copy link
Owner

neroden commented Jun 5, 2023

A few points:

1 - For timetables which cross more than one time zone, the code currently only handles North American time zones anyway. No other time zones can be printed on the output timetable. The code is not currently generalized enough to do any better than that. (It would be good to generalize that.) It should work for timetables in other places which are all within one time zone, though.

2 - The intended purpose is to make "standard" or "reference" timetables for "typical" days.

Weirdness such as what happens when you change from daylight savings to non-daylight savings time in the middle of a day is simply not handled at all. Don't use that day as a reference date for generating the timetable.

In fact, we don't handle the calendar_dates.txt file at ALL, so we won't catch any one-off special timetables of any sort. (I want to handle that at some point, but it's not a priority.)

You shouldn't be generating a timetable for such a day using timetable_kit at this time.

I'm closing this as beyond the specifications of the project -- unless someone has a real reason for producing a printable timetable specifically for the day when you transition in and out of daylight savings time. If you are actually doing that, we can reopen this.

@neroden neroden closed this as not planned Won't fix, can't repro, duplicate, stale Jun 5, 2023
@derhuerst
Copy link
Author

Don't use that day as a reference date for generating the timetable.

Fair enough! 🙂

I think this should be documented as a limitation in the readme, given that, as a person that doesn't know (or think about) the intricacies of DST & bus schedules, it will lead to unexpected outcomes.

Weirdness such as what happens when you change from daylight savings to non-daylight savings time in the middle of a day is simply not handled at all.

Note that this is not (just) about a shift in the middle of the day, but all cases whenever any trip runs across a DST shift.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants