Skip to content

GTFS Static > agency timezone > fix infrequent issue - #195

Open
mmathieum wants to merge 12 commits into
masterfrom
mm/gtfs_static_fix_timezone_issue
Open

GTFS Static > agency timezone > fix infrequent issue#195
mmathieum wants to merge 12 commits into
masterfrom
mm/gtfs_static_fix_timezone_issue

Conversation

@mmathieum

@mmathieum mmathieum commented Aug 8, 2026

Copy link
Copy Markdown
Member

Happened today in Prod, Android Studio Gemini thinks it might come from static date format instances containing old timezone.
Human Android developer is not convinced... 🤔

Some cached data (schedule status) could be saved with wrong timezone...

Happened today in Prod, AI think it might come from static date format instances containing old timezone.
@mmathieum mmathieum self-assigned this Aug 8, 2026
@mmathieum
mmathieum marked this pull request as ready for review August 8, 2026 21:43
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix GTFS static schedule timezone drift by using per-request DateFormats

🐞 Bug fix ✨ Enhancement 🕐 20-40 Minutes

Grey Divider

AI Description

• Stop caching timezone-derived formatters to prevent stale agency timezone usage.
• Create timezone-scoped DateFormats per request and pass them through schedule parsing.
• Log and fallback to device timezone when agency timezone is missing.
Diagram

graph TD
  F["AgencyUtils"] --> G["Agency timezone id"] --> A["GTFSScheduleTimestampsProvider"] --> B["GTFSStatusProvider"] --> C["DateFormat (per request)"] --> D["findScheduleList()"] --> E[("GTFS schedule files")]
  G --> B
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Keep ThreadSafeDateFormatter but invalidate on timezone changes
  • ➕ Avoids repeated formatter allocations
  • ➕ Smaller API churn (fewer signature changes)
  • ➖ Requires robust timezone-change detection and cache invalidation logic
  • ➖ Higher risk of missing edge cases (DST shifts, device tz updates, multi-agency usage)
2. Migrate to java.time (DateTimeFormatter + ZonedDateTime)
  • ➕ Immutable/thread-safe formatters by design
  • ➕ Clearer timezone semantics and fewer mutable state pitfalls
  • ➖ Larger refactor footprint; may require desugaring and broader code updates
  • ➖ More changes to validate across Android API levels
3. ThreadLocal keyed by timezone
  • ➕ Reduces allocation while keeping timezone-specific instances
  • ➕ Avoids global mutable singleton shared across threads
  • ➖ More complex lifecycle/memory behavior
  • ➖ Still relies on mutable SimpleDateFormat instances

Recommendation: The PR’s approach (create timezone-scoped SimpleDateFormat instances per request and pass them into parsing) is the safest immediate fix for a production-only, infrequent timezone drift: it removes shared mutable formatter state and makes the timezone an explicit input throughout the call chain. Consider a longer-term migration to java.time for clearer, immutable timezone handling if this area continues to grow.

Files changed (3) +83 / -73

Bug fix (3) +83 / -73
AgencyUtils.ktLoggable AgencyUtils + safer timezone fallback +11/-5

Loggable AgencyUtils + safer timezone fallback

• Makes AgencyUtils implement MTLog.Loggable and adds a log tag. Removes the lazily-cached default timezone id and instead falls back to the current device timezone at call time, logging a warning when agency timezone cannot be read.

src/main/java/org/mtransit/android/commons/provider/agency/AgencyUtils.kt

GTFSScheduleTimestampsProvider.javaUse per-request DateFormats with explicit agency timezone +15/-9

Use per-request DateFormats with explicit agency timezone

• Stops using cached ThreadSafeDateFormatter instances and instead builds new DateFormat instances from the agency timezone for each request. Passes the timezone id and a date+time formatter down to schedule list lookups, and switches formatting calls to DateFormat.format(Date).

src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSScheduleTimestampsProvider.java

GTFSStatusProvider.javaReplace cached ThreadSafeDateFormatter with new SimpleDateFormat factories +57/-59

Replace cached ThreadSafeDateFormatter with new SimpleDateFormat factories

• Removes static cached ThreadSafeDateFormatter fields and introduces factory methods that create SimpleDateFormat instances configured with the provided TimeZone. Updates status lookups and schedule/frequency parsing to pass a date+time formatter and the agency timezone id through to timestamp conversion and Schedule.Timestamp creation, preventing stale timezone reuse.

src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSStatusProvider.java

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Summary by CodeRabbit

  • Bug Fixes

    • Improved schedule, trip update, and service-status timestamp accuracy across agency time zones.
    • Schedules now retain their local time zone for more reliable display, parsing, and persistence.
    • Improved fallback behavior by using the device time zone and recording a warning when agency data is unavailable.
    • Preserved existing filtering, fallback lookups, and error handling.
  • Refactor

    • Standardized date and time processing for schedules and frequency-based services.
    • Unified time-zone handling across real-time and schedule data providers.

Walkthrough

Changes

Agency timezone flow

Layer / File(s) Summary
Schedule timezone contract
src/main/java/org/mtransit/android/commons/data/Schedule.java, src/main/java/org/mtransit/android/commons/data/ScheduleExt.kt, src/main/java/org/mtransit/android/commons/data/ScheduleTimestamps.java
Schedule, Timestamp, and ScheduleTimestamps now store timezone identifiers. JSON serialization and parsing persist these values. Missing timestamp timezones use the device timezone with debug validation and release fallback.
Timezone resolution and schedule construction
src/main/java/org/mtransit/android/commons/provider/agency/AgencyUtils.kt, src/main/java/org/mtransit/android/commons/provider/*
AgencyUtils resolves the agency timezone and logs fallback behavior. Providers pass local timezone identifiers into schedules and timestamps.
GTFS timestamp formatting
src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSScheduleTimestampsProvider.java, src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSStatusProvider.java
GTFS schedule and frequency lookups create timezone-specific formatters. Normal and weekly fallback parsing uses supplied combined date-time formatters.
Realtime timezone source cleanup
src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSRealTimeProviderExt.kt, src/main/java/org/mtransit/android/commons/provider/status/GTFSRealTimeTripUpdatesProvider.kt, src/main/res/values/gtfs_real_time_values.xml
Provider-level timezone properties and the default realtime timezone resource were removed. Realtime processing now uses AgencyUtils.getAgencyTimeZoneId(context).

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Provider
  participant AgencyUtils
  participant GTFSStatusProvider
  participant Schedule
  Provider->>AgencyUtils: Resolve agency timezone
  Provider->>GTFSStatusProvider: Create timezone-specific formatters
  GTFSStatusProvider->>GTFSStatusProvider: Parse schedule or frequency timestamps
  GTFSStatusProvider->>Schedule: Create timestamps with timezone
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.55% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies a GTFS Static agency timezone fix, which matches the primary change.
Description check ✅ Passed The description explains the production issue, possible stale timezone data, and the affected cached schedule status.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch mm/gtfs_static_fix_timezone_issue

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@qodo-code-review

qodo-code-review Bot commented Aug 8, 2026

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Formatter allocations hot path 🐞 Bug ➹ Performance
Description
GTFSStatusProvider (and GTFSScheduleTimestampsProvider) now allocate multiple SimpleDateFormat
instances per status/schedule computation. Under frequent refreshes, these extra allocations can
increase GC pressure and degrade latency compared to the previous cached formatter approach.
Code

src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSStatusProvider.java[R238-240]

+		final DateFormat dateFormat = getNewDateFormat(timeZone);
+		final DateFormat timeFormat = getNewTimeFormat(timeZone);
+		final DateFormat dateAndTimeFormat = getNewDateAndTimeFormat(timeZone);
Relevance

●● Moderate

Team accepts perf/allocation optimizations, but caching formatters risks reintroducing
timezone/staleness issues targeted by this PR.

PR-#168
PR-#41

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The updated code constructs new SimpleDateFormat instances (getNewDateFormat,
getNewTimeFormat, getNewDateAndTimeFormat) for each status/schedule computation, and these
methods are reached from the main provider entrypoints. This is a behavioral change from the prior
static cached formatter fields, so allocation rate increases are directly introduced by this PR.

src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSStatusProvider.java[170-186]
src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSStatusProvider.java[225-241]
src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSStatusProvider.java[593-605]
src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSScheduleTimestampsProvider.java[44-56]
src/main/java/org/mtransit/android/commons/provider/GTFSProvider.java[308-318]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
The PR replaces static cached `ThreadSafeDateFormatter` instances with per-call `SimpleDateFormat` allocations (date/time/date+time) in multiple provider methods. This avoids stale timezone issues, but it can regress performance on frequently executed status/schedule code paths.

### Issue Context
The main requirement is: don’t keep an outdated timezone when the device timezone changes. We can still reduce allocations by reusing formatter instances while *resetting the timezone each use* and ensuring no cross-thread sharing.

### Fix Focus Areas
- src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSStatusProvider.java[236-241]
- src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSStatusProvider.java[600-605]
- src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSScheduleTimestampsProvider.java[49-55]

### Suggested fix
Use a `ThreadLocal` (or other per-thread cache) holding `SimpleDateFormat` instances for each pattern, and call `setTimeZone(timeZone)` on every use before formatting/parsing. This preserves the timezone-change fix while cutting repeated allocations. Alternatively, cache by `(thread, timeZoneId)` if you want to avoid repeated `setTimeZone` calls.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

2. Timezone warning log spam 🐞 Bug ◔ Observability
Description
AgencyUtils.getAgencyTimeZoneId() now logs a WARN every time the agency timezone string is blank,
but the library’s default poi_agency_timezone resource is intentionally empty. If a module/app
forgets to override the string, each status/schedule computation will emit a WARN and can flood logs
and add avoidable overhead.
Code

src/main/java/org/mtransit/android/commons/provider/agency/AgencyUtils.kt[R46-49]

+        ) ?: run {
+            MTLog.w(LOG_TAG, "Impossible to read agency timezone! (using device timezone)")
+            TimeZone.getDefault().id
+        }
Relevance

● Weak

Team previously rejected reducing WARN noise/downgrading spammy WARN logs; likely keep WARN for
misconfig.

PR-#192
PR-#178

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The fallback branch always logs a warning, and the base resource intentionally leaves
poi_agency_timezone empty, which causes getAgencyString(...).firstOrNull { it.isNotBlank() } to
return null and hit the warning path. This method is called during GTFS status calculations, so it
can repeat frequently when not configured.

src/main/java/org/mtransit/android/commons/provider/agency/AgencyUtils.kt[35-49]
src/main/res/values/poi_agency_values.xml[3-8]
src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSStatusProvider.java[225-241]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

### Issue description
`AgencyUtils.getAgencyTimeZoneId()` logs `MTLog.w(...)` on every fallback to device timezone. Because the base commons resource defines `poi_agency_timezone` as empty by default, this can result in repeated warnings when the module/app hasn’t generated/overridden the value.

### Issue Context
The fallback is valid, but the current log level and frequency can create noisy logs and overhead in code paths that run often (GTFS status/schedule queries).

### Fix Focus Areas
- src/main/java/org/mtransit/android/commons/provider/agency/AgencyUtils.kt[40-49]

### Suggested fix
Implement a “log once” guard (e.g., `private var warnedMissingTimeZone = false`) and only warn the first time fallback happens, or downgrade to `MTLog.i`/`MTLog.v` in production. Keep returning `TimeZone.getDefault().id` as you do now.

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can reply 'qodo' on any finding to push back, ask questions, or dig deeper

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR addresses an infrequent production issue where GTFS static schedule parsing/formatting could use an outdated agency timezone due to cached date formatter instances, potentially leading to cached schedule status being saved with the wrong timezone.

Changes:

  • Replace cached ThreadSafeDateFormatter instances with newly created SimpleDateFormat/DateFormat instances configured per agency timezone.
  • Thread agency timezone ID and a preconfigured date+time formatter down into schedule parsing to avoid re-reading timezone configuration mid-flow.
  • Improve agency timezone fallback behavior by logging a warning when the agency timezone resource cannot be read and falling back to the device timezone.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.

File Description
src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSStatusProvider.java Stops caching timezone-bound formatters; creates new timezone-scoped DateFormats per request and threads them into schedule parsing.
src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSScheduleTimestampsProvider.java Aligns schedule timestamp retrieval with the new per-timezone DateFormat approach.
src/main/java/org/mtransit/android/commons/provider/agency/AgencyUtils.kt Adds logging and explicit fallback to device timezone when no agency timezone is configured/readable.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread src/main/java/org/mtransit/android/commons/provider/agency/AgencyUtils.kt Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/main/java/org/mtransit/android/commons/data/Schedule.java (1)

76-101: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Restore the previous public constructor overloads.

Line 87 changes the public constructor signature by inserting localTimeZoneId before sourceLabel. Existing source callers will not compile. Existing binary callers can fail with NoSuchMethodError.

Keep overloads with the previous signatures. Delegate them with localTimeZoneId set to null.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/org/mtransit/android/commons/data/Schedule.java` around lines
76 - 101, Restore the previous public Schedule constructor overloads so callers
using the original parameter order remain source- and binary-compatible. Add
overloads matching the former signatures and delegate to the current constructor
with localTimeZoneId set to null, while preserving the existing overloads that
accept localTimeZoneId.
src/main/java/org/mtransit/android/commons/data/ScheduleExt.kt (1)

24-34: 🗄️ Data Integrity & Integration | 🟠 Major | 🏗️ Heavy lift

Keep timezone metadata when creating derived schedules.

The derived-schedule factory does not carry localTimeZoneId. GTFS realtime no-data schedules therefore lose their agency timezone and persist without "tz".

  • src/main/java/org/mtransit/android/commons/data/ScheduleExt.kt#L24-L34: add timezone support to RouteDirectionStop.makeSchedule() and preserve Schedule.localTimeZoneId in Schedule.toNoData().
  • src/main/java/org/mtransit/android/commons/provider/status/GTFSRealTimeTripUpdatesProvider.kt#L210-L214: pass agencyTimeZoneId when creating the no-data schedule.
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/org/mtransit/android/commons/data/ScheduleExt.kt` around lines
24 - 34, The derived-schedule factories must preserve timezone metadata: in
src/main/java/org/mtransit/android/commons/data/ScheduleExt.kt#L24-L34, extend
RouteDirectionStop.makeSchedule() to accept and pass localTimeZoneId, and ensure
Schedule.toNoData() reuses Schedule.localTimeZoneId; in
src/main/java/org/mtransit/android/commons/provider/status/GTFSRealTimeTripUpdatesProvider.kt#L210-L214,
pass agencyTimeZoneId when creating the no-data schedule.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/org/mtransit/android/commons/data/Schedule.java`:
- Around line 113-116: Update Schedule.getTimeZone() to return localTimeZoneId
when no timestamp is available and the timestamp-derived timezone would
otherwise be null, while preserving the existing timestamp-based timezone
behavior when present.

In
`@src/main/java/org/mtransit/android/commons/provider/GTFSRealTimeProvider.java`:
- Around line 1233-1234: Update the lookup flow around the static timeParser so
its timezone is refreshed on every lookup using the current
AgencyUtils.getAgencyTimeZoneId(context) result before parsing. Do not limit
setTimeZone to first-time initialization, ensuring later device timezone changes
are reflected.

---

Outside diff comments:
In `@src/main/java/org/mtransit/android/commons/data/Schedule.java`:
- Around line 76-101: Restore the previous public Schedule constructor overloads
so callers using the original parameter order remain source- and
binary-compatible. Add overloads matching the former signatures and delegate to
the current constructor with localTimeZoneId set to null, while preserving the
existing overloads that accept localTimeZoneId.

In `@src/main/java/org/mtransit/android/commons/data/ScheduleExt.kt`:
- Around line 24-34: The derived-schedule factories must preserve timezone
metadata: in
src/main/java/org/mtransit/android/commons/data/ScheduleExt.kt#L24-L34, extend
RouteDirectionStop.makeSchedule() to accept and pass localTimeZoneId, and ensure
Schedule.toNoData() reuses Schedule.localTimeZoneId; in
src/main/java/org/mtransit/android/commons/provider/status/GTFSRealTimeTripUpdatesProvider.kt#L210-L214,
pass agencyTimeZoneId when creating the no-data schedule.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 4e6ff30e-9376-4eaf-9ff1-6887d4f25641

📥 Commits

Reviewing files that changed from the base of the PR and between 259dabf and 7660b70.

📒 Files selected for processing (16)
  • src/main/java/org/mtransit/android/commons/data/Schedule.java
  • src/main/java/org/mtransit/android/commons/data/ScheduleExt.kt
  • src/main/java/org/mtransit/android/commons/provider/CleverDevicesProvider.java
  • src/main/java/org/mtransit/android/commons/provider/GTFSRealTimeProvider.java
  • src/main/java/org/mtransit/android/commons/provider/NextBusProvider.java
  • src/main/java/org/mtransit/android/commons/provider/OneBusAwayProvider.java
  • src/main/java/org/mtransit/android/commons/provider/RTCQuebecProvider.java
  • src/main/java/org/mtransit/android/commons/provider/ReginaTransitProvider.java
  • src/main/java/org/mtransit/android/commons/provider/StmInfoApiProvider.java
  • src/main/java/org/mtransit/android/commons/provider/WinnipegTransitProvider.java
  • src/main/java/org/mtransit/android/commons/provider/agency/AgencyUtils.kt
  • src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSRealTimeProviderExt.kt
  • src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSScheduleTimestampsProvider.java
  • src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSStatusProvider.java
  • src/main/java/org/mtransit/android/commons/provider/status/GTFSRealTimeTripUpdatesProvider.kt
  • src/main/res/values/gtfs_real_time_values.xml
💤 Files with no reviewable changes (2)
  • src/main/res/values/gtfs_real_time_values.xml
  • src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSRealTimeProviderExt.kt
🚧 Files skipped from review as they are similar to previous changes (2)
  • src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSScheduleTimestampsProvider.java
  • src/main/java/org/mtransit/android/commons/provider/gtfs/GTFSStatusProvider.java

Comment thread src/main/java/org/mtransit/android/commons/data/Schedule.java

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 17 out of 17 changed files in this pull request and generated no new comments.

Suppressed comments (3)

src/main/java/org/mtransit/android/commons/provider/GTFSRealTimeProvider.java:1234

  • timeParser is a static cached formatter, but its timezone is initialized from the first Context that hits getTimeParser(). If multiple agencies/providers with different timezones can be used in the same process, this can cause parsing with the wrong timezone. Making the parser instance-scoped avoids cross-provider contamination while preserving caching per provider instance.
				timeParser = new ThreadSafeDateFormatter(formatter, Locale.ENGLISH);
				final String agencyTimeZoneId = AgencyUtils.getAgencyTimeZoneId(context);
				timeParser.setTimeZone(TimeZone.getTimeZone(agencyTimeZoneId));

src/main/java/org/mtransit/android/commons/provider/agency/AgencyUtils.kt:51

  • getAgencyTimeZoneId() now throws a RuntimeException in DEBUG builds when no agency timezone is configured. This can crash dev/debug builds for apps/tests that relied on the previous fallback behavior (or when upgrading with older modules/resources). Consider keeping a warning but always falling back to the device timezone, even in DEBUG, to avoid hard crashes.
        ) ?: run {
            if (BuildConfig.DEBUG) {
                throw RuntimeException("No agency timezone configured!")
            }
            MTLog.w(LOG_TAG, "No agency timezone configured (using device timezone)!")

src/main/java/org/mtransit/android/commons/data/Schedule.java:838

  • Schedule.Timestamp.parseJSON() throws in DEBUG when the cached JSON is missing localTimeZone. Since older cached data may legitimately lack this field, this can cause crashes after upgrading while debugging. It would be safer to log and fall back to the device timezone in all build types.
				if (TextUtils.isEmpty(localTimeZoneId)) {
					if (BuildConfig.DEBUG) {
						throw new RuntimeException("Timestamp missing timezone in JSON!");
					}
					MTLog.w(LOG_TAG, "Timestamp missing timezone in JSON (using device TZ) '%s'!", jTimestamp);

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

Successfully merging this pull request may close these issues.

2 participants