Skip to content

Implement missing DateTimeOffset functionality for the Python target #4475

Description

@ncave

[Python] Implement missing DateTimeOffset members

Summary

The Python target's DateTimeOffset implementation in fable_library/date_offset.py is incomplete. Many members from System.DateTimeOffset either throw at runtime (referenced in Replacements.fs but not implemented in the library) or are silently missing.

Currently working

  • Constructor: DateTimeOffset(year, month, day, hour, minute, second, millisecond, offset) via create
  • Properties: Year, Month, Day, Hour, Minute, Second, Offset, DateTime, Now, UtcNow
  • Static fields: MinValue
  • Methods: ToString, TryParse, FromUnixTimeMilliseconds, FromUnixTimeSeconds, ToUnixTimeMilliseconds, ToUnixTimeSeconds
  • Operator: op_subtraction (DateTimeOffset - DateTimeOffset → TimeSpan, DateTimeOffset - TimeSpan → DateTimeOffset)
  • Equality/comparison: delegated to date.equals / date.compare

Missing / broken

Constructors

  • DateTimeOffset(DateTime)fromDate referenced in Replacements.fs but missing in date_offset.py
  • DateTimeOffset(Int64 ticks, TimeSpan offset)fromTicks referenced but missing
  • DateTimeOffset(DateOnly, TimeOnly, TimeSpan) — not handled

Fields

  • MaxValuedate_offset.maxValue referenced in Replacements.fs but missing in date_offset.py
  • UnixEpoch

Properties

  • UtcDateTimeto_universal_time referenced but missing
  • LocalDateTimeto_local_time referenced but missing
  • UtcTicksgetUtcTicks referenced but missing
  • Date (date-only component as DateTime)
  • DayOfWeek
  • DayOfYear
  • Millisecond
  • Microsecond
  • Nanosecond
  • Ticks (clock time ticks)
  • TimeOfDay (as TimeSpan)
  • TotalOffsetMinutes

Methods

  • Add(TimeSpan) — would go via catch-all to date_offset.add, which is missing
  • AddDays(float) — catch-all, not implemented
  • AddHours(float) — catch-all, not implemented
  • AddMicroseconds(float) — catch-all, not implemented
  • AddMilliseconds(float) — referenced as addMilliseconds (used for AddTicks), missing
  • AddMinutes(float) — catch-all, not implemented
  • AddMonths(int) — catch-all, not implemented
  • AddSeconds(float) — catch-all, not implemented
  • AddYears(int) — catch-all, not implemented
  • AddTicks(int64) — dispatches to addMilliseconds, which is missing
  • Compare(DateTimeOffset, DateTimeOffset) — static method, not handled
  • EqualsExact(DateTimeOffset) — not handled
  • FromFileTime(int64) — not handled
  • ToFileTime() — not handled
  • ToLocalTime()to_local_time referenced but missing
  • ToOffset(TimeSpan) — not handled
  • ToUniversalTime()to_universal_time referenced but missing
  • ParseExact — not handled
  • TryParseExact — not handled

Operators

  • op_addition (DateTimeOffset + TimeSpan) — commented out in Rust extension, missing in date_offset.py

Other

  • GetHashCode / hash support — Replacements.fs routes to date.dateHash, which does not exist in date.py; DateTimeOffset values cannot be used as map/set keys reliably

Implementation notes

  • The catch-all branch in Replacements.fs (line ~3022) forwards unknown instance methods to date_offset.<lowerFirst(methodName)>, so many Add* methods will silently try to call missing functions at runtime.
  • to_local_time and to_universal_time should return DateTimeOffset (not DateTime), consistent with the .NET API.
  • AddTicks is currently mapped to addMilliseconds(ticks / 10000) — this function needs to be added, and the mapping should be verified for precision.
  • Equality semantics: .NET compares DateTimeOffset by UTC-normalized instant (not by local time + offset pair). The current delegation to date.equals needs to apply the offset before comparing.
  • The Rust extension (src/fable-library-py/src/datetime_offset.rs) has stubs for most functions commented out — these should be completed when the Python implementation is stabilized.

Files to change

  • src/fable-library-py/fable_library/date_offset.py — main implementation
  • src/Fable.Transforms/Python/Replacements.fs — wire up new functions
  • tests/Python/TestDateTimeOffset.fs — add test coverage for each implemented member

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions