Skip to content

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

Description

@Ryokki

Bug: undocumented Y and YYY tokens fall through to ZZ formatting in format()

Summary

dayjs().format() currently treats Y and YYY as matched tokens, but does not format them as year tokens.

Instead, they fall through to the timezone-offset fallback used for ZZ, producing output such as +0800.

Expected Behavior

The formatting documentation does not mention Y or YYY as supported format() tokens.

Because of that, Y and YYY should not be formatted using timezone-offset logic.

A more reasonable behavior would be to preserve them literally, for example:

dayjs('2024-01-02').format('Y')   // 'Y'
dayjs('2024-01-02').format('YYY')  // 'YYY'

At minimum, they should not behave like ZZ.

Actual Behavior

dayjs('2024-01-02').format('Y')   // return: +0800
dayjs('2024-01-02').format('YYY')// return: +0800

The exact output depends on the local timezone, because these tokens fall through to timezone-offset formatting.

Minimal Reproduction

dayjs('2024-01-02').format('Y')
dayjs('2024-01-02').format('YYY')

Root Cause

  • REGEX_FORMAT matches Y{1,4}
  • format() only implements YY and YYYY
  • unmatched tokens fall through to:
matches(match) || zoneStr.replace(':', '')

That fallback is effectively the implementation used for ZZ, so Y and YYY are formatted as timezone offsets.

Why This Is a Bug

  • Y and YYY are not documented format() tokens
  • users would not expect undocumented year-like tokens to behave like timezone formatting
  • the current output is an internal fallback artifact, not a meaningful formatting result

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions