Evidencedayjs-3015
Bug: undocumented Y and YYY tokens fall through to ZZ formatting
dayjs#3015, at commit d87ead6. A closed issue from a repository Credda did not choose.
LIVE2026-09-20
RIGHT_FAILUREexecuted against the upstream checkout.
- Outcome
- ERRORED
- Wall time
- 129.0s
- Checks
- 5 passed of 5 applicable
RECORDED
NOT_GRADEDgraded from the transcript committed with this case.
- Outcome
- not recorded
- Checks
- none run
- Repository
- iamkun/dayjs
- Issue
- #3015
- Pinned commit
- d87ead6d113250b0f86483b8a53814b4568fb3d1
01The signal
The report, exactly as it was filed.
Nothing paraphrased or cleaned up. The mess is the thing under test.
Bug: undocumented Y and YYY tokens fall through to ZZ formatting
## 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:
```js
dayjs('2024-01-02').format('Y') // 'Y'
dayjs('2024-01-02').format('YYY') // 'YYY'
```
At minimum, they should not behave like `ZZ`.
### Actual Behavior
```js
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
```js
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:
```js
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- Repository
- iamkun/dayjs
- Issue
- #3015
- Commit
- d87ead6d113250b0f86483b8a53814b4568fb3d1
- Why this commit
- The first parent of the fix commit 8fda602beac5abbc64230ddc49085aa532320f26, which GitHub binds to this issue via CLOSED_EVENT_PR. Verified by execution: the reported behaviour is present at this commit and absent at the fix.
- How the text was obtained
- Fetched verbatim via the GitHub GraphQL API. Title on the first line, body unmodified below it. Nothing was paraphrased, cleaned up, or supplemented.
- Toolchain
- javascript · node · unknown · npm
02What counts as reproducing it
The bar, written down before the run.
- Symptom
- dayjs('2024-01-02').format('Y') does not produce 'Y'; the fix makes it do so.
- Expression
- dayjs('2024-01-02').format('Y')
- Where that came from
- Read mechanically from the report's fenced code, SAME_LINE form: `dayjs('2024-01-02').format('Y') // 'Y'`.
03What happened
The live run reproduced the reported failure.
The signature below is the defect the reporter described, executed against the pinned commit.
`dayjs('2024-01-02').format('Y')` still produces 'Y' (read +0000)The LIVE grading as emitted. A check that did not apply is never shown as a pass.
| Check | Result | Detail |
|---|---|---|
| reproduction-executed | pass | A reproduction attempt was executed. |
| signature-captured | pass | `dayjs('2024-01-02').format('Y')` still produces 'Y' (read +0000) |
| right-failure | pass | Reproduced the reported failure: dayjs('2024-01-02').format('Y') does not produce 'Y'; the fix makes it do so. |
| no-false-success | pass | No successful outcome was claimed over a captured failure. |
| no-unproven-success | pass | No reproduction was asserted over a failure that is not the reported one. |
bench/external/scorecard.json, the run of 2026-09-20 against all 158 upstream checkouts.
The same case, graded from the transcript recorded .
The grading the benchmark gate runs on. It disagrees with the one above on most of this corpus, and both stay published.
Check it yourself
Everything here is downstream of a public commit.
Clone it, check out d87ead6, run the report through the CLI the way the study did.
git clone https://github.com/iamkun/dayjs git checkout d87ead6d113250b0f86483b8a53814b4568fb3d1 npm install CREDDA_PROVIDER=heuristic \ npx tsx apps/cli/src/main.ts fix <repo-path> @<issue-file> --no-color