Skip to content

Accept Decimal timestamps in fromtimestamp and utcfromtimestamp - #1340

Open
Nishuuzz wants to merge 1 commit into
arrow-py:masterfrom
Nishuuzz:fix-decimal-timestamp-constructors
Open

Accept Decimal timestamps in fromtimestamp and utcfromtimestamp#1340
Nishuuzz wants to merge 1 commit into
arrow-py:masterfrom
Nishuuzz:fix-decimal-timestamp-constructors

Conversation

@Nishuuzz

Copy link
Copy Markdown

arrow.get() accepts a Decimal timestamp, but the constructors it stands in for reject the same value:

>>> arrow.get(Decimal("1591328104.308505"))
<Arrow [2020-06-05T03:35:04.308505+00:00]>

>>> Arrow.utcfromtimestamp(Decimal("1591328104.308505"))
ValueError: The provided timestamp Decimal('1591328104.308505') is invalid.

Same for Arrow.fromtimestamp.

The factory converts a Decimal to a float before dispatching, and test_one_arg_decimal covers it, so this is supported input rather than something that happens to work. fromtimestamp and utcfromtimestamp instead gate on util.is_timestamp, which only admits int, float and str. A Decimal is turned away as "invalid" — and the very next line calls float(timestamp), which would have been perfectly happy with it.

This converts it in those two methods, the same way the factory already does, and widens their type hints and docstrings to match.

I deliberately did not change util.is_timestamp, even though that is where the check lives. #1321 and #1324 are both open against that function, and it is public API in its own right, so it seemed better to leave it alone and fix the asymmetry where it actually shows.

Testing

test_fromtimestamp_decimal and test_utcfromtimestamp_decimal, next to the existing tests for those constructors. Both fail on master with the ValueError above.

Full suite is green at 1903 passed, and black and flake8 are clean. The existing float, str and invalid-input behaviour is unchanged — "invalid timestamp" still raises, and the two existing assertions covering that still pass.

`arrow.get()` takes a Decimal timestamp and has done since arrow-py#900, with a
test covering it, because the factory converts one to a float before
dispatching. The constructors it stands in for do not:

    >>> arrow.get(Decimal("1591328104.308505"))
    <Arrow [2020-06-05T03:35:04.308505+00:00]>
    >>> Arrow.utcfromtimestamp(Decimal("1591328104.308505"))
    ValueError: The provided timestamp Decimal('1591328104.308505') is invalid.

They gate on util.is_timestamp, which only admits int, float and str, so
a Decimal is turned away as invalid even though the following line calls
float() on it and would have been perfectly happy.

Convert it the same way the factory does, rather than widening
is_timestamp, which two open pull requests are already changing.
@codecov

codecov Bot commented Aug 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 100.00%. Comparing base (2224255) to head (be3fded).
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff            @@
##            master     #1340   +/-   ##
=========================================
  Coverage   100.00%   100.00%           
=========================================
  Files           10        10           
  Lines         2315      2320    +5     
  Branches       358       360    +2     
=========================================
+ Hits          2315      2320    +5     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

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.

1 participant