Skip to content

Preserve microseconds in DateTime and Duration - #341

Merged
Rexios80 merged 7 commits into
mainfrom
fix/microsecond-precision
Oct 9, 2026
Merged

Rexios80 merged 7 commits into
mainfrom
fix/microsecond-precision

Conversation

@Rexios80

@Rexios80 Rexios80 commented Oct 7, 2026

Copy link
Copy Markdown
Member

Summary

  • Fixes DateTime and Duration lose their microseconds #340: DateTime and Duration adapters now store microseconds as a fractional millisecond double, using the approach proposed by @LahaLuhem in the issue
  • Type IDs and byte layout are unchanged: whole-millisecond values produce identical bytes, so existing data reads exactly and older versions still read new data as milliseconds
  • Round trips are exact for dates between roughly 1692 and 2247 (and durations under ~278 years); outside that range they are within 500 µs
  • Bumps hive_ce to 2.21.0

Test plan

@codecov

codecov Bot commented Oct 7, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 93.68%. Comparing base (8171c32) to head (8434624).

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #341      +/-   ##
==========================================
+ Coverage   93.66%   93.68%   +0.02%     
==========================================
  Files          66       66              
  Lines        2668     2678      +10     
==========================================
+ Hits         2499     2509      +10     
  Misses        169      169              

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

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@LahaLuhem

Copy link
Copy Markdown
Contributor

@Rexios80 That was quick!

A few range problems with implementation:

  1. Existing whole-ms data past 4252 reads back changed, about 3 in 4 values by 9999. DateTime.utc(9999, 12, 31, 23, 59, 59, 999) written by 2.20.1 comes back 8 µs off
  2. 1827 to 1830 and 2109 to 2112 aren't exact. About 1 in 4 stamps comes back 1 µs off, e.g. 2110-05-22T13:24:37.221776Z

I would recommend something like:

double _encodeMillis(int micros) {
  final whole = micros ~/ 1000;
  return whole + (micros - whole * 1000) / 1000;
}

int _decodeMicros(double millis) {
  final whole = millis.truncate();
  return whole * 1000 + ((millis - whole) * 1000).round();
}

The mock tests only use DateTime.now(), so they pass either way. Reading 253402300799999.0 through the adapter is broken for this branch.

@Rexios80

Rexios80 commented Oct 7, 2026

Copy link
Copy Markdown
Member Author

Yeah I'm still working on this. Thanks for the help.

@Rexios80

Rexios80 commented Oct 8, 2026

Copy link
Copy Markdown
Member Author

@LahaLuhem Are you happy with this?

@LahaLuhem

Copy link
Copy Markdown
Contributor

@LahaLuhem Are you happy with this?

LGTM.
Checked on the VM, dart2js and dart2wasm. Thanks!

@Rexios80
Rexios80 merged commit 16adeda into main Oct 9, 2026
25 of 26 checks passed
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.

DateTime and Duration lose their microseconds

2 participants