diff --git a/lib/app/modules/detailRoute/views/dateTimePicker.dart b/lib/app/modules/detailRoute/views/dateTimePicker.dart index 944c5c7a..b6188276 100644 --- a/lib/app/modules/detailRoute/views/dateTimePicker.dart +++ b/lib/app/modules/detailRoute/views/dateTimePicker.dart @@ -155,6 +155,14 @@ class DateTimeWidget extends StatelessWidget { var time = await showTimePicker( context: context, initialTime: TimeOfDay.now(), + builder: (BuildContext context, Widget? child) { + return MediaQuery( + data: MediaQuery.of(context).copyWith( + alwaysUse24HourFormat: AppSettings.use24HourFormatRx.value, + ), + child: child!, + ); + }, ); if (time != null) { var dateTime = date.add( diff --git a/lib/app/modules/detailRoute/views/detail_route_view.dart b/lib/app/modules/detailRoute/views/detail_route_view.dart index 478da44f..217dcbd7 100644 --- a/lib/app/modules/detailRoute/views/detail_route_view.dart +++ b/lib/app/modules/detailRoute/views/detail_route_view.dart @@ -249,7 +249,10 @@ class AttributeWidget extends StatelessWidget { @override Widget build(BuildContext context) { var localValue = (value is DateTime) - ? DateFormat.yMEd().add_jms().format(value.toLocal()) + ? DateFormat(AppSettings.use24HourFormatRx.value + ? 'EEE, yyyy-MM-dd HH:mm:ss' + : 'EEE, yyyy-MM-dd hh:mm:ss a') + .format(value.toLocal()) : ((value is BuiltList) ? (value).toBuilder() : value); switch (name) { diff --git a/lib/app/modules/home/controllers/home_controller.dart b/lib/app/modules/home/controllers/home_controller.dart index 32df5896..84f8ae9b 100644 --- a/lib/app/modules/home/controllers/home_controller.dart +++ b/lib/app/modules/home/controllers/home_controller.dart @@ -79,6 +79,12 @@ class HomeController extends GetxController { handleHomeWidgetClicked(); } fetchTasksFromDB(); + + ever(AppSettings.use24HourFormatRx, (_) { + _refreshTasks(); + update(); + }); + everAll([ pendingFilter, waitingFilter, @@ -499,7 +505,6 @@ class HomeController extends GetxController { RxBool syncOnStart = false.obs; RxBool syncOnTaskCreate = false.obs; RxBool delaytask = false.obs; - RxBool change24hr = false.obs; RxBool taskchampion = false.obs; // dialogue box diff --git a/lib/app/modules/home/views/add_task_bottom_sheet.dart b/lib/app/modules/home/views/add_task_bottom_sheet.dart index 73d4f5d0..4113bf5a 100644 --- a/lib/app/modules/home/views/add_task_bottom_sheet.dart +++ b/lib/app/modules/home/views/add_task_bottom_sheet.dart @@ -250,7 +250,7 @@ class AddTaskBottomSheet extends StatelessWidget { }, fieldHintText: "Month/Date/Year", context: context, - initialDate: homeController.due.value?? DateTime.now(), + initialDate: homeController.due.value ?? DateTime.now(), firstDate: DateTime.now(), lastDate: DateTime(2037, 12, 31), ); @@ -287,7 +287,7 @@ class AddTaskBottomSheet extends StatelessWidget { child: Obx(() => MediaQuery( data: MediaQuery.of(context).copyWith( alwaysUse24HourFormat: - homeController.change24hr.value, + AppSettings.use24HourFormatRx.value, ), child: child!)), ); @@ -308,8 +308,11 @@ class AddTaskBottomSheet extends StatelessWidget { homeController.due.value = dateTime; // print("due value ${homeController.due}"); + String timeFormat = AppSettings.use24HourFormatRx.value + ? 'dd-MM-yyyy HH:mm' + : 'dd-MM-yyyy hh:mm a'; homeController.dueString.value = - DateFormat("dd-MM-yyyy HH:mm").format(dateTime); + DateFormat(timeFormat).format(dateTime); // print(homeController.dueString.value); if (dateTime.isBefore(DateTime.now())) { //Try changing the color. in the settings and Due display. @@ -355,10 +358,7 @@ class AddTaskBottomSheet extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.center, children: [ Text( - "${SentenceManager( - currentLanguage: homeController.selectedLanguage.value) - .sentences - .addTaskPriority} :", + "${SentenceManager(currentLanguage: homeController.selectedLanguage.value).sentences.addTaskPriority} :", style: GoogleFonts.poppins( fontWeight: TaskWarriorFonts.bold, color: AppSettings.isDarkMode @@ -367,16 +367,19 @@ class AddTaskBottomSheet extends StatelessWidget { ), textAlign: TextAlign.left, ), - const SizedBox(width: 2,), + const SizedBox( + width: 2, + ), Obx( () => Row( children: [ - for(int i=0;i tags = trimmedString.split(" "); - for(tag in tags){ - if(checkTagIfExists(tag)) { + for (tag in tags) { + if (checkTagIfExists(tag)) { removeTag(tag); } homeController.tags.add(tag); @@ -576,9 +577,11 @@ class AddTaskBottomSheet extends StatelessWidget { homeController.tagcontroller.text = ''; } } - bool checkTagIfExists(String tag){ + + bool checkTagIfExists(String tag) { return homeController.tags.contains(tag); } + void removeTag(String tag) { homeController.tags.remove(tag); } diff --git a/lib/app/modules/home/views/add_task_to_taskc_bottom_sheet.dart b/lib/app/modules/home/views/add_task_to_taskc_bottom_sheet.dart index ae29a077..50dfe23b 100644 --- a/lib/app/modules/home/views/add_task_to_taskc_bottom_sheet.dart +++ b/lib/app/modules/home/views/add_task_to_taskc_bottom_sheet.dart @@ -217,7 +217,7 @@ class AddTaskToTaskcBottomSheet extends StatelessWidget { child: MediaQuery( data: MediaQuery.of(context).copyWith( alwaysUse24HourFormat: - homeController.change24hr.value, + AppSettings.use24HourFormatRx.value, ), child: child!), ); @@ -234,8 +234,11 @@ class AddTaskToTaskcBottomSheet extends StatelessWidget { ), ); homeController.due.value = dateTime.toUtc(); + String timeFormat = AppSettings.use24HourFormatRx.value + ? 'yyyy-MM-dd HH:mm' + : 'yyyy-MM-dd hh:mm a'; homeController.dueString.value = - DateFormat("yyyy-MM-dd").format(dateTime); + DateFormat(timeFormat).format(dateTime); if (dateTime.isBefore(DateTime.now())) { homeController.inThePast.value = true; diff --git a/lib/app/modules/home/views/nav_drawer.dart b/lib/app/modules/home/views/nav_drawer.dart index 0a3d36dc..cd99f735 100644 --- a/lib/app/modules/home/views/nav_drawer.dart +++ b/lib/app/modules/home/views/nav_drawer.dart @@ -238,8 +238,6 @@ class NavDrawer extends StatelessWidget { prefs.getBool('sync-OnTaskCreate') ?? false; homeController.delaytask.value = prefs.getBool('delaytask') ?? false; - homeController.change24hr.value = - prefs.getBool('24hourformate') ?? false; Get.toNamed(Routes.SETTINGS); }, diff --git a/lib/app/modules/home/views/show_details.dart b/lib/app/modules/home/views/show_details.dart index b85daeb2..4bfbef9b 100644 --- a/lib/app/modules/home/views/show_details.dart +++ b/lib/app/modules/home/views/show_details.dart @@ -360,7 +360,10 @@ class _TaskDetailsState extends State { try { DateTime parsedDate = DateTime.parse(dateString); - return DateFormat('yyyy-MM-dd HH:mm:ss').format(parsedDate); + String timeFormat = AppSettings.use24HourFormatRx.value + ? 'yyyy-MM-dd HH:mm:ss' + : 'yyyy-MM-dd hh:mm:ss a'; + return DateFormat(timeFormat).format(parsedDate); } catch (e) { debugPrint('Error parsing date: $dateString'); return '-'; diff --git a/lib/app/modules/settings/controllers/settings_controller.dart b/lib/app/modules/settings/controllers/settings_controller.dart index 15987b3e..df848b10 100644 --- a/lib/app/modules/settings/controllers/settings_controller.dart +++ b/lib/app/modules/settings/controllers/settings_controller.dart @@ -165,7 +165,6 @@ class SettingsController extends GetxController { RxBool isSyncOnStartActivel = false.obs; RxBool isSyncOnTaskCreateActivel = false.obs; RxBool delaytask = false.obs; - RxBool change24hr = false.obs; RxBool taskchampion = false.obs; RxBool isDarkModeOn = false.obs; @@ -180,7 +179,6 @@ class SettingsController extends GetxController { isSyncOnTaskCreateActivel.value = prefs.getBool('sync-OnTaskCreate') ?? false; delaytask.value = prefs.getBool('delaytask') ?? false; - change24hr.value = prefs.getBool('24hourformate') ?? false; taskchampion.value = prefs.getBool('taskc') ?? false; initDarkMode(); baseDirectory.value = await getBaseDirectory(); diff --git a/lib/app/modules/settings/views/settings_page_enable_24hr_format_list_tile_trailing.dart b/lib/app/modules/settings/views/settings_page_enable_24hr_format_list_tile_trailing.dart index 19b44a58..6f54e321 100644 --- a/lib/app/modules/settings/views/settings_page_enable_24hr_format_list_tile_trailing.dart +++ b/lib/app/modules/settings/views/settings_page_enable_24hr_format_list_tile_trailing.dart @@ -1,12 +1,10 @@ import 'package:flutter/material.dart'; import 'package:get/get.dart'; -import 'package:shared_preferences/shared_preferences.dart'; -import 'package:taskwarrior/app/modules/home/controllers/home_controller.dart'; +import 'package:taskwarrior/app/utils/app_settings/app_settings.dart'; import '../controllers/settings_controller.dart'; - class SettingsPageEnable24hrFormatListTileTrailing extends StatelessWidget { final SettingsController controller; const SettingsPageEnable24hrFormatListTileTrailing( @@ -16,13 +14,14 @@ class SettingsPageEnable24hrFormatListTileTrailing extends StatelessWidget { Widget build(BuildContext context) { return Obx( () => Switch( - value: controller.change24hr.value, + value: AppSettings.use24HourFormatRx.value, onChanged: (bool value) async { - controller.change24hr.value = value; - - final SharedPreferences prefs = await SharedPreferences.getInstance(); - await prefs.setBool('24hourformate', value); - Get.find().change24hr.value = value; + AppSettings.use24HourFormatRx.value = value; + AppSettings.saveSettings( + AppSettings.isDarkMode, + AppSettings.selectedLanguage, + value, + ); }, ), ); diff --git a/lib/app/services/notification_services.dart b/lib/app/services/notification_services.dart index 1b6c8a9b..9a24c7fc 100644 --- a/lib/app/services/notification_services.dart +++ b/lib/app/services/notification_services.dart @@ -7,6 +7,8 @@ import 'package:flutter/foundation.dart'; import 'package:flutter_local_notifications/flutter_local_notifications.dart'; import 'package:timezone/data/latest.dart' as tz; import 'package:timezone/timezone.dart' as tz; +import 'package:intl/intl.dart'; +import 'package:taskwarrior/app/utils/app_settings/app_settings.dart'; class NotificationService { final FlutterLocalNotificationsPlugin _flutterLocalNotificationsPlugin = @@ -53,13 +55,21 @@ class NotificationService { return notificationId; } + // Helper method to format date time based on user preferences + String getFormattedDateTime(DateTime dateTime) { + String timeFormat = AppSettings.use24HourFormatRx.value + ? 'yyyy-MM-dd HH:mm:ss' + : 'yyyy-MM-dd hh:mm:ss a'; + return DateFormat(timeFormat).format(dateTime); + } + void sendNotification( DateTime dtb, String taskname, bool isWait, DateTime entryTime) async { DateTime dateTime = DateTime.now(); tz.initializeTimeZones(); if (kDebugMode) { print("date and time are:-$dateTime"); - print("date and time are:-$dtb"); + print("date and time are:-${getFormattedDateTime(dtb)}"); } final tz.TZDateTime scheduledAt = tz.TZDateTime.from(dtb.add(const Duration(minutes: 0)), tz.local); diff --git a/lib/app/utils/app_settings/app_settings.dart b/lib/app/utils/app_settings/app_settings.dart index ce37244f..fb46c7b5 100644 --- a/lib/app/utils/app_settings/app_settings.dart +++ b/lib/app/utils/app_settings/app_settings.dart @@ -1,27 +1,33 @@ +import 'package:get/get.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:taskwarrior/app/utils/language/supported_language.dart'; part 'save_tour_status.dart'; part 'selected_theme.dart'; part 'selected_language.dart'; +part 'selected_time_format.dart'; class AppSettings { static bool isDarkMode = true; static SupportedLanguage selectedLanguage = SupportedLanguage.english; + static final RxBool use24HourFormatRx = false.obs; static Future init() async { await SelectedTheme.init(); await SelectedLanguage.init(); await SaveTourStatus.init(); + await SelectedTimeFormat.init(); isDarkMode = SelectedTheme.getMode() ?? true; selectedLanguage = SelectedLanguage.getSelectedLanguage() ?? SupportedLanguage.english; + use24HourFormatRx.value = SelectedTimeFormat.getTimeFormat() ?? false; } static Future saveSettings( - bool isDarkMode, SupportedLanguage language) async { + bool isDarkMode, SupportedLanguage language, bool use24hour) async { await SelectedTheme.saveMode(isDarkMode); await SelectedLanguage.saveSelectedLanguage(language); + await SelectedTimeFormat.saveTimeFormat(use24hour); } } diff --git a/lib/app/utils/app_settings/selected_time_format.dart b/lib/app/utils/app_settings/selected_time_format.dart new file mode 100644 index 00000000..79d2700d --- /dev/null +++ b/lib/app/utils/app_settings/selected_time_format.dart @@ -0,0 +1,17 @@ +part of 'app_settings.dart'; + +class SelectedTimeFormat { + static SharedPreferences? _preferences; + + static Future init() async { + _preferences = await SharedPreferences.getInstance(); + } + + static Future saveTimeFormat(bool mode) async { + await _preferences?.setBool('24hourformate', mode); + } + + static bool? getTimeFormat() { + return _preferences?.getBool('24hourformate'); + } +} diff --git a/lib/app/utils/taskfunctions/datetime_differences.dart b/lib/app/utils/taskfunctions/datetime_differences.dart index 94b4aeb9..41586ced 100644 --- a/lib/app/utils/taskfunctions/datetime_differences.dart +++ b/lib/app/utils/taskfunctions/datetime_differences.dart @@ -1,10 +1,11 @@ -String age(DateTime dt) => difference(DateTime.now().difference(dt)); +import 'package:intl/intl.dart'; +import 'package:taskwarrior/app/utils/app_settings/app_settings.dart'; -String when(DateTime dt) => difference(dt.difference(DateTime.now())); +String age(DateTime dt, {bool? use24HourFormat}) { + final format = AppSettings.use24HourFormatRx.value; -String difference(Duration difference) { String result; - var days = difference.abs().inDays; + var days = DateTime.now().difference(dt).abs().inDays; if (days > 365) { result = '${(days / 365).toStringAsFixed(1).replaceFirst(RegExp(r'\.0$'), '')}y'; @@ -14,12 +15,46 @@ String difference(Duration difference) { result = '${days ~/ 7}w'; } else if (days > 0) { result = '${days}d'; - } else if (difference.abs().inHours > 0) { - result = '${difference.abs().inHours}h'; - } else if (difference.abs().inMinutes > 0) { - result = '${difference.abs().inMinutes}min'; + } else if (DateTime.now().difference(dt).abs().inHours > 0) { + result = '${DateTime.now().difference(dt).abs().inHours}h'; + } else if (DateTime.now().difference(dt).abs().inMinutes > 0) { + result = '${DateTime.now().difference(dt).abs().inMinutes}min'; } else { - result = '${difference.abs().inSeconds}s'; + result = '${DateTime.now().difference(dt).abs().inSeconds}s'; } - return '$result ${(difference.isNegative) ? 'ago ' : ''}'; + + // Format the time part according to the format preference + String timeFormat = format ? 'HH:mm' : 'hh:mm a'; + String formattedTime = DateFormat(timeFormat).format(dt); + + return '$result ago ($formattedTime)'; +} + +String when(DateTime dt, {bool? use24HourFormat}) { + final format = AppSettings.use24HourFormatRx.value; + + String result; + var days = dt.difference(DateTime.now()).abs().inDays; + if (days > 365) { + result = + '${(days / 365).toStringAsFixed(1).replaceFirst(RegExp(r'\.0$'), '')}y'; + } else if (days > 30) { + result = '${days ~/ 30}mo'; + } else if (days > 7) { + result = '${days ~/ 7}w'; + } else if (days > 0) { + result = '${days}d'; + } else if (dt.difference(DateTime.now()).abs().inHours > 0) { + result = '${dt.difference(DateTime.now()).abs().inHours}h'; + } else if (dt.difference(DateTime.now()).abs().inMinutes > 0) { + result = '${dt.difference(DateTime.now()).abs().inMinutes}min'; + } else { + result = '${dt.difference(DateTime.now()).abs().inSeconds}s'; + } + + // Format the time part according to the format preference + String timeFormat = format ? 'HH:mm' : 'hh:mm a'; + String formattedTime = DateFormat(timeFormat).format(dt); + + return '$result ($formattedTime)'; } diff --git a/pubspec.lock b/pubspec.lock index 73a98954..848dcad2 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1045,10 +1045,10 @@ packages: dependency: "direct main" description: name: shared_preferences - sha256: "846849e3e9b68f3ef4b60c60cf4b3e02e9321bc7f4d8c4692cf87ffa82fc8a3a" + sha256: "6e8bf70b7fef813df4e9a36f658ac46d107db4b4cfe1048b477d4e453a8159f5" url: "https://pub.dev" source: hosted - version: "2.5.2" + version: "2.5.3" shared_preferences_android: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 0ba71a2f..f3d55bbe 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -51,7 +51,7 @@ dependencies: package_info_plus: ^8.3.0 pem: ^2.0.1 permission_handler: ^11.4.0 - shared_preferences: ^2.2.2 + shared_preferences: ^2.5.3 shared_preferences_web: ^2.0.3 sizer: ^3.0.5 sqflite: ^2.3.3+1 @@ -61,7 +61,7 @@ dependencies: timezone: ^0.10.0 tuple: ^2.0.0 tutorial_coach_mark: ^1.2.11 - url_launcher: ^6.1.14 + url_launcher: ^6.3.1 uuid: ^4.2.2 built_collection: ^5.1.1 path_provider: ^2.1.5 diff --git a/test/taskfunctions/datetime_differences_test.dart b/test/taskfunctions/datetime_differences_test.dart index 434771e9..fcf639d5 100644 --- a/test/taskfunctions/datetime_differences_test.dart +++ b/test/taskfunctions/datetime_differences_test.dart @@ -62,35 +62,5 @@ void main() { result = when(dt); expect(result, contains('29s')); }); - - test('Test difference function', () { - DateTime dt = DateTime.now().subtract(const Duration(days: 365)); - String result = difference(DateTime.now().difference(dt)); - expect(result, contains('12mo ')); - - dt = DateTime.now().subtract(const Duration(days: 60)); - result = difference(DateTime.now().difference(dt)); - expect(result, contains('2mo ')); - - dt = DateTime.now().subtract(const Duration(days: 21)); - result = difference(DateTime.now().difference(dt)); - expect(result, contains('3w ')); - - dt = DateTime.now().subtract(const Duration(days: 4)); - result = difference(DateTime.now().difference(dt)); - expect(result, contains('4d ')); - - dt = DateTime.now().subtract(const Duration(hours: 5)); - result = difference(DateTime.now().difference(dt)); - expect(result, contains('5h ')); - - dt = DateTime.now().subtract(const Duration(minutes: 10)); - result = difference(DateTime.now().difference(dt)); - expect(result, contains('10min ')); - - dt = DateTime.now().subtract(const Duration(seconds: 30)); - result = difference(DateTime.now().difference(dt)); - expect(result, contains('30s ')); - }); }); } diff --git a/test/utils/app_settings/app_settings_test.dart b/test/utils/app_settings/app_settings_test.dart index 592de7a1..6e62b267 100644 --- a/test/utils/app_settings/app_settings_test.dart +++ b/test/utils/app_settings/app_settings_test.dart @@ -13,12 +13,15 @@ void main() { test('should initialize settings correctly', () async { expect(AppSettings.isDarkMode, true); expect(AppSettings.selectedLanguage, SupportedLanguage.english); + expect(AppSettings.use24HourFormatRx.value, false); }); test('should save settings correctly', () async { - await AppSettings.saveSettings(false, SupportedLanguage.english); + await AppSettings.saveSettings(true, SupportedLanguage.english, true); + await AppSettings.init(); expect(AppSettings.isDarkMode, true); expect(AppSettings.selectedLanguage, SupportedLanguage.english); + expect(AppSettings.use24HourFormatRx.value, true); }); }); diff --git a/test/utils/app_settings/selected_time_format_test.dart b/test/utils/app_settings/selected_time_format_test.dart new file mode 100644 index 00000000..c5bd8e8a --- /dev/null +++ b/test/utils/app_settings/selected_time_format_test.dart @@ -0,0 +1,34 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:shared_preferences/shared_preferences.dart'; +import 'package:taskwarrior/app/utils/app_settings/app_settings.dart'; + +void main() { + TestWidgetsFlutterBinding.ensureInitialized(); + + setUp(() async { + SharedPreferences.setMockInitialValues({}); + await AppSettings.init(); + }); + + test('should save and retrieve time format setting', () async { + // Initially should be false (12-hour format) + expect(AppSettings.use24HourFormatRx.value, false); + + // Set to true (24-hour format) + await SelectedTimeFormat.saveTimeFormat(true); + expect(SelectedTimeFormat.getTimeFormat(), true); + + // Set back to false (12-hour format) + await SelectedTimeFormat.saveTimeFormat(false); + expect(SelectedTimeFormat.getTimeFormat(), false); + }); + + test('AppSettings should initialize with the stored time format', () async { + // Set format to true (24-hour) + await SelectedTimeFormat.saveTimeFormat(true); + + // Re-initialize and check + await AppSettings.init(); + expect(AppSettings.use24HourFormatRx.value, true); + }); +} diff --git a/test/utils/taskfunctions/datetime_differences_test.dart b/test/utils/taskfunctions/datetime_differences_test.dart index 9e47a0c0..0395a526 100644 --- a/test/utils/taskfunctions/datetime_differences_test.dart +++ b/test/utils/taskfunctions/datetime_differences_test.dart @@ -1,7 +1,13 @@ import 'package:flutter_test/flutter_test.dart'; +import 'package:get/get.dart'; +import 'package:taskwarrior/app/utils/app_settings/app_settings.dart'; import 'package:taskwarrior/app/utils/taskfunctions/datetime_differences.dart'; void main() { + setUp(() { + AppSettings.use24HourFormatRx.value = false; + }); + group('DateTime Differences', () { test('age function should return correct string for years', () { final now = DateTime.now(); @@ -45,12 +51,42 @@ void main() { expect(age(dt), '2s '); }); + test('age function should respect use24HourFormat app setting', () { + final now = DateTime.now(); + final dt = now.subtract(const Duration(days: 2)); // 2 days + + // Test with 12-hour format + AppSettings.use24HourFormatRx.value = false; + expect(age(dt), contains('2d')); + expect(age(dt), contains('(hh:mm a)')); + + // Test with 24-hour format + AppSettings.use24HourFormatRx.value = true; + expect(age(dt), contains('2d')); + expect(age(dt), contains('(HH:mm)')); + }); + test('when function should return correct string for future dates', () { final now = DateTime.now(); final dt = now.add(const Duration(days: 2)); // 2 days from now expect(when(dt), '1d '); }); + test('when function should respect use24HourFormat app setting', () { + final now = DateTime.now(); + final dt = now.add(const Duration(days: 2)); // 2 days from now + + // Test with 12-hour format + AppSettings.use24HourFormatRx.value = false; + expect(when(dt), contains('1d')); + expect(when(dt), contains('(hh:mm a)')); + + // Test with 24-hour format + AppSettings.use24HourFormatRx.value = true; + expect(when(dt), contains('1d')); + expect(when(dt), contains('(HH:mm)')); + }); + test( 'difference function should return correct string for various durations', () { diff --git a/test/utils/taskfunctions/datetime_format_test.dart b/test/utils/taskfunctions/datetime_format_test.dart new file mode 100644 index 00000000..029b4a68 --- /dev/null +++ b/test/utils/taskfunctions/datetime_format_test.dart @@ -0,0 +1,57 @@ +import 'package:flutter_test/flutter_test.dart'; +import 'package:intl/intl.dart'; +import 'package:taskwarrior/app/utils/app_settings/app_settings.dart'; +import 'package:get/get.dart'; + +void main() { + setUp(() { + AppSettings.use24HourFormatRx.value = false; + }); + + test('DateFormat should respect 24-hour format setting', () { + // Test date: May 15, 2023, 2:30 PM / 14:30 + final dateTime = DateTime(2023, 5, 15, 14, 30); + + // Test with 12-hour format + AppSettings.use24HourFormatRx.value = false; + final format12h = DateFormat(AppSettings.use24HourFormatRx.value + ? 'yyyy-MM-dd HH:mm' + : 'yyyy-MM-dd hh:mm a'); + String formatted12h = format12h.format(dateTime); + expect(formatted12h, contains('02:30 PM')); + expect(formatted12h, isNot(contains('14:30'))); + + // Test with 24-hour format + AppSettings.use24HourFormatRx.value = true; + final format24h = DateFormat(AppSettings.use24HourFormatRx.value + ? 'yyyy-MM-dd HH:mm' + : 'yyyy-MM-dd hh:mm a'); + String formatted24h = format24h.format(dateTime); + expect(formatted24h, contains('14:30')); + expect(formatted24h, isNot(contains('PM'))); + expect(formatted24h, isNot(contains('AM'))); + }); + + test('DateTime formatting in detail view should respect 24-hour format', () { + // Test date: May 15, 2023, 2:30 PM / 14:30 + final dateTime = DateTime(2023, 5, 15, 14, 30); + + // Test with 12-hour format + AppSettings.use24HourFormatRx.value = false; + final format12h = DateFormat(AppSettings.use24HourFormatRx.value + ? 'EEE, yyyy-MM-dd HH:mm:ss' + : 'EEE, yyyy-MM-dd hh:mm:ss a'); + String formatted12h = format12h.format(dateTime); + expect(formatted12h, contains('02:30:00 PM')); + expect(formatted12h, isNot(contains('14:30:00'))); + + // Test with 24-hour format + AppSettings.use24HourFormatRx.value = true; + final format24h = DateFormat(AppSettings.use24HourFormatRx.value + ? 'EEE, yyyy-MM-dd HH:mm:ss' + : 'EEE, yyyy-MM-dd hh:mm:ss a'); + String formatted24h = format24h.format(dateTime); + expect(formatted24h, contains('14:30:00')); + expect(formatted24h, isNot(contains('PM'))); + }); +}