diff --git a/packages/neon/neon_files/lib/src/blocs/files.dart b/packages/neon/neon_files/lib/src/blocs/files.dart index 2e7739198ba..0914424321f 100644 --- a/packages/neon/neon_files/lib/src/blocs/files.dart +++ b/packages/neon/neon_files/lib/src/blocs/files.dart @@ -19,6 +19,7 @@ import 'package:path_provider/path_provider.dart'; import 'package:queue/queue.dart'; import 'package:rxdart/rxdart.dart'; import 'package:share_plus/share_plus.dart'; +import 'package:timezone/timezone.dart' as tz; import 'package:universal_io/io.dart'; sealed class FilesBloc implements InteractiveBloc { @@ -30,7 +31,7 @@ sealed class FilesBloc implements InteractiveBloc { void uploadFile(PathUri uri, String localPath); - void uploadMemory(PathUri uri, Uint8List bytes, {DateTime? lastModified}); + void uploadMemory(PathUri uri, Uint8List bytes, {tz.TZDateTime? lastModified}); void openFile(PathUri uri, String etag, String? mimeType); @@ -115,7 +116,7 @@ class _FilesBloc extends InteractiveBloc implements FilesBloc { } @override - Future uploadMemory(PathUri uri, Uint8List bytes, {DateTime? lastModified}) async { + Future uploadMemory(PathUri uri, Uint8List bytes, {tz.TZDateTime? lastModified}) async { await wrapAction( () async { final task = FilesUploadTaskMemory( diff --git a/packages/neon/neon_files/lib/src/models/file_details.dart b/packages/neon/neon_files/lib/src/models/file_details.dart index d1c954b7209..09d2c828eda 100644 --- a/packages/neon/neon_files/lib/src/models/file_details.dart +++ b/packages/neon/neon_files/lib/src/models/file_details.dart @@ -1,6 +1,7 @@ import 'package:meta/meta.dart'; import 'package:neon_files/src/utils/task.dart'; import 'package:nextcloud/webdav.dart'; +import 'package:timezone/timezone.dart' as tz; @immutable class FileDetails { @@ -73,7 +74,7 @@ class FileDetails { final String? mimeType; - final DateTime? lastModified; + final tz.TZDateTime? lastModified; final bool? hasPreview; diff --git a/packages/neon/neon_files/lib/src/utils/task.dart b/packages/neon/neon_files/lib/src/utils/task.dart index 0c7822c4449..85fa0d636c8 100644 --- a/packages/neon/neon_files/lib/src/utils/task.dart +++ b/packages/neon/neon_files/lib/src/utils/task.dart @@ -3,6 +3,7 @@ import 'dart:typed_data'; import 'package:meta/meta.dart'; import 'package:nextcloud/nextcloud.dart'; +import 'package:timezone/timezone.dart' as tz; import 'package:universal_io/io.dart'; sealed class FilesTask { @@ -34,7 +35,7 @@ sealed class FilesUploadTask extends FilesTask { final int? size; - final DateTime? lastModified; + final tz.TZDateTime? lastModified; } sealed class FilesTaskIO extends FilesTask { @@ -83,10 +84,10 @@ class FilesUploadTaskIO extends FilesTaskIO implements FilesUploadTask { late final FileStat _stat = file.statSync(); @override - late int? size = _stat.size; + late int size = _stat.size; @override - late DateTime? lastModified = _stat.modified; + late tz.TZDateTime lastModified = tz.TZDateTime.from(_stat.modified, tz.UTC); Future execute(NextcloudClient client) async { await client.webdav.putFile( @@ -129,7 +130,7 @@ class FilesUploadTaskMemory extends FilesTaskMemory implements FilesUploadTask { final int? size; @override - final DateTime? lastModified; + final tz.TZDateTime? lastModified; Future execute(NextcloudClient client) async { await client.webdav.putStream( diff --git a/packages/neon/neon_files/pubspec.yaml b/packages/neon/neon_files/pubspec.yaml index fae04c770ac..85d117949e0 100644 --- a/packages/neon/neon_files/pubspec.yaml +++ b/packages/neon/neon_files/pubspec.yaml @@ -36,6 +36,7 @@ dependencies: queue: ^3.0.0 rxdart: ^0.27.0 share_plus: ^7.0.0 + timezone: ^0.9.2 universal_io: ^2.0.0 dev_dependencies: diff --git a/packages/neon/neon_notifications/lib/src/pages/main.dart b/packages/neon/neon_notifications/lib/src/pages/main.dart index 267bcbd5937..ec8e9fa8f34 100644 --- a/packages/neon/neon_notifications/lib/src/pages/main.dart +++ b/packages/neon/neon_notifications/lib/src/pages/main.dart @@ -10,6 +10,7 @@ import 'package:neon_notifications/l10n/localizations.dart'; import 'package:neon_notifications/src/blocs/notifications.dart'; import 'package:nextcloud/ids.dart'; import 'package:nextcloud/notifications.dart' as notifications; +import 'package:timezone/timezone.dart' as tz; class NotificationsMainPage extends StatefulWidget { const NotificationsMainPage({ @@ -84,7 +85,7 @@ class _NotificationsMainPageState extends State { ), ], RelativeTime( - date: DateTime.parse(notification.datetime).toUtc(), + date: tz.TZDateTime.parse(tz.UTC, notification.datetime), ), ], ), diff --git a/packages/neon/neon_notifications/pubspec.yaml b/packages/neon/neon_notifications/pubspec.yaml index 4f311998153..499cbb69508 100644 --- a/packages/neon/neon_notifications/pubspec.yaml +++ b/packages/neon/neon_notifications/pubspec.yaml @@ -23,6 +23,7 @@ dependencies: path: packages/neon_framework nextcloud: ^5.0.2 rxdart: ^0.27.0 + timezone: ^0.9.2 dev_dependencies: build_runner: ^2.4.8 diff --git a/packages/neon/neon_talk/lib/src/widgets/message.dart b/packages/neon/neon_talk/lib/src/widgets/message.dart index 732336b9ed7..66cb7742b3f 100644 --- a/packages/neon/neon_talk/lib/src/widgets/message.dart +++ b/packages/neon/neon_talk/lib/src/widgets/message.dart @@ -237,7 +237,7 @@ class TalkCommentMessage extends StatelessWidget { tz.UTC, chatMessage.timestamp, ); - DateTime? previousDate; + tz.TZDateTime? previousDate; if (previousChatMessage != null) { previousDate = DateTimeUtils.fromSecondsSinceEpoch( tz.UTC, diff --git a/packages/neon_framework/lib/src/blocs/user_status.dart b/packages/neon_framework/lib/src/blocs/user_status.dart index 6047408a397..3f5f13a871b 100644 --- a/packages/neon_framework/lib/src/blocs/user_status.dart +++ b/packages/neon_framework/lib/src/blocs/user_status.dart @@ -15,6 +15,7 @@ import 'package:nextcloud/nextcloud.dart'; import 'package:nextcloud/user_status.dart' as user_status; import 'package:nextcloud/utils.dart'; import 'package:rxdart/rxdart.dart'; +import 'package:timezone/timezone.dart' as tz; import 'package:window_manager/window_manager.dart'; /// Bloc for managing user statuses. @@ -42,14 +43,14 @@ abstract class UserStatusBloc implements InteractiveBloc { /// Predefined status messages received from [predefinedStatuses]. void setPredefinedMessage({ required String id, - required DateTime? clearAt, + required tz.TZDateTime? clearAt, }); /// Set a custom status [message] with the [icon] and [clearAt]. void setCustomMessage({ required String? message, required String? icon, - required DateTime? clearAt, + required tz.TZDateTime? clearAt, }); /// Clear the current status message. @@ -211,7 +212,7 @@ class _UserStatusBloc extends InteractiveBloc implements UserStatusBloc { @override Future setPredefinedMessage({ required String id, - required DateTime? clearAt, + required tz.TZDateTime? clearAt, }) async { await wrapAction( () async { @@ -230,7 +231,7 @@ class _UserStatusBloc extends InteractiveBloc implements UserStatusBloc { Future setCustomMessage({ required String? message, required String? icon, - required DateTime? clearAt, + required tz.TZDateTime? clearAt, }) async { await wrapAction( () async { diff --git a/packages/neon_framework/lib/src/pages/settings.dart b/packages/neon_framework/lib/src/pages/settings.dart index b81cf719ac3..1f86f8459d6 100644 --- a/packages/neon_framework/lib/src/pages/settings.dart +++ b/packages/neon_framework/lib/src/pages/settings.dart @@ -28,6 +28,7 @@ import 'package:neon_framework/src/widgets/dialog.dart'; import 'package:neon_framework/src/widgets/error.dart'; import 'package:nextcloud/utils.dart'; import 'package:package_info_plus/package_info_plus.dart'; +import 'package:timezone/timezone.dart' as tz; import 'package:url_launcher/url_launcher_string.dart'; final _log = Logger('SettingsPage'); @@ -249,7 +250,7 @@ class _SettingsPageState extends State { final settingsExportHelper = _buildSettingsExportHelper(context); try { - final fileName = 'nextcloud-neon-settings-${DateTime.timestamp().secondsSinceEpoch}.json'; + final fileName = 'nextcloud-neon-settings-${tz.TZDateTime.now(tz.UTC).secondsSinceEpoch}.json'; final data = settingsExportHelper.exportToFile(); await NeonPlatform.instance.saveFileWithPickDialog(fileName, 'application/json', data); diff --git a/packages/neon_framework/lib/src/storage/request_cache.dart b/packages/neon_framework/lib/src/storage/request_cache.dart index 90a05ca16f7..e5469a525cb 100644 --- a/packages/neon_framework/lib/src/storage/request_cache.dart +++ b/packages/neon_framework/lib/src/storage/request_cache.dart @@ -7,6 +7,7 @@ import 'package:neon_framework/src/utils/request_manager.dart'; import 'package:path/path.dart' as p; import 'package:path_provider/path_provider.dart'; import 'package:sqflite_common_ffi/sqflite_ffi.dart'; +import 'package:timezone/timezone.dart' as tz; final _log = Logger('RequestCache'); @@ -168,9 +169,9 @@ CREATE TABLE "cache" ( return CacheParameters( etag: row?['etag'] as String?, expires: expires != null - ? DateTime.fromMillisecondsSinceEpoch( + ? tz.TZDateTime.fromMillisecondsSinceEpoch( + tz.UTC, expires, - isUtc: true, ) : null, ); diff --git a/packages/neon_framework/lib/src/utils/push_utils.dart b/packages/neon_framework/lib/src/utils/push_utils.dart index c93d01ef2e6..1792a522ae7 100644 --- a/packages/neon_framework/lib/src/utils/push_utils.dart +++ b/packages/neon_framework/lib/src/utils/push_utils.dart @@ -25,6 +25,7 @@ import 'package:neon_framework/src/utils/request_manager.dart'; import 'package:neon_framework/storage.dart'; import 'package:nextcloud/notifications.dart' as notifications; import 'package:rxdart/rxdart.dart'; +import 'package:timezone/timezone.dart' as tz; final _log = Logger('PushUtils'); @@ -152,7 +153,7 @@ class PushUtils { } final title = (notification?.subject ?? pushNotification.subject.subject)!; final message = (notification?.message.isNotEmpty ?? false) ? notification!.message : null; - final when = notification != null ? DateTime.parse(notification.datetime).toUtc() : null; + final when = notification != null ? tz.TZDateTime.parse(tz.UTC, notification.datetime) : null; await localNotificationsPlugin.show( _getNotificationID(instance, pushNotification), diff --git a/packages/neon_framework/lib/src/utils/relative_time.dart b/packages/neon_framework/lib/src/utils/relative_time.dart index 56b2f6f4531..c30b024586f 100644 --- a/packages/neon_framework/lib/src/utils/relative_time.dart +++ b/packages/neon_framework/lib/src/utils/relative_time.dart @@ -1,20 +1,21 @@ import 'package:meta/meta.dart'; import 'package:neon_framework/l10n/localizations.dart'; +import 'package:timezone/timezone.dart' as tz; -/// Extension for formatting the difference between two [DateTime]s. +/// Extension for formatting the difference between two [tz.TZDateTime]s. @internal -extension RelativeTimeFormatDateTime on DateTime { +extension RelativeTimeFormatDateTime on tz.TZDateTime { /// Format the relative time between this and [to]. /// - /// If [to] is unspecified [DateTime.timestamp] will be used. + /// If [to] is unspecified the current time in the 'UTC' timezone will be used. /// Set [includeSign] to skip the parts that tell if the difference is into the future or into the past. /// It should only be used if it is already clear from the context if it is about the future or the past. String formatRelative( NeonLocalizations localizations, { bool includeSign = true, - DateTime? to, + tz.TZDateTime? to, }) => - difference(to ?? DateTime.timestamp()).formatRelative( + difference(to ?? tz.TZDateTime.now(tz.UTC)).formatRelative( localizations, includeSign: includeSign, ); diff --git a/packages/neon_framework/lib/src/utils/request_manager.dart b/packages/neon_framework/lib/src/utils/request_manager.dart index d945604a716..f1f422cf930 100644 --- a/packages/neon_framework/lib/src/utils/request_manager.dart +++ b/packages/neon_framework/lib/src/utils/request_manager.dart @@ -14,6 +14,7 @@ import 'package:neon_framework/src/models/account.dart'; import 'package:neon_framework/storage.dart'; import 'package:nextcloud/nextcloud.dart'; import 'package:rxdart/rxdart.dart'; +import 'package:timezone/timezone.dart' as tz; import 'package:xml/xml.dart' as xml; final _log = Logger('RequestManager'); @@ -365,7 +366,12 @@ class CacheParameters { /// Parse the cache parameters from HTTP response headers. factory CacheParameters.parseHeaders(Map headers) { - final expiry = headers.containsKey('expires') ? parseHttpDate(headers['expires']! as String) : null; + tz.TZDateTime? expiry; + if (headers.containsKey('expires')) { + final parsed = parseHttpDate(headers['expires']! as String); + expiry = tz.TZDateTime.from(parsed, tz.UTC); + } + return CacheParameters( etag: headers['etag'] as String?, expires: _isExpired(expiry) ? null : expiry, @@ -376,12 +382,12 @@ class CacheParameters { final String? etag; /// `Expires` of the resource. - final DateTime? expires; + final tz.TZDateTime? expires; /// Whether the resource has expired based on [expires]. bool get isExpired => _isExpired(expires); - static bool _isExpired(DateTime? date) => date?.isBefore(DateTime.timestamp()) ?? true; + static bool _isExpired(tz.TZDateTime? date) => date?.isBefore(tz.TZDateTime.now(tz.UTC)) ?? true; @override bool operator ==(Object other) => other is CacheParameters && other.etag == etag && other.expires == expires; diff --git a/packages/neon_framework/lib/src/utils/user_status_clear_at.dart b/packages/neon_framework/lib/src/utils/user_status_clear_at.dart index c4daa198b3e..17315bd654f 100644 --- a/packages/neon_framework/lib/src/utils/user_status_clear_at.dart +++ b/packages/neon_framework/lib/src/utils/user_status_clear_at.dart @@ -2,6 +2,7 @@ import 'package:meta/meta.dart'; import 'package:neon_framework/l10n/localizations.dart'; import 'package:neon_framework/src/utils/relative_time.dart'; import 'package:nextcloud/user_status.dart' as user_status; +import 'package:timezone/timezone.dart' as tz; @internal extension ClearAt on user_status.ClearAt { @@ -25,16 +26,16 @@ extension ClearAt on user_status.ClearAt { throw ArgumentError('Unknown ClearAt $this'); } - DateTime? toDateTime([DateTime? base]) { - base = base?.toUtc() ?? DateTime.timestamp(); + tz.TZDateTime? toDateTime([tz.TZDateTime? base]) { + base = base?.toUtc() ?? tz.TZDateTime.now(tz.UTC); switch (type) { case user_status.ClearAt_Type.endOf: switch (time.clearAtTimeType) { case user_status.ClearAtTimeType.day: - return DateTime.utc(base.year, base.month, base.day).add(const Duration(days: 1)); + return tz.TZDateTime.utc(base.year, base.month, base.day).add(const Duration(days: 1)); case user_status.ClearAtTimeType.week: - return DateTime.utc(base.year, base.month, base.day).add(Duration(days: 8 - base.weekday)); + return tz.TZDateTime.utc(base.year, base.month, base.day).add(Duration(days: 8 - base.weekday)); } case user_status.ClearAt_Type.period: return base.add(Duration(seconds: time.$int!)); diff --git a/packages/neon_framework/lib/src/widgets/dialog.dart b/packages/neon_framework/lib/src/widgets/dialog.dart index e08e2429274..c097070de18 100644 --- a/packages/neon_framework/lib/src/widgets/dialog.dart +++ b/packages/neon_framework/lib/src/widgets/dialog.dart @@ -758,7 +758,7 @@ class NeonUserStatusDialog extends StatefulWidget { final Account account; /// The current time, only used for testing. - final DateTime? now; + final tz.TZDateTime? now; @override State createState() => _NeonUserStatusDialogState(); diff --git a/packages/neon_framework/lib/src/widgets/image.dart b/packages/neon_framework/lib/src/widgets/image.dart index 4ad12ae5685..a23ef085ad7 100644 --- a/packages/neon_framework/lib/src/widgets/image.dart +++ b/packages/neon_framework/lib/src/widgets/image.dart @@ -15,6 +15,7 @@ import 'package:neon_framework/src/widgets/error.dart'; import 'package:neon_framework/src/widgets/linear_progress_indicator.dart'; import 'package:nextcloud/nextcloud.dart'; import 'package:rxdart/rxdart.dart'; +import 'package:timezone/timezone.dart' as tz; /// The signature of a function building a widget displaying [error]. typedef ErrorWidgetBuilder = Widget? Function(BuildContext context, Object? error); @@ -191,7 +192,7 @@ class NeonApiImage extends StatefulWidget { final String? etag; /// The expiration date used for invalidating the cache. - final DateTime? expires; + final tz.TZDateTime? expires; /// {@macro NeonImage.svgHint} final bool isSvgHint; diff --git a/packages/neon_framework/lib/src/widgets/relative_time.dart b/packages/neon_framework/lib/src/widgets/relative_time.dart index bcc36c64413..772c8c0f2f0 100644 --- a/packages/neon_framework/lib/src/widgets/relative_time.dart +++ b/packages/neon_framework/lib/src/widgets/relative_time.dart @@ -3,8 +3,9 @@ import 'dart:async'; import 'package:flutter/widgets.dart'; import 'package:neon_framework/l10n/localizations.dart'; import 'package:neon_framework/src/utils/relative_time.dart'; +import 'package:timezone/timezone.dart' as tz; -/// Shows the time elapsed since a [DateTime] and periodically updates itself. +/// Shows the time elapsed since a [tz.TZDateTime] and periodically updates itself. class RelativeTime extends StatefulWidget { /// Creates a new relative DateTime widget. const RelativeTime({ @@ -14,7 +15,7 @@ class RelativeTime extends StatefulWidget { }); /// The timestamp to be displayed. - final DateTime date; + final tz.TZDateTime date; /// The text style of the calculated time. /// diff --git a/packages/neon_framework/test/dialog_test.dart b/packages/neon_framework/test/dialog_test.dart index 3b07c5016bf..8231b4b7da4 100644 --- a/packages/neon_framework/test/dialog_test.dart +++ b/packages/neon_framework/test/dialog_test.dart @@ -12,6 +12,7 @@ import 'package:nextcloud/user_status.dart' as user_status; import 'package:nextcloud/utils.dart'; import 'package:rxdart/rxdart.dart'; import 'package:shared_preferences/shared_preferences.dart'; +import 'package:timezone/timezone.dart' as tz; void main() { group('dialog', () { @@ -209,7 +210,7 @@ void main() { testWidgets('NeonUserStatusDialog', (tester) async { SharedPreferences.setMockInitialValues({}); - final now = DateTime.utc(2024, 1, 20); + final now = tz.TZDateTime.utc(2024, 1, 20); final status = BehaviorSubject.seeded( Result.success( diff --git a/packages/neon_framework/test/persistence_test.dart b/packages/neon_framework/test/persistence_test.dart index 42cee4ef870..39c245d1439 100644 --- a/packages/neon_framework/test/persistence_test.dart +++ b/packages/neon_framework/test/persistence_test.dart @@ -7,6 +7,7 @@ import 'package:neon_framework/src/storage/request_cache.dart'; import 'package:neon_framework/src/storage/sqlite_persistence.dart'; import 'package:neon_framework/src/utils/request_manager.dart'; import 'package:sqflite_common_ffi/sqflite_ffi.dart'; +import 'package:timezone/timezone.dart' as tz; void main() { group('Persistences', () { @@ -44,9 +45,9 @@ void main() { parameters = CacheParameters( etag: 'etag', - expires: DateTime.fromMillisecondsSinceEpoch( - DateTime.timestamp().millisecondsSinceEpoch, - isUtc: true, + expires: tz.TZDateTime.fromMillisecondsSinceEpoch( + tz.UTC, + tz.TZDateTime.now(tz.UTC).millisecondsSinceEpoch, ), ); await cache.updateParameters('key', parameters); diff --git a/packages/neon_framework/test/relative_time_test.dart b/packages/neon_framework/test/relative_time_test.dart index b13dcd8886a..b00f470cf3f 100644 --- a/packages/neon_framework/test/relative_time_test.dart +++ b/packages/neon_framework/test/relative_time_test.dart @@ -3,6 +3,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:neon_framework/l10n/localizations_en.dart'; import 'package:neon_framework/src/utils/relative_time.dart'; +import 'package:timezone/timezone.dart' as tz; void main() { final localizations = NeonLocalizationsEn(); @@ -40,7 +41,7 @@ void main() { }); test('DateTime', () { - final base = DateTime.timestamp(); + final base = tz.TZDateTime.now(tz.UTC); expect(base.formatRelative(localizations), 'now'); diff --git a/packages/neon_framework/test/request_manager_test.dart b/packages/neon_framework/test/request_manager_test.dart index b8013bd0a02..e79b864cf6b 100644 --- a/packages/neon_framework/test/request_manager_test.dart +++ b/packages/neon_framework/test/request_manager_test.dart @@ -14,6 +14,7 @@ import 'package:neon_framework/src/bloc/result.dart'; import 'package:neon_framework/src/utils/request_manager.dart'; import 'package:neon_framework/testing.dart'; import 'package:rxdart/rxdart.dart'; +import 'package:timezone/timezone.dart' as tz; String base64String(String value) => base64.encode(utf8.encode(value)); @@ -499,7 +500,7 @@ void main() { (_) => Future.value( CacheParameters( etag: null, - expires: DateTime.timestamp().add(const Duration(hours: 1)), + expires: tz.TZDateTime.now(tz.UTC).add(const Duration(hours: 1)), ), ), ); @@ -537,7 +538,7 @@ void main() { (_) => Future.value( CacheParameters( etag: null, - expires: DateTime.timestamp().subtract(const Duration(hours: 1)), + expires: tz.TZDateTime.now(tz.UTC).subtract(const Duration(hours: 1)), ), ), ); @@ -575,7 +576,10 @@ void main() { test('cached ETag', () async { final callback = MockCallbackFunction(); - final newExpires = DateTime.timestamp().copyWith(microsecond: 0, millisecond: 0).add(const Duration(hours: 1)); + final newExpires = tz.TZDateTime.from( + DateTime.timestamp().copyWith(millisecond: 0, microsecond: 0).add(const Duration(hours: 1)), + tz.UTC, + ); when(() => cache.getParameters(any())).thenAnswer( (_) => Future.value( @@ -675,7 +679,10 @@ void main() { test('cache ETag and Expires', () async { for (final (hours, isSet) in [(1, true), (-1, false)]) { - final newExpires = DateTime.timestamp().copyWith(millisecond: 0, microsecond: 0).add(Duration(hours: hours)); + final newExpires = tz.TZDateTime.from( + DateTime.timestamp().copyWith(millisecond: 0, microsecond: 0).add(Duration(hours: hours)), + tz.UTC, + ); final subject = BehaviorSubject>(); diff --git a/packages/neon_framework/test/user_status_bloc_test.dart b/packages/neon_framework/test/user_status_bloc_test.dart index 42ddf997f09..822ba3d822b 100644 --- a/packages/neon_framework/test/user_status_bloc_test.dart +++ b/packages/neon_framework/test/user_status_bloc_test.dart @@ -235,7 +235,10 @@ void main() { test('Set predefined message', () async { await Future.delayed(const Duration(milliseconds: 1)); - final clearAt = DateTime.timestamp().copyWith(millisecond: 0, microsecond: 0).add(const Duration(hours: 1)); + final clearAt = tz.TZDateTime.from( + DateTime.timestamp().copyWith(millisecond: 0, microsecond: 0).add(const Duration(hours: 1)), + tz.UTC, + ); bloc.setPredefinedMessage( id: 'predefined', clearAt: clearAt, @@ -254,7 +257,10 @@ void main() { }); test('Set custom message', () async { - final clearAt = DateTime.timestamp().copyWith(millisecond: 0, microsecond: 0).add(const Duration(hours: 1)); + final clearAt = tz.TZDateTime.from( + DateTime.timestamp().copyWith(millisecond: 0, microsecond: 0).add(const Duration(hours: 1)), + tz.UTC, + ); bloc.setCustomMessage( message: 'message', icon: 'icon', @@ -274,7 +280,10 @@ void main() { }); test('Clear message', () async { - final clearAt = DateTime.timestamp().copyWith(millisecond: 0, microsecond: 0).add(const Duration(hours: 1)); + final clearAt = tz.TZDateTime.from( + DateTime.timestamp().copyWith(millisecond: 0, microsecond: 0).add(const Duration(hours: 1)), + tz.UTC, + ); bloc ..setCustomMessage( message: 'message', diff --git a/packages/neon_framework/test/user_status_clear_at_test.dart b/packages/neon_framework/test/user_status_clear_at_test.dart index 3d5f29fb81f..02c202a7341 100644 --- a/packages/neon_framework/test/user_status_clear_at_test.dart +++ b/packages/neon_framework/test/user_status_clear_at_test.dart @@ -2,6 +2,7 @@ import 'package:flutter_test/flutter_test.dart'; import 'package:neon_framework/l10n/localizations_en.dart'; import 'package:neon_framework/src/utils/user_status_clear_at.dart'; import 'package:nextcloud/user_status.dart' as user_status; +import 'package:timezone/timezone.dart' as tz; void main() { final localizations = NeonLocalizationsEn(); @@ -41,7 +42,7 @@ void main() { test('To DateTime', () { for (final entry in clearAts.entries) { - expect(entry.key.toDateTime(DateTime.utc(2024)), entry.value.$2); + expect(entry.key.toDateTime(tz.TZDateTime.utc(2024)), entry.value.$2); } }); }