srawlins / timezone

Time zone database and time zone aware DateTime object for Dart.
BSD 2-Clause "Simplified" License
102 stars 54 forks source link

Error occurred when getting difference between DateTime and TZDateTime #57

Open markqq opened 4 years ago

markqq commented 4 years ago

Hi, I can't get the difference between DateTime and TZDateTime by the following code:

DateTime dt;
TZDatetime tz;

...

print(dt.difference(tz));

Is there any way to solve the problem? Thx.

srawlins commented 4 years ago

Hi @markqq , I'll need a more specific example than that.

matthewlloyd commented 4 years ago

Here's an example:

import 'package:timezone/standalone.dart' as tz;

void main() async {
  await tz.initializeTimeZone();

  final tz.TZDateTime tzdt = tz.TZDateTime.utc(2020, 6, 15);
  final DateTime dt = DateTime.now().toUtc();
  print(dt.difference(tzdt));
}

This unexpectedly produces a runtime exception:

Unhandled exception:
NoSuchMethodError: Class 'TZDateTime' has no instance getter '_value'.
Receiver: Instance of 'TZDateTime'
Tried calling: _value
#0      Object.noSuchMethod (dart:core-patch/object_patch.dart:53:5)
#1      TZDateTime._value (dart:core/date_time.dart:158:13)
#2      DateTime.difference (dart:core-patch/date_patch.dart:203:54)
#3      main (file:///.../timezone_test/main.dart:8:12)
<asynchronous suspension>
#4      _startIsolate.<anonymous closure> (dart:isolate-patch/isolate_patch.dart:301:19)
#5      _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:168:12)

It's because TZDateTime doesn't have the _value field which is part of the DateTime interface.

It really should be caught at compile time, so it may actually be a Dart language bug. If you put skeleton DateTime and TZDateTime classes in the same file, the compiler does in fact complain:

class DateTime {
  final int _value = 0;
}

class TZDateTime implements DateTime {
}

void main() {
}

This correctly produces a compiler exception:

Error compiling to JavaScript:
main.dart:5:7:
Error: The non-abstract class 'TZDateTime' is missing implementations for these members:
 - DateTime._value
class TZDateTime implements DateTime {
      ^^^^^^^^^^
main.dart:2:13:
Info: 'DateTime._value' is defined here.
  final int _value = 0;
            ^^^^^^
Error: Compilation failed.

It may be a compiler limitation that it doesn't notice the missing implementation if the classes are in separate packages. This is with Dart 2.8.4.

This issue caused a nasty runtime crash in my production app and affected a lot of users... I had to issue an emergency app store update to fix it.

matthewlloyd commented 4 years ago

Related: https://github.com/dart-lang/sdk/issues/34962

matthewlloyd commented 4 years ago

It's a bug in the Dark SDK's implementation of DateTime. I submitted a pull request that fixes it.

kubaprzetakiewicz commented 2 years ago

Any traction on this? Can still reproduce:

Error message ``` errors.dart:202 Uncaught (in promise) Error: NoSuchMethodError: '_value' method not found Receiver: Instance of 'TZDateTime' Arguments: [] at Object.throw_ [as throw] (errors.dart:251) at Object.defaultNoSuchMethod (operations.dart:731) at date_time.TZDateTime.from.noSuchMethod (core_patch.dart:61) at date_time.TZDateTime.from.get [_value] (date_time.dart:477) at core.DateTime._withValue.difference (core_patch.dart:382) ```
flutter doctor ``` [✓] Flutter (Channel stable, 2.5.1, on macOS 11.4 20F71 darwin-x64, locale en-GB) • Flutter version 2.5.1 at /Users/kubaprzetakiewicz/SDKs/flutter • Upstream repository https://github.com/flutter/flutter.git • Framework revision ffb2ecea52 (2 weeks ago), 2021-09-17 15:26:33 -0400 • Engine revision b3af521a05 • Dart version 2.14.2 [✓] Android toolchain - develop for Android devices (Android SDK version 30.0.3) • Android SDK at /Users/kubaprzetakiewicz/Library/Android/sdk • Platform android-30, build-tools 30.0.3 • Java binary at: /Applications/Android Studio.app/Contents/jre/jdk/Contents/Home/bin/java • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495) • All Android licenses accepted. [✓] Xcode - develop for iOS and macOS • Xcode at /Applications/Xcode.app/Contents/Developer • Xcode 13.0, Build version 13A233 • CocoaPods version 1.11.2 [✓] Chrome - develop for the web • CHROME_EXECUTABLE = /Applications/Google Chrome Canary.app/Contents/MacOS/Google Chrome Canary [✓] Android Studio (version 4.1) • Android Studio at /Applications/Android Studio.app/Contents • Flutter plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/9212-flutter • Dart plugin can be installed from: 🔨 https://plugins.jetbrains.com/plugin/6351-dart • Java version OpenJDK Runtime Environment (build 1.8.0_242-release-1644-b3-6915495) [✓] IntelliJ IDEA Ultimate Edition (version 2021.1.2) • IntelliJ at /Applications/IntelliJ IDEA.app • Flutter plugin version 57.0.5 • Dart plugin version 211.7233 [✓] VS Code (version 1.60.2) • VS Code at /Applications/Visual Studio Code.app/Contents • Flutter extension version 3.26.0 [✓] Connected device (1 available) • Chrome (web) • chrome • web-javascript • Google Chrome 96.0.4658.2 canary • No issues found! ```