[migration/ilib-js-to-dart] feat(date): add julianday/rd options to ILibDateOptions and fix DateFmt calendar/timezone conversion - #95
Merged
gouniLee merged 10 commits intoJul 31, 2026
Conversation
…LibDateFmt - Add julianday, rd fields to ILibDateOptions; _toCalendarDate() separates absolute-instant and component paths cleanly - Derive calendar from locale when type/calendar is omitted - Expose toCalendarDate() for locale-specific year/month/day access - Fix _convertToFormatterCalendar: timezone mismatch triggers re-creation for ILibCalendarDate; timezone propagated through _createCalendarDate - Fix local DateTime regression: utcConverted flag prevents double offset application when isUtc=false - Add tests covering julianday/rd formatting, calendar conversion, locale-driven calendar selection, and the two-step gregorian → julianday → locale pattern
Contributor
|
I've added test/date/datefmt_TimezoneCalendar_extra_test.dart. |
_convertToFormatterCalendar gated timezone conversion on whether the formatter's timezone was explicitly set (_explicitTimezone). This ignored an ILibDateOptions' own timezone when the formatter timezone defaulted from the locale, so a date with an explicit timezone formatted differently from an equivalent ILibCalendarDate. Gate on the date's own timezone instead (matches JS (date.timezone || 'local') === formatterTz): convert only when the date carries an explicit timezone differing from the formatter's. A null date timezone means 'local' and needs no conversion, preserving the plain- component and local-DateTime cases. Removes the _explicitTimezone field.
…tant _resolveDateOptions merged the caller's year/month/day (via `?? dt.X`) with the decomposed absolute instant. When an instant (dateTime/unixtime/ julianday/rd) was combined with explicit components in another calendar (e.g. type:'islamic', year:1445), those components were kept but stamped 'gregorian', producing a wrong date. Take all components from the decomposed dt only, so they stay consistent with the hardcoded 'gregorian' calendar. No effect on normal usage, where an absolute instant is passed alone.
Contributor
Author
I’ve made updates so that everything works, including the test files you added, and I also updated the code after validating more diverse edge cases. Please check them again. |
seonmiJin
approved these changes
Jul 31, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Checklist
The following lists affects Pub Points on pub.dev when the package is published.
dart formatcommand.Summary
Adds
julianday/rdinputs toILibDateOptions(parity with JSDateFactory) and fixes several calendar/timezone conversion bugs inILibDateFmt.format()that were uncovered by a follow-up code review.What changed
Feature
ILibDateOptions: newjuliandayandrdfields;_toCalendarDate()now cleanly separates the absolute-instant path (julianday/rd/unixtime/dateTime) from the component path.toCalendarDate(): new public method exposing the resolvedILibCalendarDate(matches what JSDateFactoryreturns directly).getCalendar()/_toCalendarDate()derive the calendar fromlocalewhentype/calendaris omitted, then fall back togregorian.Fixes
type:DateFactory({unixtime, type:'islamic'})-style input no longer misreads the decomposed Gregorian components as being in the caller's calendar (was producing wildly wrong dates likeOctober 19, 2585).format()now re-creates the date in the formatter's timezone when the input's timezone differs, gated on the date's timezone (matching JS(date.timezone || 'local') === formatterTz) rather than a formatter-explicit flag.DateTime: a non-UTCDateTime(isUtc=false) is no longer double-offset during calendar conversion.gregoriancalendar.Verification against iLib JS
All conversion results were checked 1:1 against iLib JS (
DateFactory/DateFmt):unixtime + type:islamic→ gregorian formatter →July 4, 2024✓unixtime→ explicit islamic formatter →Ḏu al-Ḥijja 27, 1445(= JS1445-12-27) ✓GregorianDate(tz:'Europe/Berlin')→ en-US formatter →6:00 AM(Berlin→NY) ✓Notes
Two review findings were investigated and intentionally not changed, as current behavior already matches iLib JS:
ILibCalendarDatetimezone comparison is unconditional (no formatter-explicit gate) — matches JS.B(flexible day-period) selection with midnight-wrapping periods matches JS output.Motivation
Enables the JS two-step pattern in Dart:
Test plan
flutter test test/date/datefmt_datetime_calendar_extra_test.dartflutter test test/date/datefmt_TimezoneCalendar_extra_test.dartflutter testfa-IR/am-ETdatetime formatting)