arrow-py / arrow-py/arrow

dehumanize() silently returns wrong times for fractional inputs ("1.5 hours ago" is off by 3.5 hours)

Open
#1,341 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
Python
Stars
9.1k
Forks
784
PR merge metrics
No merged PRs in 30d

Description

`dehumanize()` silently returns **wrong times** for any fractional input — the digits around the decimal point are handled independently instead of being parsed as one number.

**Version:** arrow 1.4.0 (release; also on current master). Verified on Python 3.13.

## Repro

```python
import arrow

base = arrow.get("2026-01-01T00:00:00+00:00")

print(base.dehumanize("1.5 hours ago"))
print(base.dehumanize("0.5 days ago"))
```

Actual vs expected:

| input | release 1.4.0 | correct |
|---|---|---|
| `"1.5 hours ago"` | `2025-12-31T19:00:00+00:00` (**−5 h**) | `2025-12-31T22:30:00+00:00` (−1.5 h) |
| `"0.5 days ago"` | `2025-12-27T00:00:00+00:00` (**−5 days**) | `2025-12-31T12:00:00+00:00` (−0.5 d) |

No exception, no warning — just a quietly wrong timestamp, off by 3.5 hours / 4.5 days respectively in these examples. The magnitude of the error scales with the discarded fraction's digits, so inputs like `"2.25 weeks"` drift even further.

## Root cause

The token/number handling in `DateTimeParser.parse` + `dehumanize` ends up splitting `"1.5"` at the dot and treating the fragments as separate numeric contributions rather than one float (`"0.5 days"` behaves like `"5 days"`, which matches the −5 d result exactly).

## Proposed fix direction

Accept an unsigned int-or-decimal in the number pattern fed to dehumanize (e.g. `\d+(?:[.,]\d+)?`, also covering comma decimals used by locales such as fr_FR), convert with `float(...)`, and carry the value through `time_object_info` as float — the downstream `timedelta` math already handles floats.

## Working implementation

PR #1334 implements exactly this and I verified it locally against the matrix above — all cases become exact (`−1.5 h`, `−0.5 d`, and `"1.5 days ago"` → −36 h), including comma-decimal inputs. Filing this issue so the released-version bug is tracked independently of that PR, since users on 1.4.0 are affected today.

Contributor guide

No contributing guide indexed for this repository

Research direction

Start with DateTimeParser.parse and dehumanize, then compare the behavior and test coverage in PR #1334. Done means the reported integer, decimal-point, and comma-decimal examples produce the expected timestamps without warnings or exceptions.

Written by the indexing model from the issue text.

Assessment

Tech stack
python
Domain
backend
Issue type
Bug
Difficulty
2/5
Estimated time
1-3 hours
Activity status
Stale
Clarity
Clearly specified
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.