sdk icon indicating copy to clipboard operation
sdk copied to clipboard

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

Open osaxma opened this issue 4 years ago • 11 comments

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)

osaxma avatar Feb 06 '21 09:02 osaxma

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.

lrhn avatar Feb 06 '21 22:02 lrhn

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 avatar Feb 07 '21 12:02 rydmike

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?

rydmike avatar Feb 07 '21 13:02 rydmike

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:

https://github.com/dart-lang/sdk/blob/30ba97bb1b0717f70545cc98050be823a25757de/sdk/lib/_internal/js_runtime/lib/core_patch.dart#L333

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 ?)

vsmenon avatar Feb 08 '21 13:02 vsmenon

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... 😃

rydmike avatar Feb 08 '21 16:02 rydmike

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

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

thanks!

vsmenon avatar Feb 08 '21 16:02 vsmenon

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

pq avatar Feb 08 '21 16:02 pq

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

rydmike avatar Feb 08 '21 16:02 rydmike

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

Roms1383 avatar Sep 10 '22 06:09 Roms1383

@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

osaxma avatar Sep 10 '22 10:09 osaxma

@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!

Roms1383 avatar Sep 10 '22 15:09 Roms1383

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?

HideakiSago avatar May 10 '24 06:05 HideakiSago

Fixed via https://github.com/dart-lang/sdk/commit/20316bcc5bf1a801c0344eb01d90587a1c1f97f0, https://github.com/dart-lang/sdk/commit/b42bd24b782c6cc31672dc3e994a4faf53ce300d

rakudrama avatar Jun 07 '24 21:06 rakudrama