Skip to content

feat: support yyyy-MM-dd_HH-mm-ss format for time parameter#1071

Open
3rabiii wants to merge 1 commit into
OneBusAway:mainfrom
3rabiii:fix-trip-details_issue_4
Open

feat: support yyyy-MM-dd_HH-mm-ss format for time parameter#1071
3rabiii wants to merge 1 commit into
OneBusAway:mainfrom
3rabiii:fix-trip-details_issue_4

Conversation

@3rabiii

@3rabiii 3rabiii commented Jun 14, 2026

Copy link
Copy Markdown
Collaborator

Description

This PR addresses by updating the shared parseTripParams function to accept the time query parameter as a calendar datetime string (yyyy-MM-dd_HH-mm-ss), as specified in the wiki.

Changes Included:

  • Dual-Format Parsing: The time parameter now natively accepts both Unix millisecond timestamps (preserving backwards compatibility) and human-readable datetime strings.
  • Timezone Localization: Datetime strings are parsed using time.ParseInLocation with the agency's configured timezone. This ensures that a time requested as "14:30:00" is accurately evaluated in the agency's local time, not UTC.
  • Validation Messaging: Updated the fieldErrors map to return a precise error message when an invalid format is provided.
  • Test Coverage:
    • Added a unit test to verify exact extraction of year, month, day, hour, minute, and second.
    • Added an integration test (TestTripDetailsHandlerWithTimeParameterString) to verify the endpoint successfully returns HTTP 200 when using the new parameter format.

Fixes: #1055

Summary by CodeRabbit

  • New Features
    • The time parameter now accepts datetime strings in yyyy-MM-dd_HH-mm-ss format in addition to Unix timestamps in milliseconds.

@coderabbitai

coderabbitai Bot commented Jun 14, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

parseTripParams in the trip-details handler is extended to accept the time query parameter as either a Unix millisecond timestamp or a yyyy-MM-dd_HH-mm-ss datetime string. The datetime string is parsed using the provided timezone location, defaulting to UTC. Validation error messaging and tests are updated accordingly.

Changes

trip-details time parameter datetime string support

Layer / File(s) Summary
parseTripParams datetime fallback and tests
internal/restapi/trip_details_handler.go, internal/restapi/trip_details_handler_test.go
On Unix-millis parse failure, parseTripParams attempts to parse time as yyyy-MM-dd_HH-mm-ss with the provided location (UTC default) and updates the validation error message to describe both formats. Unit test error expectation is updated, a new subcase verifies correct field extraction from the datetime format, and a new handler-level test asserts HTTP 200 with a non-empty TripID when time=2025-07-20_14-30-00 is supplied.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related issues

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% 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
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding support for yyyy-MM-dd_HH-mm-ss format for the time parameter.
Linked Issues check ✅ Passed The pull request fully implements the requirements from issue #1055: both Unix millisecond timestamps and datetime strings in yyyy-MM-dd_HH-mm-ss format are now supported with proper timezone-aware parsing.
Out of Scope Changes check ✅ Passed All changes are directly related to implementing datetime format support for the time parameter as specified in issue #1055; no out-of-scope modifications detected.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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 and usage tips.

@sonarqubecloud

Copy link
Copy Markdown

@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: 1

🧹 Nitpick comments (1)
internal/restapi/trip_details_handler_test.go (1)

273-286: ⚡ Quick win

Add one non-UTC location test to cover the new agency-timezone parsing branch.

Line 276 calls parseTripParams(req, true) without loc, so this only validates UTC fallback. Add a case passing a concrete location (for example America/Los_Angeles) and assert the parsed instant matches that local wall-clock input.

Suggested test addition
 t.Run("time yyyy-MM-dd_HH-mm-ss format", func(t *testing.T) {
   req := httptest.NewRequest("GET", "/?time=2024-06-15_14-30-00", nil)

   params, errs := api.parseTripParams(req, true)

   assert.Nil(t, errs)
   require.NotNil(t, params.Time)
   assert.Equal(t, 2024, params.Time.Year())
   assert.Equal(t, time.June, params.Time.Month())
   assert.Equal(t, 15, params.Time.Day())
   assert.Equal(t, 14, params.Time.Hour())
   assert.Equal(t, 30, params.Time.Minute())
   assert.Equal(t, 0, params.Time.Second())
 })
+
+t.Run("time yyyy-MM-dd_HH-mm-ss format with explicit location", func(t *testing.T) {
+  req := httptest.NewRequest("GET", "/?time=2024-06-15_14-30-00", nil)
+  loc, err := time.LoadLocation("America/Los_Angeles")
+  require.NoError(t, err)
+
+  params, errs := api.parseTripParams(req, true, loc)
+
+  assert.Nil(t, errs)
+  require.NotNil(t, params.Time)
+  assert.Equal(t, loc, params.Time.Location())
+  assert.Equal(t, 14, params.Time.Hour())
+})
🤖 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 `@internal/restapi/trip_details_handler_test.go` around lines 273 - 286, The
current test case for the time yyyy-MM-dd_HH-mm-ss format only validates UTC
fallback behavior by calling parseTripParams without a location parameter. Add a
new test case that passes a concrete non-UTC location (such as
America/Los_Angeles) to parseTripParams and verifies that the parsed time
correctly reflects the local wall-clock values for that timezone. This will
provide test coverage for the agency-timezone parsing branch that the current
UTC-only test does not exercise.
🤖 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 `@internal/restapi/trip_details_handler.go`:
- Around line 72-87: The trip-details endpoint handler accepts both Unix
millisecond timestamps via strconv.ParseInt and datetime strings via
time.ParseInLocation, but the OpenAPI specification only documents the integer
format. Choose one approach: either remove the datetime string parsing logic
(the time.ParseInLocation call and associated error handling in the fieldErrors
validation) to restrict the implementation to integer-only, or update the
OpenAPI specification to document both the integer and string format support for
the time parameter. Ensure the implementation and OpenAPI spec remain
synchronized to prevent SDK generation and API conformance tool failures.

---

Nitpick comments:
In `@internal/restapi/trip_details_handler_test.go`:
- Around line 273-286: The current test case for the time yyyy-MM-dd_HH-mm-ss
format only validates UTC fallback behavior by calling parseTripParams without a
location parameter. Add a new test case that passes a concrete non-UTC location
(such as America/Los_Angeles) to parseTripParams and verifies that the parsed
time correctly reflects the local wall-clock values for that timezone. This will
provide test coverage for the agency-timezone parsing branch that the current
UTC-only test does not exercise.
🪄 Autofix (Beta)

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: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e4ff93a2-6ade-4d40-8742-8afab5a2052c

📥 Commits

Reviewing files that changed from the base of the PR and between 9898b8f and b2a666c.

📒 Files selected for processing (2)
  • internal/restapi/trip_details_handler.go
  • internal/restapi/trip_details_handler_test.go

Comment on lines +72 to +87
// Validate time — accepts either a Unix timestamp in milliseconds
// (e.g. "1718459400000") or a datetime in yyyy-MM-dd_HH-mm-ss format (e.g. "2024-06-15_14-30-00").
if timeStr := r.URL.Query().Get("time"); timeStr != "" {
if timeMs, err := strconv.ParseInt(timeStr, 10, 64); err == nil {
timeParam := time.Unix(timeMs/1000, 0)
params.Time = &timeParam
} else {
fieldErrors["time"] = []string{"must be a valid Unix timestamp in milliseconds"}
timeLoc := time.UTC
if len(loc) > 0 && loc[0] != nil {
timeLoc = loc[0]
}
if timeParam, err := time.ParseInLocation("2006-01-02_15-04-05", timeStr, timeLoc); err == nil {
params.Time = &timeParam
} else {
fieldErrors["time"] = []string{"must be a valid Unix timestamp in milliseconds or a datetime in yyyy-MM-dd_HH-mm-ss format"}
}

@coderabbitai coderabbitai Bot Jun 14, 2026

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verify local OpenAPI contract shape for trip-details "time" query parameter.
# Read-only reconnaissance script.

set -euo pipefail

echo "== Locate OpenAPI files =="
fd -i 'openapi*.yml'
fd -i 'openapi*.yaml'

echo
echo "== Inspect trip-details time parameter in testdata/openapi.yml (if present) =="
if [ -f testdata/openapi.yml ]; then
  rg -n -C4 'trip-details|name:\s*time|format:\s*int64|type:\s*integer' testdata/openapi.yml
else
  echo "testdata/openapi.yml not found"
fi

echo
echo "== Inspect conformance tests referencing trip-details time param expectations =="
rg -n -C3 'trip-details|time.*parameter|int64|yyyy-MM-dd_HH-mm-ss' --type=go

Repository: OneBusAway/maglev

Length of output: 50374


API contract mismatch: time parameter accepts string format not documented in OpenAPI spec.

The trip-details endpoint code (lines 72–87) accepts both Unix millisecond timestamps and yyyy-MM-dd_HH-mm-ss datetime strings, but the OpenAPI specification (testdata/openapi.yml, lines 752–757) defines time as type: integer, format: int64 only. This contract drift may cause SDK generation tools and API conformance checks to fail. Either restrict the implementation to integer-only or update the OpenAPI spec to document the string format support.

🤖 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 `@internal/restapi/trip_details_handler.go` around lines 72 - 87, The
trip-details endpoint handler accepts both Unix millisecond timestamps via
strconv.ParseInt and datetime strings via time.ParseInLocation, but the OpenAPI
specification only documents the integer format. Choose one approach: either
remove the datetime string parsing logic (the time.ParseInLocation call and
associated error handling in the fieldErrors validation) to restrict the
implementation to integer-only, or update the OpenAPI specification to document
both the integer and string format support for the time parameter. Ensure the
implementation and OpenAPI spec remain synchronized to prevent SDK generation
and API conformance tool failures.

Source: Coding guidelines

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

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

Cool, but the correct workflow is to update the openapi.yml in the sdk repo first, so i will open an issue there to fix this

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

@3rabiii, that makes sense — the SDK repo (OneBusAway/sdk-config) being the source of truth for the OpenAPI contract is the right approach. Updating the spec there first (or at least tracking it as a follow-up issue) keeps the contract and implementation in sync in the intended direction.

Would you like me to open a tracking issue in OneBusAway/sdk-config on your behalf? I can reference this PR as context and note that the time parameter for the trip-details endpoint should be updated from type: integer, format: int64 to also document the yyyy-MM-dd_HH-mm-ss string format.


🧠 Learnings used
Learnt from: ARCoder181105
Repo: OneBusAway/maglev PR: 787
File: internal/restapi/arrivals_and_departures_for_location.go:686-694
Timestamp: 2026-04-26T10:27:18.975Z
Learning: In OneBusAway/maglev `internal/restapi` Go handlers, it is acceptable (and intentional) to access `sql.NullString.String` and `sql.NullInt64.Int64` directly without checking `.Valid`. Treat Go zero values (`""` and `0`) as the correct wire-format defaults, matching the Java OBA output. Do not require `.Valid` guards for these fields in this layer; this should only be changed if the wire-format semantics are confirmed to differ.

@3rabiii 3rabiii requested a review from burma-shave June 14, 2026 22:31
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.

trip-details: time parameter should accept yyyy-MM-dd_HH-mm-ss format

1 participant