Skip to content

fix: preserve unsupported year tokens in format (#3015)#3016

Merged
iamkun merged 3 commits intoiamkun:devfrom
Ryokki:fix-format-y-token-fallback
Mar 16, 2026
Merged

fix: preserve unsupported year tokens in format (#3015)#3016
iamkun merged 3 commits intoiamkun:devfrom
Ryokki:fix-format-y-token-fallback

Conversation

@Ryokki
Copy link
Copy Markdown
Contributor

@Ryokki Ryokki commented Mar 12, 2026

Summary

This changes format() so unsupported year tokens are preserved literally instead of falling through to the timezone-offset fallback.

Closes #3015.

Root Cause

REGEX_FORMAT matches Y{1,4}, but format() only implements YY and YYYY.

Previously, unmatched tokens fell through to:

matches(match) || zoneStr.replace(':', '')

That fallback was intended for ZZ, but it also affected unsupported tokens such as Y and YYY, causing them to be formatted as timezone offsets.

Changes

  • handle ZZ explicitly in format()
  • preserve unsupported matched tokens literally
  • add regression coverage in display.test.js for:
    • Y
    • YYY

@iamkun
Copy link
Copy Markdown
Owner

iamkun commented Mar 12, 2026

Perhaps it would be better to update the REGEX_FORMAT regex constant to YYYY|YY to address this issue at the source.
A copy of the current REGEX_FORMAT could be preserved in src/plugin/duration/index.js.
This would fix the problem at its root and keep the implementation simpler and cleaner.
The current test cases could remain as they are.

@Ryokki
Copy link
Copy Markdown
Contributor Author

Ryokki commented Mar 13, 2026

Thanks, I agree that tightening REGEX_FORMAT is the better fix here, since it resolves the mismatch at the source instead of handling it later in format().

I also agree that src/plugin/duration/index.js may need to keep its own copy of the current regex, because its supported year tokens differ from core format().

One point I want to clarify is the expected behavior for YYY once the core regex is narrowed to YYYY|YY.

My current preference is to treat YYY as YY token plus a literal Y, rather than preserving the whole sequence as literal YYY. That seems like the simpler rule: supported tokens are matched normally, and only the unsupported remainder falls back to literal text.

If you agree with that interpretation, I can adjust the implementation and tests in that direction.

@iamkun
Copy link
Copy Markdown
Owner

iamkun commented Mar 13, 2026

Thanks for the clarification. I agree that interpreting YYY as YY + a literal Y makes sense. It keeps the rule simple: supported tokens are parsed normally, and the remaining characters fall back to literal text. That behavior looks reasonable to me.

@Ryokki
Copy link
Copy Markdown
Contributor Author

Ryokki commented Mar 13, 2026

Thanks for confirming. I’ve updated the implementation accordingly.

@iamkun iamkun merged commit 8fda602 into iamkun:dev Mar 16, 2026
1 check passed
@iamkun
Copy link
Copy Markdown
Owner

iamkun commented Mar 16, 2026

THX

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.

Bug: undocumented Y and YYY tokens fall through to ZZ formatting

2 participants