Skip to content

fix: preserve an explicit year zero in TimestampFlag - #2458

Merged
Juneezee merged 2 commits into
urfave:mainfrom
ac1982:fix/timestamp-explicit-year-zero
Oct 8, 2026
Merged

Juneezee merged 2 commits into
urfave:mainfrom
ac1982:fix/timestamp-explicit-year-zero

Conversation

@ac1982

@ac1982 ac1982 commented Oct 7, 2026

Copy link
Copy Markdown
Contributor

What type of PR is this?

  • bug

What this PR does / why we need it:

TimestampFlag replaces a parsed year of zero with the current year even when the layout and input explicitly contain 0000. For example, --time 0000-02-29T12:34:56Z with time.RFC3339 becomes March 1 of the current non-leap year instead of preserving the supplied timestamp.

Distinguish an omitted year from an explicit zero year by probing the matched layout, just as the existing date-presence helper does. Preserve yearless/time-only defaulting. Add CLI-level regressions for RFC3339, a full date, and a year-plus-time layout.

Which issue(s) this PR fixes:

No existing issue found. Searched timestamp/year issues and open/closed PRs, including #2427 and #2450; those address layouts without a year rather than an explicitly supplied year zero.

Testing

  • All three new cases fail before the fix.
  • go test ./... passed, including the existing yearless and time-only timezone cases.
  • go vet ./... passed.
  • make v3diff passed (no public API change).
  • Files formatted with gofmt. Full make all / gfmrun documentation checks were not run.

Release Notes

TimestampFlag preserves an explicitly supplied year 0000 instead of replacing it with the current year.

@ac1982
ac1982 requested a review from a team as a code owner October 7, 2026 12:06
@greptile-apps

greptile-apps Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

RetriggerConfidence Score: 5/5

[Medium risk] Fixes timestamp parsing to preserve explicit year zero.

The PR appears safe to merge.

Summary

The PR preserves an explicitly parsed year zero in TimestampFlag while retaining defaulting for layouts that omit the year. It adds CLI-level regression tests for three year-bearing layouts.

Reviews (1) · Last reviewed commit: "fix: preserve explicit year zero in time..." · Reviewed by Greptile

@Juneezee Juneezee left a comment •

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, the fix looks correct. The three new cases fail on main and pass here, and yearless layouts such as "01-02" and "15:04" still default to the current year/date.

I pushed 029b760, which merges layoutHasDate and layoutHasYear into one probe, since both round-tripped the same reference time with different reference years (2 and 2001):

cli/flag_timestamp.go

Lines 130 to 139 in 029b760

// layoutFields reports whether layout carries a year and month/day components,
// probed by round-tripping a reference date that is not January 1 of year 0.
func layoutFields(layout string) (hasYear, hasDate bool) {
ref := time.Date(2, time.March, 4, 5, 6, 7, 0, time.UTC)
if p, err := time.Parse(layout, ref.Format(layout)); err == nil {
hasYear = p.Year() != 0
hasDate = p.Month() != time.January || p.Day() != 1
}
return hasYear, hasDate
}

An omitted year always parses as year 0, and "06" never parses as 0 (00 is 2000), so p.Year() != 0 is enough to tell whether the layout carries a year.

layoutHasDate and layoutHasYear round-tripped the same reference time
through the layout, only with different reference years (2 and 2001).

An omitted year always parses as year 0, and a two-digit "06" year never
parses as 0, so one probe can report both whether the layout carries a
year and whether it carries a month/day. Replace both helpers with
layoutFields.

Reference: 37ad84c ("fix: preserve explicit year zero in timestamp flags")
Reference: e8c2eb5 ("Fix a year-less timestamp layout losing January 1")
Assisted-by: claude:claude-opus-5-5
Signed-off-by: Eng Zer Jun <engzerjun@gmail.com>
@Juneezee
Juneezee force-pushed the fix/timestamp-explicit-year-zero branch from d83a84d to 029b760 Compare October 8, 2026 15:16
@Juneezee
Juneezee merged commit 6f2d8e9 into urfave:main Oct 8, 2026
7 checks passed
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