Skip to content

[Python] Implement missing DateTimeOffset members, add DateOnly and TimeOnly#4477

Merged
dbrattli merged 14 commits intomainfrom
python-datetimeoffset
Apr 2, 2026
Merged

[Python] Implement missing DateTimeOffset members, add DateOnly and TimeOnly#4477
dbrattli merged 14 commits intomainfrom
python-datetimeoffset

Conversation

@dbrattli
Copy link
Copy Markdown
Collaborator

@dbrattli dbrattli commented Apr 2, 2026

Summary

  • Implement missing DateTimeOffset members for the Python target, closing Implement missing DateTimeOffset functionality for the Python target #4475
  • Add DateOnly and TimeOnly support (new date_only.py and time_only.py)
  • Fix DateTimeOffset equality/comparison to use UTC-normalized instants (.NET semantics)
  • All 2193 Python tests pass (21 new); 78 .NET tests pass; 0 Pyright errors

DateTimeOffset — new members

Constructors: FromDate(DateTime), FromTicks(int64, TimeSpan), DateTimeOffset(DateOnly, TimeOnly, TimeSpan)

Fields: MaxValue, UnixEpoch

Properties: UtcDateTime, LocalDateTime, Date, DayOfWeek, DayOfYear, TimeOfDay, Ticks, UtcTicks, TotalOffsetMinutes

Methods: Add, AddYears/Months/Days/Hours/Minutes/Seconds/Milliseconds/Ticks, ToUniversalTime, ToLocalTime, ToOffset, Subtract, Compare, CompareTo, EqualsExact, FromUnixTimeSeconds/Milliseconds, ToUnixTimeSeconds/Milliseconds

Operators: op_Addition

DateOnly — new

Constructors, MinValue/MaxValue, Day/Month/Year, DayOfWeek, DayOfYear, AddDays/AddMonths/AddYears, ToDateTime, ToString, Parse/TryParse, FromDateTime

TimeOnly — new

Constructors, MinValue, FromTicks, FromTimeSpan, FromDateTime, Hour/Minute/Second/Millisecond, Ticks, ToTimeSpan, Add, AddHours/AddMinutes, IsBetween, ToString, Parse/TryParse, op_Subtraction

Key fixes

  • DateTimeOffset equality/comparison routes to date_offset module (UTC-normalized)
  • FromUnixTimeSeconds/Milliseconds call proper date_offset functions
  • from_date_time_offset in date.py returns plain datetime (not DateTimeOffset subclass)
  • DateTimeOffset.__sub__/__add__ overrides prevent wrong constructor dispatch
  • Unsafe thisArg.Value replaced with pattern matching in Replacements.fs

Test plan

  • 2193 Python tests pass (0 regressions, 21 new)
  • 78 .NET tests pass (DateTimeOffset + DateOnly + TimeOnly)
  • 0 Pyright errors on all library files
  • Changelogs updated

🤖 Generated with Claude Code

dbrattli and others added 2 commits April 2, 2026 21:58
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Apr 2, 2026

Python Type Checking Results (Pyright)

Metric Value
Total errors 18
Files with errors 4
Excluded files 4
New errors ✅ No
Excluded files with errors (4 files)

These files have known type errors and are excluded from CI. Remove from pyrightconfig.ci.json as errors are fixed.

File Errors Status
temp/tests/Python/test_applicative.py 12 Excluded
temp/tests/Python/test_hash_set.py 3 Excluded
temp/tests/Python/test_nested_and_recursive_pattern.py 2 Excluded
temp/tests/Python/fable_modules/thoth_json_python/encode.py 1 Excluded

dbrattli and others added 4 commits April 2, 2026 22:08
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Use SupportsInt/SupportsFloat for Fable numeric type parameters
- Add @overload for op_subtraction/subtract/__sub__
- Return int32 from compare/compare_to
- Use Int64 constant for AddTicks divisor
- Replace unsafe thisArg.Value with pattern matching

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add date_only.py: create, min/max, day/month/year, dayOfWeek,
  dayOfYear, addDays/Months/Years, toDateTime, toString, parse
- Add time_only.py: create, fromTicks, fromTimeSpan, fromDateTime,
  add, addHours/Minutes, isBetween, toString, parse
- Add DateTimeOffset: UnixEpoch, TotalOffsetMinutes,
  DateTimeOffset(DateOnly, TimeOnly, TimeSpan) constructor
- Wire up dateOnly/timeOnly handlers in Python Replacements.fs
- Add 21 new tests (10 DateOnly + 8 TimeOnly + 3 DateTimeOffset)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@dbrattli dbrattli changed the title [Python] Implement missing DateTimeOffset members [Python] Implement missing DateTimeOffset members, add DateOnly and TimeOnly Apr 2, 2026
dbrattli and others added 3 commits April 2, 2026 23:12
- Remove datetime_offset.rs and .pyi stub (pure Python approach)
- Return int32 from DateTimeOffset property accessors
- Add TimeOnly property functions (hour, minute, second, millisecond, ticks)
- Use SupportsFloat for TimeOnly add_hours/add_minutes
- Route TimeOnly.MinValue through library call

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
dbrattli and others added 2 commits April 2, 2026 23:36
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@ncave
Copy link
Copy Markdown
Collaborator

ncave commented Apr 2, 2026

@dbrattli While you're at it, perhaps also fix the create to match the microsecond constructor, since the underlying object supports microseconds storage.

dbrattli and others added 3 commits April 2, 2026 23:51
- Fix misleading comment in _to_utc_ms
- Remove unused _ticks_per_millisecond
- Fix precision loss in ticks() using integer arithmetic
- Add docstring to from_date_time clarifying representations
- Add missing __all__ entries in time_only.py

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Refactor create() to use isinstance checks for TimeSpan offset detection,
supporting all constructor arities: 7-arg (with offset), 8-arg (with ms
and offset), and 9-arg (with ms, mc, and offset).

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…int()

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@dbrattli dbrattli merged commit 436731d into main Apr 2, 2026
24 checks passed
@dbrattli dbrattli deleted the python-datetimeoffset branch April 2, 2026 22:42
dbrattli added a commit that referenced this pull request Apr 2, 2026
…eOnly

Port the Python DateTimeOffset/DateOnly/TimeOnly work from #4477 to the
Beam target.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
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.

3 participants