Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Microseconds are lost when creating DateTime.parse or DateTime.fromMicrosecondsSinceEpoch #44876

Closed
osaxma opened this issue Feb 6, 2021 · 13 comments
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-core type-documentation A request to add or improve documentation

Comments

@osaxma
Copy link
Contributor

osaxma commented Feb 6, 2021

As mentioned in the title and as shown in the example below:

main() {
 final datetimeParsed = DateTime.parse('2021-02-05T22:37:12.933232+00:00');
 final datetimeMS = DateTime.fromMicrosecondsSinceEpoch(1612564632933232);
  
 print(datetimeParsed.toIso8601String()); // prints 2021-02-05T22:37:12.933Z
 print(datetimeMS.toUtc().toIso8601String()); // prints 2021-02-05T22:37:12.933Z
  
 print(datetimeParsed.microsecondsSinceEpoch); // prints 1612564632933000
 print(datetimeMS.microsecondsSinceEpoch); // prints 1612564632933000 
}

Dart SDK on 2.10.4 (example on DartPad)

@lrhn
Copy link
Member

lrhn commented Feb 6, 2021

The web Date object doesn't support microseconds. It's implemented using the JavaScript Date object which only supports millisecond precision. So, working as well as possible.

@rydmike
Copy link

rydmike commented Feb 7, 2021

Since Flutter Web is probably going mainstream very soon, it would be helpful to devs if the Flutter and Dart teams could collaborate and create an overview list of APIs with different behavior in VM and WEB builds. Since more and many devs new to Dart, will probably start to build cross platforms apps, more devs are likely to stumble on such issues from time to time. It would be good to preempt it a bit at least, and provide a consolidated source for already known such potential pitfalls.

Perhaps there already is such an overview in the Dart lang docs site? In that case it would be good to promote it better and reference it from the Flutter site as well.

Yes this particular case is of course documented at least in the doc comments for the getter in question, so it is in API docs, IDE tooling and when you drill into the source:
https://api.dart.dev/stable/2.10.5/dart-core/DateTime/microsecondsSinceEpoch.html

But can be easy to miss, especially if you just build something that was originally built just for Flutter VM apps to run on Flutter Web as well.

@rydmike
Copy link

rydmike commented Feb 7, 2021

On that note, would it be possible to create a lint rule that could be enabled to detect these kind of issues, and it would warn you when you might have an issue due to differences in VM and WEB implementations?

@vsmenon vsmenon added area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-core labels Feb 8, 2021
@vsmenon
Copy link
Member

vsmenon commented Feb 8, 2021

Assigning to lib to improve the doc on this API to at least say what @lrhn says above. As written, it looks like it could return anything. The implementation uses millisecond precision and multiplies by 1000 here:

int get microsecondsSinceEpoch => 1000 * _value;

A general VM vs Web lint would be difficult ( any API uses int might behave different, but it's usually not likely to matter ). We might consider flagging certain APIs more likely to be misused though. ( @pq @rakudrama @ferhatb ?)

@rydmike
Copy link

rydmike commented Feb 8, 2021

A lint rule that can catch and warn about certain APIs, that you might stumble on in Flutter Web and VM cross platform dev, would already imo be very useful and helpful, definitely better than nothing and relaying on memory to remember them.

Would you like a separate submission of a suggestion/issue for such a lint rule? Just to have it as its own actionable topic instead of the comment I just threw up in the air here to see if it might stick... 😃

@vsmenon
Copy link
Member

vsmenon commented Feb 8, 2021

@rydmike - please do - you can file it here and reference this issue:

https://github.com/dart-lang/linter/issues

thanks!

@pq
Copy link
Member

pq commented Feb 8, 2021

Yes, thank you @rydmike. Issues would be greatly appreciated!

@rydmike
Copy link

rydmike commented Feb 8, 2021

Added: dart-lang/linter#2447

@Roms1383
Copy link

I think I currently have the same issue, here's a quick demo on dartpad.

@osaxma
Copy link
Contributor Author

osaxma commented Sep 10, 2022

@Roms1383

By the way, this is only an issue for dart in the Web (e.g. DartPad or Flutter Web).

Running your script on other platforms than web would produce expected results.

This was ran on macOS:

equivalent in Rust: 1970-01-01 00:02:30.151152 UTC (ms 150151152)
ms: 150151152
date: 1970-01-01 00:02:30.151152Z
ms since epoch: 150151152
----------------
equivalent in Rust: 1970-01-02 17:42:31.152153 UTC (ms 150151152153)
ms: 150151152153
date: 1970-01-02 17:42:31.152153Z
ms since epoch: 150151152153
----------------
equivalent in Rust: 1974-10-04 20:39:12.153154 UTC (ms 150151152153154)
ms: 150151152153154
ms multiplied by 1000: 150151152153154000
date: 1974-10-04 20:39:12.153154Z
date with multiplied ms: 6728-02-07 13:22:33.154Z
ms since epoch: 150151152153154
ms since epoch date with multiplied ms: 150151152153154000

@Roms1383
Copy link

@osaxma Oh nice, thanks !
My bad I thought DartPad produced a result equivalent to e.g. desktop, this is actually a good news for me too!

@HideakiSago
Copy link

HideakiSago commented May 10, 2024

I think this problem is very serious.

for example
Parsing 1999-12-31T23:59:59.999500 on the web
It will be rounded off to 2000-1-1-T0:0:0.000.

I don't think there is any particular problem when generating with DateTime.now().
However, if the server side handles date and time down to micro seconds or nano seconds, if these are rounded off by the client, the timestamp of the data will be different between the server and the client.
(If this was truncated, it might still be usable...)

I don't think it would be acceptable to have these differences between platforms.

I think this problem will cause a very troublesome problem.

There are several ideas to work around this problem, but I think these ideas are pretty stupid.

  • Truncate micro seconds system-wide when providing system for the web
  • Prepare your own class that can handle up to micro seconds instead of DateTime

I understand that Dart is a language developed to replace JS.
I don't think we should be held back by old technology.

What do you think, guys?

copybara-service bot pushed a commit that referenced this issue May 31, 2024
…f `DataTime`"

Original change: https://dart-review.googlesource.com/c/sdk/+/366963

This reverts commit 72b2883.


[js_runtime, js_dev_runtime] Implement `microsecond` field of `DataTime`

- Move DateTime implementation for dart2js and DDC into a shared place to reduce duplication.

- Add a _microsecond field to the web DateTime to track microseconds outside of the JavaScript Date.

- The cute dart2js optimization whereby `DateTime.now().millisecondsSinceEpoch` is compiled to `Date.now()` still works.

- Both implementations report better errors.

- Fixed VM bug with in-range sentinel.


Issue: #44876
Issue: firebase/flutterfire#12102
Issue: b/342552853
CoreLibraryReviewExempt: Reapply of unchanged code
Change-Id: I7f14b69e412a052ef3fe6b43cc9cf9d96319adb8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/368380
Commit-Queue: Stephen Adams <[email protected]>
Reviewed-by: Lasse Nielsen <[email protected]>
@rakudrama
Copy link
Member

Fixed via 20316bc, b42bd24

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-core-library SDK core library issues (core, async, ...); use area-vm or area-web for platform specific libraries. library-core type-documentation A request to add or improve documentation
Projects
None yet
Development

No branches or pull requests

8 participants