diff --git a/lib/app/modules/alarmRing/views/alarm_ring_view.dart b/lib/app/modules/alarmRing/views/alarm_ring_view.dart index 56a84100..5db684e9 100644 --- a/lib/app/modules/alarmRing/views/alarm_ring_view.dart +++ b/lib/app/modules/alarmRing/views/alarm_ring_view.dart @@ -13,8 +13,7 @@ class AlarmControlView extends GetView { ThemeController themeController = Get.find(); - Obx getAddSnoozeButtons( - BuildContext context, int snoozeMinutes, String title) { + Obx getAddSnoozeButtons(BuildContext context, int snoozeMinutes, String title){ return Obx( () => TextButton( style: ButtonStyle( @@ -48,7 +47,6 @@ class AlarmControlView extends GetView { if (didPop) { return; } - Get.snackbar( 'Note'.tr, "You can't go back while the alarm is ringing".tr, @@ -82,10 +80,7 @@ class AlarmControlView extends GetView { : (controller.is24HourFormat.value) ? '${controller.timeNow24Hr}' : '${controller.timeNow[0]} ${controller.timeNow[1]}', - style: Theme.of(context) - .textTheme - .displayLarge! - .copyWith(fontSize: 50), + style: Theme.of(context).textTheme.displayLarge!.copyWith(fontSize: 50), ), const SizedBox( height: 20, @@ -224,29 +219,29 @@ class AlarmControlView extends GetView { ), ), ), - Positioned( - bottom: 0, - left: 0, - right: 0, - child: Container( - width: double.infinity, - height: 60, - color: Colors.red, - child: TextButton( - onPressed: () { - Utils.hapticFeedback(); - Get.offNamed('/bottom-navigation-bar'); - }, - child: Text( - 'Exit Preview'.tr, - style: Theme.of(context).textTheme.bodyLarge!.copyWith( - color: Colors.white, - fontWeight: FontWeight.bold, - ), - ), - ), - ), - ), + // Positioned( + // bottom: 0, + // left: 0, + // right: 0, + // child: Container( + // width: double.infinity, + // height: 60, + // color: Colors.red, + // child: TextButton( + // onPressed: () { + // Utils.hapticFeedback(); + // Get.offNamed('/bottom-navigation-bar'); + // }, + // child: Text( + // 'Exit Preview'.tr, + // style: Theme.of(context).textTheme.bodyLarge!.copyWith( + // color: Colors.white, + // fontWeight: FontWeight.bold, + // ), + // ), + // ), + // ), + // ), ], ), ), diff --git a/lib/app/modules/bottomNavigationBar/controllers/bottom_navigation_bar_controller.dart b/lib/app/modules/bottomNavigationBar/controllers/bottom_navigation_bar_controller.dart index ce4b548e..a25dba56 100644 --- a/lib/app/modules/bottomNavigationBar/controllers/bottom_navigation_bar_controller.dart +++ b/lib/app/modules/bottomNavigationBar/controllers/bottom_navigation_bar_controller.dart @@ -4,6 +4,7 @@ import 'package:ultimate_alarm_clock/app/data/providers/secure_storage_provider. import 'package:ultimate_alarm_clock/app/modules/home/views/home_view.dart'; import 'package:ultimate_alarm_clock/app/modules/stopwatch/views/stopwatch_view.dart'; import 'package:ultimate_alarm_clock/app/modules/timer/views/timer_view.dart'; +import 'package:ultimate_alarm_clock/app/modules/worldClockPage/views/world_clock_view.dart'; class BottomNavigationBarController extends GetxController with WidgetsBindingObserver { @@ -16,6 +17,7 @@ class BottomNavigationBarController extends GetxController HomeView(), StopwatchView(), TimerView(), + WorldClockView(), ]; @override @@ -46,6 +48,5 @@ class BottomNavigationBarController extends GetxController void changeTab(int index) { activeTabIndex.value = index; _saveState(); - } } diff --git a/lib/app/modules/bottomNavigationBar/views/bottom_navigation_bar_view.dart b/lib/app/modules/bottomNavigationBar/views/bottom_navigation_bar_view.dart index 05c8aaec..ba6e4bbc 100644 --- a/lib/app/modules/bottomNavigationBar/views/bottom_navigation_bar_view.dart +++ b/lib/app/modules/bottomNavigationBar/views/bottom_navigation_bar_view.dart @@ -27,7 +27,8 @@ class BottomNavigationBarView extends GetView { controller.changeTab(index); }, ); - } else { + } + else { return const Center( child: CircularProgressIndicator.adaptive( backgroundColor: Colors.transparent, @@ -45,29 +46,31 @@ class BottomNavigationBarView extends GetView { useLegacyColorScheme: false, items: [ BottomNavigationBarItem( - icon: const Icon(Icons.alarm), + icon: const Icon(Icons.alarm, size: 20), label: 'Alarm'.tr, ), BottomNavigationBarItem( - icon: const Icon(Icons.timer_outlined), + icon: const Icon(Icons.timer_outlined, size: 20), label: 'StopWatch'.tr, ), BottomNavigationBarItem( - icon: const Icon(Icons.timelapse_outlined), + icon: const Icon(Icons.timelapse_outlined, size: 20), label: 'Timer'.tr, ), + BottomNavigationBarItem( + icon: const Icon(Icons.more_time_outlined, size: 20), + label: 'WorldClock'.tr, + ), ], onTap: (index) { Utils.hapticFeedback(); controller.changeTab(index); - pageController.jumpToPage( - index, - ); + pageController.jumpToPage(index); }, currentIndex: controller.activeTabIndex.value, selectedLabelStyle: TextStyle( color: kprimaryColor, - fontSize: 14, + fontSize: 12, decorationColor: themeController.primaryBackgroundColor.value, decorationThickness: 0.8, diff --git a/lib/app/modules/citySelection/bindings/city_selection_binding.dart b/lib/app/modules/citySelection/bindings/city_selection_binding.dart new file mode 100644 index 00000000..73b180f3 --- /dev/null +++ b/lib/app/modules/citySelection/bindings/city_selection_binding.dart @@ -0,0 +1,17 @@ +import 'package:get/get.dart'; +import 'package:ultimate_alarm_clock/app/modules/bottomNavigationBar/controllers/bottom_navigation_bar_controller.dart'; +import 'package:ultimate_alarm_clock/app/modules/citySelection/controllers/city_selection_controller.dart'; + +class HomeBinding extends Bindings { + @override + void dependencies() { + Get.put( + CitySelectionController(), + ); + + + Get.lazyPut( + () => BottomNavigationBarController(), + ); + } +} diff --git a/lib/app/modules/citySelection/controllers/city_selection_controller.dart b/lib/app/modules/citySelection/controllers/city_selection_controller.dart new file mode 100644 index 00000000..9cbf0266 --- /dev/null +++ b/lib/app/modules/citySelection/controllers/city_selection_controller.dart @@ -0,0 +1,46 @@ +import 'package:get/get.dart'; +import 'package:flutter/material.dart'; +import 'package:ultimate_alarm_clock/app/utils/utils_world_gmt_data.dart'; +import 'package:ultimate_alarm_clock/app/utils/selected_cities.dart'; + +class CitySelectionController extends GetxController { + ScrollController scrollController = ScrollController(); + RxMap letterIndexMap = {}.obs; + RxString selectedLetter = "".obs; + + final List alphabet = [ + "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", + "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z" + ]; + + void scrollToLetter(String letter) { + if (letterIndexMap.containsKey(letter)) { + int index = letterIndexMap[letter]!; + scrollController.animateTo( + index * 60.0, + duration: Duration(milliseconds: 300), + curve: Curves.easeInOut, + ); + } + } + + void onCityTap(Map city) { + selectedCities.add(city); + Get.back(result: city); + } + + @override + void onInit() { + super.onInit(); + for (int i = 0; i < cities.length; i++) { + String letter = cities[i]['city']![0]; + letterIndexMap[letter] = letterIndexMap[letter] ?? i; + } + } + + @override + void onClose() { + scrollController.dispose(); + super.onClose(); + } +} diff --git a/lib/app/modules/citySelection/controllers/search_controller.dart b/lib/app/modules/citySelection/controllers/search_controller.dart new file mode 100644 index 00000000..ef9929ad --- /dev/null +++ b/lib/app/modules/citySelection/controllers/search_controller.dart @@ -0,0 +1,42 @@ +import 'package:get/get.dart'; +import 'package:flutter/material.dart'; +import 'package:ultimate_alarm_clock/app/utils/utils_world_gmt_data.dart'; +import 'package:ultimate_alarm_clock/app/utils/selected_cities.dart'; + +class SearchController extends GetxController { + RxBool showCancelIcon = false.obs; + RxList> filteredCities = >[].obs; + TextEditingController searchController = TextEditingController(); + + void searchKeyword(String query) { + query = query.toLowerCase(); + filteredCities.value = cities.where((city) { + return city['city']!.toLowerCase().contains(query) || + city['timezone']!.toLowerCase().contains(query) || + city['country']!.toLowerCase().contains(query); + }).toList(); + } + + void clearSearch() { + searchController.clear(); + filteredCities.clear(); // Clear the filtered cities list + } + + + void onCityTap(Map city) { + if (!selectedCities.contains(city)) { + selectedCities.add(city); + } + Get.back(result: city); + } + + void checkQueryEmptyOrNot(String text) { + showCancelIcon.value = text.isNotEmpty; + } + + @override + void onInit() { + super.onInit(); + filteredCities.value = []; + } +} diff --git a/lib/app/modules/citySelection/views/city_selection_view.dart b/lib/app/modules/citySelection/views/city_selection_view.dart new file mode 100644 index 00000000..7c7c5ca2 --- /dev/null +++ b/lib/app/modules/citySelection/views/city_selection_view.dart @@ -0,0 +1,88 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:ultimate_alarm_clock/app/modules/citySelection/controllers/city_selection_controller.dart'; +import 'package:ultimate_alarm_clock/app/modules/citySelection/views/search_view.dart'; +import 'package:ultimate_alarm_clock/app/modules/settings/controllers/theme_controller.dart'; +import 'package:ultimate_alarm_clock/app/utils/utils_world_gmt_data.dart'; + +class CitySelectionView extends StatelessWidget { + final CitySelectionController controller = Get.put(CitySelectionController()); + + @override + Widget build(BuildContext context) { + ThemeController themeController = Get.find(); + return Scaffold( + backgroundColor: Color(0xFF16171C), + appBar: AppBar( + backgroundColor: const Color(0xFF16171C), + iconTheme: const IconThemeData( + color: Color(0xffAFFC41), + ), + shadowColor: Colors.transparent, + ), + body: Padding( + padding: const EdgeInsets.all(10.0), + child: Column( + children: [ + const Text('Select City', + style: TextStyle( + color: Colors.white, + fontSize: 30, + fontWeight: FontWeight.bold, + ), + ), + const Text('Time zones', + style: TextStyle( + color: Colors.white, + fontSize: 20, + ), + ), + + const SizedBox(height: 20,), + + Container( + height: 60, + width: double.infinity, + child: TextField( + readOnly: true, + onTap: () => Get.to(() => SearchView()), + decoration: InputDecoration( + hintText: 'Search for country or city', + hintStyle: const TextStyle( + color: Colors.black38, + fontSize: 18, + ), + prefixIcon: const Icon(Icons.search, size: 30, color: Colors.black,), + filled: true, + fillColor: Colors.white, + border: OutlineInputBorder( + borderSide: BorderSide.none, + borderRadius: BorderRadius.circular(50.0), + ), + ), + ), + ), + + const SizedBox(height: 20,), + + Expanded( + child: ListView.builder( + controller: controller.scrollController, + itemCount: cities.length, + itemBuilder: (context, index) => ListTile( + onTap: () => controller.onCityTap(cities[index]), + title: Text(cities[index]['city']!, + style: const TextStyle( + color: Color(0xffAFFC41), + ), + ), + subtitle: Text(cities[index]['timezone']!), + ), + ), + ), + ], + ), + ), + ); + } +} \ No newline at end of file diff --git a/lib/app/modules/citySelection/views/search_view.dart b/lib/app/modules/citySelection/views/search_view.dart new file mode 100644 index 00000000..12a679bc --- /dev/null +++ b/lib/app/modules/citySelection/views/search_view.dart @@ -0,0 +1,97 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:ultimate_alarm_clock/app/modules/citySelection/controllers/search_controller.dart' as custom; + +class SearchView extends StatelessWidget { + final custom.SearchController controller = Get.put(custom.SearchController()); + + SearchView({super.key}); + + @override + Widget build(BuildContext context) { + return Scaffold( + backgroundColor: Color(0xFF16171C), + body: Padding( + padding: const EdgeInsets.only(top: 60.0, left: 20, right: 20), + child: Column( + children: [ + Container( + height: 50, + width: double.infinity, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: TextField( + controller: controller.searchController, + onChanged: controller.searchKeyword, + style: const TextStyle( + color: Colors.black, + ), + decoration: InputDecoration( + hintText: 'Country or City or Timezone', + prefixIcon: GestureDetector( + onTap: () { + controller.searchKeyword(controller.searchController.text); + }, + child: const Icon(Icons.search, size: 30, color: Colors.black), + ), + suffixIcon: GestureDetector( + onTap: () { + controller.clearSearch(); + }, + child: const Icon(Icons.cancel, size: 20, color: Colors.black), + ), + filled: true, + fillColor: Colors.white, + border: OutlineInputBorder( + borderSide: BorderSide.none, + borderRadius: BorderRadius.circular(30), + ), + contentPadding: const EdgeInsets.symmetric(vertical: 12), + ), + cursorColor: Colors.black87, + ), + ), + GestureDetector( + onTap: () { + Get.back(); + }, + child: const Padding( + padding: EdgeInsets.only(left: 10.0), + child: Text('Cancel', + style: TextStyle(color: Color(0xffAFFC41), fontSize: 20), + ), + ), + ) + ], + ), + ), + const SizedBox(height: 20), + + Expanded( + child: Obx(() { + return ListView.builder( + itemCount: controller.filteredCities.length, + itemBuilder: (context, index) { + final city = controller.filteredCities[index]; + return GestureDetector( + onTap: () { + controller.onCityTap(city); + Get.back(); + }, + child: ListTile( + title: Text(city['city']!), + subtitle: Text(city['timezone']!), + ), + ); + }, + ); + }), + ), + ], + ), + ), + ); + } +} diff --git a/lib/app/modules/timer/bindings/timer_binding.dart b/lib/app/modules/timer/bindings/timer_binding.dart index d3ae437d..c6203b67 100644 --- a/lib/app/modules/timer/bindings/timer_binding.dart +++ b/lib/app/modules/timer/bindings/timer_binding.dart @@ -7,7 +7,5 @@ class TimerBinding extends Bindings { Get.put( TimerController(), ); - - } } diff --git a/lib/app/modules/worldClockPage/bindings/world_clock_binding.dart b/lib/app/modules/worldClockPage/bindings/world_clock_binding.dart new file mode 100644 index 00000000..c51473b8 --- /dev/null +++ b/lib/app/modules/worldClockPage/bindings/world_clock_binding.dart @@ -0,0 +1,17 @@ +import 'package:get/get.dart'; +import 'package:ultimate_alarm_clock/app/modules/bottomNavigationBar/controllers/bottom_navigation_bar_controller.dart'; +import 'package:ultimate_alarm_clock/app/modules/worldClockPage/controllers/world_clock_controller.dart'; + +class HomeBinding extends Bindings { + @override + void dependencies() { + Get.put( + WorldClockController(), + ); + + + Get.lazyPut( + () => BottomNavigationBarController(), + ); + } +} diff --git a/lib/app/modules/worldClockPage/controllers/my_clocks_controller.dart b/lib/app/modules/worldClockPage/controllers/my_clocks_controller.dart new file mode 100644 index 00000000..3b16eb5a --- /dev/null +++ b/lib/app/modules/worldClockPage/controllers/my_clocks_controller.dart @@ -0,0 +1,46 @@ +import 'dart:async'; +import 'package:get/get.dart'; + +class MyClocksController extends GetxController { + var formattedTime = ''.obs; + var formattedDate = ''.obs; + var formattedDay = ''.obs; + Timer? timer; + + void updateTime(String timezone) { + _updateTimeForCity(timezone); + + timer?.cancel(); // Cancel existing timer before starting a new one + timer = Timer.periodic(const Duration(seconds: 1), (timer) { + _updateTimeForCity(timezone); + }); + } + + void _updateTimeForCity(String gmtOffset) { + DateTime now = DateTime.now().toUtc(); + RegExp regex = RegExp(r'GMT([+-]\d{2}):(\d{2})'); + Match? match = regex.firstMatch(gmtOffset); + + if (match != null) { + int hours = int.parse(match.group(1)!); + int minutes = int.parse(match.group(2)!); + DateTime cityTime = now.add(Duration(hours: hours, minutes: minutes)); + + formattedTime.value = '${cityTime.hour}:${cityTime.minute.toString().padLeft(2, '0')}:${cityTime.second}'; + formattedDate.value = '${cityTime.day}/${cityTime.month}/${cityTime.year}'; + formattedDay.value = + const ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', + 'Sunday'][cityTime.weekday - 1]; + } else { + formattedTime.value = 'Invalid Time'; + formattedDate.value = 'Invalid Date'; + formattedDay.value = 'Invalid Day'; + } + } + + @override + void onClose() { + timer?.cancel(); + super.onClose(); + } +} diff --git a/lib/app/modules/worldClockPage/controllers/world_clock_controller.dart b/lib/app/modules/worldClockPage/controllers/world_clock_controller.dart new file mode 100644 index 00000000..9f6d4bb0 --- /dev/null +++ b/lib/app/modules/worldClockPage/controllers/world_clock_controller.dart @@ -0,0 +1,39 @@ +import 'package:get/get.dart'; +import 'dart:async'; +import 'package:intl/intl.dart'; + +class WorldClockController extends GetxController { + RxList> selectedTimeZones = >[].obs; + RxString formattedTime = ''.obs; + RxString formattedDateNDay = ''.obs; + late Timer timer; + + @override + void onInit() { + super.onInit(); + selectedTimeZones.assignAll(selectedTimeZones); // Load initial cities + updateTime(); + timer = Timer.periodic(const Duration(seconds: 1), (timer) => updateTime()); + } + + void updateTime() { + formattedTime.value = DateFormat('hh:mm:ss a').format(DateTime.now()); + formattedDateNDay.value = DateFormat('dd/MM/yyyy').format(DateTime.now()); + } + + void addCity(Map city) { + if (!selectedTimeZones.contains(city)) { + selectedTimeZones.add(city); + } + } + + void removeCity(Map city) { + selectedTimeZones.remove(city); + } + + @override + void onClose() { + timer.cancel(); + super.onClose(); + } +} diff --git a/lib/app/modules/worldClockPage/views/my_clocks_view.dart b/lib/app/modules/worldClockPage/views/my_clocks_view.dart new file mode 100644 index 00000000..8706282d --- /dev/null +++ b/lib/app/modules/worldClockPage/views/my_clocks_view.dart @@ -0,0 +1,54 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:ultimate_alarm_clock/app/modules/worldClockPage/controllers/my_clocks_controller.dart'; +import 'package:ultimate_alarm_clock/app/utils/selected_cities.dart'; + +class MyClocksView extends StatelessWidget { + final Map clockDetails; + MyClocksView({Key? key, required this.clockDetails}) : super(key: key); + + final MyClocksController controller = Get.put(MyClocksController()); + + @override + Widget build(BuildContext context) { + controller.updateTime(clockDetails['timezone']!); + + return Obx(() => Padding( + padding: const EdgeInsets.only(top: 10, bottom: 2, left: 10, right: 10), + child: Container( + height: 100, + width: double.infinity, + decoration: BoxDecoration( + border: Border.all(width: 2, color: Colors.transparent), + color: const Color(0xffAFFC41), + borderRadius: BorderRadius.circular(30), + ), + child: GestureDetector( + onDoubleTap: () { + selectedCities.removeWhere((city) => city['city'] == clockDetails['city']); + // selectedCities.refresh(); + }, + child: ListTile( + title: Padding( + padding: const EdgeInsets.all(15.0), + child: Row( + children: [ + Text('${controller.formattedTime.value} | '), + Text(clockDetails['city']!), + ], + ), + ), + titleTextStyle: const TextStyle(fontSize: 25, color: Colors.black, fontWeight: FontWeight.bold), + subtitleTextStyle: const TextStyle(fontSize: 20, color: Colors.black, fontWeight: FontWeight.bold), + subtitle: Padding( + padding: const EdgeInsets.only(bottom: 10.0, left: 10.0), + child: Text( + '${controller.formattedDate.value} ${controller.formattedDay.value} | ${clockDetails['timezone']!}', + ), + ), + ), + ), + ), + ),); + } +} diff --git a/lib/app/modules/worldClockPage/views/world_clock_view.dart b/lib/app/modules/worldClockPage/views/world_clock_view.dart new file mode 100644 index 00000000..ba30050c --- /dev/null +++ b/lib/app/modules/worldClockPage/views/world_clock_view.dart @@ -0,0 +1,171 @@ +import 'package:flutter/material.dart'; +import 'package:get/get.dart'; +import 'package:ultimate_alarm_clock/app/modules/citySelection/views/city_selection_view.dart'; +import 'package:ultimate_alarm_clock/app/modules/settings/controllers/theme_controller.dart'; +import 'package:ultimate_alarm_clock/app/modules/worldClockPage/views/my_clocks_view.dart'; +import 'package:ultimate_alarm_clock/app/modules/worldClockPage/controllers/world_clock_controller.dart'; +import 'package:ultimate_alarm_clock/app/utils/utils.dart'; + +class WorldClockView extends StatelessWidget { + final WorldClockController controller = Get.put(WorldClockController()); + + @override + Widget build(BuildContext context) { + ThemeController themeController = Get.find(); + return Scaffold( + backgroundColor: const Color(0xFF16171C), + + body: Container( + color: const Color(0xFF16171C), + child: Padding( + padding: const EdgeInsets.all(10.0), + child: Column( + children: [ + Padding( + padding: const EdgeInsets.only(left: 5.0, right: 5.0, top: 50.0), + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + const Text('Clock', + style: TextStyle( + fontSize: 30, + fontWeight: FontWeight.bold + ), + ), + IconButton( + onPressed: () { + Utils.hapticFeedback(); + Scaffold.of(context).openEndDrawer(); + }, + icon: const Icon( + Icons.menu, + ), + color: themeController.primaryTextColor.value + .withOpacity(0.75), + iconSize: 27, + // splashRadius: 0.000001, + ), + ], + ), + ), + + const SizedBox(height: 30,), + + Obx(() => + Column( + children: [ + Text(controller.formattedTime.value, style: const TextStyle(fontSize: 30, fontWeight: FontWeight.bold),), + const SizedBox(height: 10,), + Text(controller.formattedDateNDay.value, style: const TextStyle(fontSize: 20, fontWeight: FontWeight.bold)), + ], + ), + ), + + const SizedBox(height: 30,), + + const Text('Long Press the custom clock to Delete it!', + style: TextStyle( + color: Color(0xffAFFC41), + ), + ), + + const SizedBox(height: 1,), + + Expanded( + child: Obx(() => controller.selectedTimeZones.isEmpty + ? const Expanded( + child: Column( + children: [ + const Icon(Icons.search_rounded, size: 400, color: Color(0xff71A7D9FF),), + Text('No Clocks', + style: TextStyle( + fontSize: 30, + ), + ), + ], + ), + ) + + : Expanded( + child: ListView.builder( + itemCount: controller.selectedTimeZones.length, + itemBuilder: (context, index) { + // return MyClocksView(selectedTimeZones: controller.selectedTimeZones[index]); + return MyClocksView(clockDetails: controller.selectedTimeZones[index],); + }, + ), + ), + ) + ), + ], + ), + ), + ), + + floatingActionButton: FloatingActionButton( + onPressed: () async { + final result = await Navigator.push(context, MaterialPageRoute(builder: (context) => CitySelectionView()), ); + + if(result != null) { + controller.addCity(result); + // print("City added: $result"); + } + }, + backgroundColor: Color(0xff6FBC00), + child: const Icon(Icons.add, color: Colors.black, size: 35,), + ), + ); + } +} + + + + + + + +// CODE TO DISPLAY AN ANALOG WATCH +// class ClockPainter extends CustomPainter { +// @override +// void paint(Canvas canvas, Size size) { +// final center = Offset(size.width / 2, size.height / 2); +// final radius = size.width / 2; +// +// final circlePaint = Paint() +// ..color = Colors.white +// ..style = PaintingStyle.fill; +// +// final handPaint = Paint() +// ..color = Colors.black +// ..strokeWidth = 4 +// ..strokeCap = StrokeCap.round; +// +// final secondHandPaint = Paint() +// ..color = Colors.red +// ..strokeWidth = 2 +// ..strokeCap = StrokeCap.round; +// +// canvas.drawCircle(center, radius, circlePaint); // Clock face +// +// final now = DateTime.now(); +// final hourAngle = (now.hour % 12) * 30 + (now.minute / 60) * 30; +// final minuteAngle = now.minute * 6; +// final secondAngle = now.second * 6; +// +// _drawHand(canvas, center, radius * 0.5, hourAngle, handPaint); +// _drawHand(canvas, center, radius * 0.7, minuteAngle.toDouble(), handPaint); +// _drawHand(canvas, center, radius * 0.9, secondAngle.toDouble(), secondHandPaint); +// } +// +// void _drawHand(Canvas canvas, Offset center, double length, double angle, Paint paint) { +// final angleRad = (angle - 90) * pi / 180; +// final handEnd = Offset( +// center.dx + length * cos(angleRad), +// center.dy + length * sin(angleRad), +// ); +// canvas.drawLine(center, handEnd, paint); +// } +// +// @override +// bool shouldRepaint(covariant CustomPainter oldDelegate) => true; +// } \ No newline at end of file diff --git a/lib/app/routes/app_pages.dart b/lib/app/routes/app_pages.dart index cb092b13..849a9530 100644 --- a/lib/app/routes/app_pages.dart +++ b/lib/app/routes/app_pages.dart @@ -1,5 +1,5 @@ import 'package:get/get.dart'; - +import 'package:ultimate_alarm_clock/app/modules/worldClockPage/views/world_clock_view.dart'; import '../modules/about/bindings/about_binding.dart'; import '../modules/about/views/about_view.dart'; import '../modules/addOrUpdateAlarm/bindings/add_or_update_alarm_binding.dart'; @@ -36,26 +36,31 @@ class AppPages { page: () => const SplashScreenView(), binding: SplashScreenBinding(), ), + GetPage( name: _Paths.HOME, page: () => HomeView(), binding: HomeBinding(), ), + GetPage( name: _Paths.ADD_OR_UPDATE_ALARM, page: () => AddOrUpdateAlarmView(), binding: AddOrUpdateAlarmBinding(), ), + GetPage( name: _Paths.ALARM_RING, page: () => AlarmControlView(), binding: AlarmControlBinding(), ), + GetPage( name: _Paths.SETTINGS, page: () => SettingsView(), binding: SettingsBinding(), ), + GetPage( name: _Paths.ALARM_CHALLENGE, page: () => AlarmChallengeView(), @@ -67,11 +72,13 @@ class AppPages { page: () => AboutView(), binding: AboutBinding(), ), + GetPage( name: _Paths.BOTTOM_NAVIGATION_BAR, page: () => BottomNavigationBarView(), binding: BottomNavigationBarBinding(), ), + GetPage( name: _Paths.TIMER_RING, page: () => TimerRingView(), @@ -83,10 +90,17 @@ class AppPages { page: () => StopwatchView(), binding: StopwatchBinding(), ), + GetPage( name: _Paths.NOTIFICATIONS, page: () => const NotificationsView(), binding: NotificationsBinding(), ), + + // GetPage( + // name: _Paths.WORLDCLOCK, + // page: () => const WorldClockView(), + // binding: WorldClockBinding(), + // ), ]; } diff --git a/lib/app/routes/app_routes.dart b/lib/app/routes/app_routes.dart index b245c308..6adb8137 100644 --- a/lib/app/routes/app_routes.dart +++ b/lib/app/routes/app_routes.dart @@ -11,8 +11,9 @@ abstract class Routes { static const ALARM_CHALLENGE = _Paths.ALARM_CHALLENGE; static const ABOUT = _Paths.ABOUT; static const BOTTOM_NAVIGATION_BAR = _Paths.BOTTOM_NAVIGATION_BAR; - static const TIMER_RING = _Paths.TIMER_RING; + static const TIMER_RING = _Paths. TIMER_RING; static const STOPWATCH = _Paths.STOPWATCH; + static const WORLDCLOCK = _Paths.WORLDCLOCK; static const ADD_OR_UPDATE_PROFILE = _Paths.ADD_OR_UPDATE_PROFILE; static const NOTIFICATIONS = _Paths.NOTIFICATIONS; } @@ -29,6 +30,7 @@ abstract class _Paths { static const BOTTOM_NAVIGATION_BAR = '/bottom-navigation-bar'; static const TIMER_RING = '/timer-ring'; static const STOPWATCH = '/stopwatch'; + static const WORLDCLOCK = '/world-clock'; static const ADD_OR_UPDATE_PROFILE = '/add-or-update-profile'; static const NOTIFICATIONS = '/notifications'; } diff --git a/lib/app/utils/selected_cities.dart b/lib/app/utils/selected_cities.dart new file mode 100644 index 00000000..396e41fd --- /dev/null +++ b/lib/app/utils/selected_cities.dart @@ -0,0 +1,4 @@ +import 'package:get/get.dart'; + +// Convert selectedCities into an observable list +RxList> selectedCities = >[].obs; diff --git a/lib/app/utils/utils_world_gmt_data.dart b/lib/app/utils/utils_world_gmt_data.dart new file mode 100644 index 00000000..68cbf1f5 --- /dev/null +++ b/lib/app/utils/utils_world_gmt_data.dart @@ -0,0 +1,598 @@ +List> cities = [ + {'city': 'Abidjan', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Accra', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Addis Ababa', 'country': 'Africa', 'timezone': 'GMT+03:00'}, + {'city': 'Algiers', 'country': 'Africa', 'timezone': 'GMT+01:00'}, + {'city': 'Asmara', 'country': 'Africa', 'timezone': 'GMT+03:00'}, + {'city': 'Asmera', 'country': 'Africa', 'timezone': 'GMT+03:00'}, + {'city': 'Bamako', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Bangui', 'country': 'Africa', 'timezone': 'GMT+01:00'}, + {'city': 'Banjul', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Bissau', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Blantyre', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Brazzaville', 'country': 'Africa', 'timezone': 'GMT+01:00'}, + {'city': 'Bujumbura', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Cairo', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Casablanca', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Ceuta', 'country': 'Africa', 'timezone': 'GMT+01:00'}, + {'city': 'Conakry', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Dakar', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Dar es Salaam', 'country': 'Africa', 'timezone': 'GMT+03:00'}, + {'city': 'Djibouti', 'country': 'Africa', 'timezone': 'GMT+03:00'}, + {'city': 'Douala', 'country': 'Africa', 'timezone': 'GMT+01:00'}, + {'city': 'El Aaiun', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Freetown', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Gaborone', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Harare', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Johannesburg', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Juba', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Kampala', 'country': 'Africa', 'timezone': 'GMT+03:00'}, + {'city': 'Khartoum', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Kigali', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Kinshasa', 'country': 'Africa', 'timezone': 'GMT+01:00'}, + {'city': 'Lagos', 'country': 'Africa', 'timezone': 'GMT+01:00'}, + {'city': 'Libreville', 'country': 'Africa', 'timezone': 'GMT+01:00'}, + {'city': 'Lome', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Luanda', 'country': 'Africa', 'timezone': 'GMT+01:00'}, + {'city': 'Lubumbashi', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Lusaka', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Malabo', 'country': 'Africa', 'timezone': 'GMT+01:00'}, + {'city': 'Maputo', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Maseru', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Mbabane', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Mogadishu', 'country': 'Africa', 'timezone': 'GMT+03:00'}, + {'city': 'Monrovia', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Nairobi', 'country': 'Africa', 'timezone': 'GMT+03:00'}, + {'city': 'Ndjamena', 'country': 'Africa', 'timezone': 'GMT+01:00'}, + {'city': 'Niamey', 'country': 'Africa', 'timezone': 'GMT+01:00'}, + {'city': 'Nouakchott', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Ouagadougou', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Porto-Novo', 'country': 'Africa', 'timezone': 'GMT+01:00'}, + {'city': 'Sao Tome', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Timbuktu', 'country': 'Africa', 'timezone': 'GMT+00:00'}, + {'city': 'Tripoli', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Tunis', 'country': 'Africa', 'timezone': 'GMT+01:00'}, + {'city': 'Windhoek', 'country': 'Africa', 'timezone': 'GMT+02:00'}, + {'city': 'Adak', 'country': 'America', 'timezone': 'GMT-09:00'}, + {'city': 'Anchorage', 'country': 'America', 'timezone': 'GMT-08:00'}, + {'city': 'Anguilla', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Antigua', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Araguaina', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'America/Argentina/Buenos Aires', 'country': 'Unknown', 'timezone': 'GMT-03:00'}, + {'city': 'America/Argentina/Catamarca', 'country': 'Unknown', 'timezone': 'GMT-03:00'}, + {'city': 'America/Argentina/ComodRivadavia', 'country': 'Unknown', 'timezone': 'GMT-03:00'}, + {'city': 'America/Argentina/Cordoba', 'country': 'Unknown', 'timezone': 'GMT-03:00'}, + {'city': 'America/Argentina/Jujuy', 'country': 'Unknown', 'timezone': 'GMT-03:00'}, + {'city': 'America/Argentina/La Rioja', 'country': 'Unknown', 'timezone': 'GMT-03:00'}, + {'city': 'America/Argentina/Mendoza', 'country': 'Unknown', 'timezone': 'GMT-03:00'}, + {'city': 'America/Argentina/Rio Gallegos', 'country': 'Unknown', 'timezone': 'GMT-03:00'}, + {'city': 'America/Argentina/Salta', 'country': 'Unknown', 'timezone': 'GMT-03:00'}, + {'city': 'America/Argentina/San Juan', 'country': 'Unknown', 'timezone': 'GMT-03:00'}, + {'city': 'America/Argentina/San Luis', 'country': 'Unknown', 'timezone': 'GMT-03:00'}, + {'city': 'America/Argentina/Tucuman', 'country': 'Unknown', 'timezone': 'GMT-03:00'}, + {'city': 'America/Argentina/Ushuaia', 'country': 'Unknown', 'timezone': 'GMT-03:00'}, + {'city': 'Aruba', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Asuncion', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Atikokan', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Atka', 'country': 'America', 'timezone': 'GMT-09:00'}, + {'city': 'Bahia', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Bahia Banderas', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Barbados', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Belem', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Belize', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Blanc-Sablon', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Boa Vista', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Bogota', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Boise', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Buenos Aires', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Cambridge Bay', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Campo Grande', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Cancun', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Caracas', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Catamarca', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Cayenne', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Cayman', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Chicago', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Chihuahua', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Ciudad Juarez', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Coral Harbour', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Cordoba', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Costa Rica', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Creston', 'country': 'America', 'timezone': 'GMT-07:00'}, + {'city': 'Cuiaba', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Curacao', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Danmarkshavn', 'country': 'America', 'timezone': 'GMT+00:00'}, + {'city': 'Dawson', 'country': 'America', 'timezone': 'GMT-07:00'}, + {'city': 'Dawson Creek', 'country': 'America', 'timezone': 'GMT-07:00'}, + {'city': 'Denver', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Detroit', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Dominica', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Edmonton', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Eirunepe', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'El Salvador', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Ensenada', 'country': 'America', 'timezone': 'GMT-07:00'}, + {'city': 'Fort Nelson', 'country': 'America', 'timezone': 'GMT-07:00'}, + {'city': 'Fort Wayne', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Fortaleza', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Glace Bay', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Godthab', 'country': 'America', 'timezone': 'GMT-02:00'}, + {'city': 'Goose Bay', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Grand Turk', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Grenada', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Guadeloupe', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Guatemala', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Guayaquil', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Guyana', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Halifax', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Havana', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Hermosillo', 'country': 'America', 'timezone': 'GMT-07:00'}, + {'city': 'America/Indiana/Indianapolis', 'country': 'Unknown', 'timezone': 'GMT-04:00'}, + {'city': 'America/Indiana/Knox', 'country': 'Unknown', 'timezone': 'GMT-05:00'}, + {'city': 'America/Indiana/Marengo', 'country': 'Unknown', 'timezone': 'GMT-04:00'}, + {'city': 'America/Indiana/Petersburg', 'country': 'Unknown', 'timezone': 'GMT-04:00'}, + {'city': 'America/Indiana/Tell City', 'country': 'Unknown', 'timezone': 'GMT-05:00'}, + {'city': 'America/Indiana/Vevay', 'country': 'Unknown', 'timezone': 'GMT-04:00'}, + {'city': 'America/Indiana/Vincennes', 'country': 'Unknown', 'timezone': 'GMT-04:00'}, + {'city': 'America/Indiana/Winamac', 'country': 'Unknown', 'timezone': 'GMT-04:00'}, + {'city': 'Indianapolis', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Inuvik', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Iqaluit', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Jamaica', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Jujuy', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Juneau', 'country': 'America', 'timezone': 'GMT-08:00'}, + {'city': 'America/Kentucky/Louisville', 'country': 'Unknown', 'timezone': 'GMT-04:00'}, + {'city': 'America/Kentucky/Monticello', 'country': 'Unknown', 'timezone': 'GMT-04:00'}, + {'city': 'Knox IN', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Kralendijk', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'La Paz', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Lima', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Los Angeles', 'country': 'America', 'timezone': 'GMT-07:00'}, + {'city': 'Louisville', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Lower Princes', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Maceio', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Managua', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Manaus', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Marigot', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Martinique', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Matamoros', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Mazatlan', 'country': 'America', 'timezone': 'GMT-07:00'}, + {'city': 'Mendoza', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Menominee', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Merida', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Metlakatla', 'country': 'America', 'timezone': 'GMT-08:00'}, + {'city': 'Mexico City', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Miquelon', 'country': 'America', 'timezone': 'GMT-02:00'}, + {'city': 'Moncton', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Monterrey', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Montevideo', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Montreal', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Montserrat', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Nassau', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'New York', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Nipigon', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Nome', 'country': 'America', 'timezone': 'GMT-08:00'}, + {'city': 'Noronha', 'country': 'America', 'timezone': 'GMT-02:00'}, + {'city': 'America/North Dakota/Beulah', 'country': 'Unknown', 'timezone': 'GMT-05:00'}, + {'city': 'America/North Dakota/Center', 'country': 'Unknown', 'timezone': 'GMT-05:00'}, + {'city': 'America/North Dakota/New Salem', 'country': 'Unknown', 'timezone': 'GMT-05:00'}, + {'city': 'Nuuk', 'country': 'America', 'timezone': 'GMT-02:00'}, + {'city': 'Ojinaga', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Panama', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Pangnirtung', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Paramaribo', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Phoenix', 'country': 'America', 'timezone': 'GMT-07:00'}, + {'city': 'Port-au-Prince', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Port of Spain', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Porto Acre', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Porto Velho', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Puerto Rico', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Punta Arenas', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Rainy River', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Rankin Inlet', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Recife', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Regina', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Resolute', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Rio Branco', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Rosario', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Santa Isabel', 'country': 'America', 'timezone': 'GMT-07:00'}, + {'city': 'Santarem', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Santiago', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Santo Domingo', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Sao Paulo', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Scoresbysund', 'country': 'America', 'timezone': 'GMT-02:00'}, + {'city': 'Shiprock', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Sitka', 'country': 'America', 'timezone': 'GMT-08:00'}, + {'city': 'St Barthelemy', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'St Johns', 'country': 'America', 'timezone': 'GMT-02:30'}, + {'city': 'St Kitts', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'St Lucia', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'St Thomas', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'St Vincent', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Swift Current', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Tegucigalpa', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Thule', 'country': 'America', 'timezone': 'GMT-03:00'}, + {'city': 'Thunder Bay', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Tijuana', 'country': 'America', 'timezone': 'GMT-07:00'}, + {'city': 'Toronto', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Tortola', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Vancouver', 'country': 'America', 'timezone': 'GMT-07:00'}, + {'city': 'Virgin', 'country': 'America', 'timezone': 'GMT-04:00'}, + {'city': 'Whitehorse', 'country': 'America', 'timezone': 'GMT-07:00'}, + {'city': 'Winnipeg', 'country': 'America', 'timezone': 'GMT-05:00'}, + {'city': 'Yakutat', 'country': 'America', 'timezone': 'GMT-08:00'}, + {'city': 'Yellowknife', 'country': 'America', 'timezone': 'GMT-06:00'}, + {'city': 'Casey', 'country': 'Antarctica', 'timezone': 'GMT+08:00'}, + {'city': 'Davis', 'country': 'Antarctica', 'timezone': 'GMT+07:00'}, + {'city': 'DumontDUrville', 'country': 'Antarctica', 'timezone': 'GMT+10:00'}, + {'city': 'Macquarie', 'country': 'Antarctica', 'timezone': 'GMT+11:00'}, + {'city': 'Mawson', 'country': 'Antarctica', 'timezone': 'GMT+05:00'}, + {'city': 'McMurdo', 'country': 'Antarctica', 'timezone': 'GMT+13:00'}, + {'city': 'Palmer', 'country': 'Antarctica', 'timezone': 'GMT-03:00'}, + {'city': 'Rothera', 'country': 'Antarctica', 'timezone': 'GMT-03:00'}, + {'city': 'South Pole', 'country': 'Antarctica', 'timezone': 'GMT+13:00'}, + {'city': 'Syowa', 'country': 'Antarctica', 'timezone': 'GMT+03:00'}, + {'city': 'Troll', 'country': 'Antarctica', 'timezone': 'GMT+00:00'}, + {'city': 'Vostok', 'country': 'Antarctica', 'timezone': 'GMT+05:00'}, + {'city': 'Longyearbyen', 'country': 'Arctic', 'timezone': 'GMT+01:00'}, + {'city': 'Aden', 'country': 'Asia', 'timezone': 'GMT+03:00'}, + {'city': 'Almaty', 'country': 'Asia', 'timezone': 'GMT+05:00'}, + {'city': 'Amman', 'country': 'Asia', 'timezone': 'GMT+03:00'}, + {'city': 'Anadyr', 'country': 'Asia', 'timezone': 'GMT+12:00'}, + {'city': 'Aqtau', 'country': 'Asia', 'timezone': 'GMT+05:00'}, + {'city': 'Aqtobe', 'country': 'Asia', 'timezone': 'GMT+05:00'}, + {'city': 'Ashgabat', 'country': 'Asia', 'timezone': 'GMT+05:00'}, + {'city': 'Ashkhabad', 'country': 'Asia', 'timezone': 'GMT+05:00'}, + {'city': 'Atyrau', 'country': 'Asia', 'timezone': 'GMT+05:00'}, + {'city': 'Baghdad', 'country': 'Asia', 'timezone': 'GMT+03:00'}, + {'city': 'Bahrain', 'country': 'Asia', 'timezone': 'GMT+03:00'}, + {'city': 'Baku', 'country': 'Asia', 'timezone': 'GMT+04:00'}, + {'city': 'Bangkok', 'country': 'Asia', 'timezone': 'GMT+07:00'}, + {'city': 'Barnaul', 'country': 'Asia', 'timezone': 'GMT+07:00'}, + {'city': 'Beirut', 'country': 'Asia', 'timezone': 'GMT+02:00'}, + {'city': 'Bishkek', 'country': 'Asia', 'timezone': 'GMT+06:00'}, + {'city': 'Brunei', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Calcutta', 'country': 'Asia', 'timezone': 'GMT+05:30'}, + {'city': 'Chita', 'country': 'Asia', 'timezone': 'GMT+09:00'}, + {'city': 'Choibalsan', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Chongqing', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Chungking', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Colombo', 'country': 'Asia', 'timezone': 'GMT+05:30'}, + {'city': 'Dacca', 'country': 'Asia', 'timezone': 'GMT+06:00'}, + {'city': 'Damascus', 'country': 'Asia', 'timezone': 'GMT+03:00'}, + {'city': 'Dhaka', 'country': 'Asia', 'timezone': 'GMT+06:00'}, + {'city': 'Dili', 'country': 'Asia', 'timezone': 'GMT+09:00'}, + {'city': 'Dubai', 'country': 'Asia', 'timezone': 'GMT+04:00'}, + {'city': 'Dushanbe', 'country': 'Asia', 'timezone': 'GMT+05:00'}, + {'city': 'Famagusta', 'country': 'Asia', 'timezone': 'GMT+02:00'}, + {'city': 'Gaza', 'country': 'Asia', 'timezone': 'GMT+02:00'}, + {'city': 'Harbin', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Hebron', 'country': 'Asia', 'timezone': 'GMT+02:00'}, + {'city': 'Ho Chi Minh', 'country': 'Asia', 'timezone': 'GMT+07:00'}, + {'city': 'Hong Kong', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Hovd', 'country': 'Asia', 'timezone': 'GMT+07:00'}, + {'city': 'Irkutsk', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Istanbul', 'country': 'Asia', 'timezone': 'GMT+03:00'}, + {'city': 'Jakarta', 'country': 'Asia', 'timezone': 'GMT+07:00'}, + {'city': 'Jayapura', 'country': 'Asia', 'timezone': 'GMT+09:00'}, + {'city': 'Jerusalem', 'country': 'Asia', 'timezone': 'GMT+02:00'}, + {'city': 'Kabul', 'country': 'Asia', 'timezone': 'GMT+04:30'}, + {'city': 'Kamchatka', 'country': 'Asia', 'timezone': 'GMT+12:00'}, + {'city': 'Karachi', 'country': 'Asia', 'timezone': 'GMT+05:00'}, + {'city': 'Kashgar', 'country': 'Asia', 'timezone': 'GMT+06:00'}, + {'city': 'Kathmandu', 'country': 'Asia', 'timezone': 'GMT+05:45'}, + {'city': 'Katmandu', 'country': 'Asia', 'timezone': 'GMT+05:45'}, + {'city': 'Khandyga', 'country': 'Asia', 'timezone': 'GMT+09:00'}, + {'city': 'Kolkata', 'country': 'Asia', 'timezone': 'GMT+05:30'}, + {'city': 'Krasnoyarsk', 'country': 'Asia', 'timezone': 'GMT+07:00'}, + {'city': 'Kuala Lumpur', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Kuching', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Kuwait', 'country': 'Asia', 'timezone': 'GMT+03:00'}, + {'city': 'Macao', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Macau', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Magadan', 'country': 'Asia', 'timezone': 'GMT+11:00'}, + {'city': 'Makassar', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Manila', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Muscat', 'country': 'Asia', 'timezone': 'GMT+04:00'}, + {'city': 'Nicosia', 'country': 'Asia', 'timezone': 'GMT+02:00'}, + {'city': 'Novokuznetsk', 'country': 'Asia', 'timezone': 'GMT+07:00'}, + {'city': 'Novosibirsk', 'country': 'Asia', 'timezone': 'GMT+07:00'}, + {'city': 'Omsk', 'country': 'Asia', 'timezone': 'GMT+06:00'}, + {'city': 'Oral', 'country': 'Asia', 'timezone': 'GMT+05:00'}, + {'city': 'Phnom Penh', 'country': 'Asia', 'timezone': 'GMT+07:00'}, + {'city': 'Pontianak', 'country': 'Asia', 'timezone': 'GMT+07:00'}, + {'city': 'Pyongyang', 'country': 'Asia', 'timezone': 'GMT+09:00'}, + {'city': 'Qatar', 'country': 'Asia', 'timezone': 'GMT+03:00'}, + {'city': 'Qostanay', 'country': 'Asia', 'timezone': 'GMT+05:00'}, + {'city': 'Qyzylorda', 'country': 'Asia', 'timezone': 'GMT+05:00'}, + {'city': 'Rangoon', 'country': 'Asia', 'timezone': 'GMT+06:30'}, + {'city': 'Riyadh', 'country': 'Asia', 'timezone': 'GMT+03:00'}, + {'city': 'Saigon', 'country': 'Asia', 'timezone': 'GMT+07:00'}, + {'city': 'Sakhalin', 'country': 'Asia', 'timezone': 'GMT+11:00'}, + {'city': 'Samarkand', 'country': 'Asia', 'timezone': 'GMT+05:00'}, + {'city': 'Seoul', 'country': 'Asia', 'timezone': 'GMT+09:00'}, + {'city': 'Shanghai', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Singapore', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Srednekolymsk', 'country': 'Asia', 'timezone': 'GMT+11:00'}, + {'city': 'Taipei', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Tashkent', 'country': 'Asia', 'timezone': 'GMT+05:00'}, + {'city': 'Tbilisi', 'country': 'Asia', 'timezone': 'GMT+04:00'}, + {'city': 'Tehran', 'country': 'Asia', 'timezone': 'GMT+03:30'}, + {'city': 'Tel Aviv', 'country': 'Asia', 'timezone': 'GMT+02:00'}, + {'city': 'Thimbu', 'country': 'Asia', 'timezone': 'GMT+06:00'}, + {'city': 'Thimphu', 'country': 'Asia', 'timezone': 'GMT+06:00'}, + {'city': 'Tokyo', 'country': 'Asia', 'timezone': 'GMT+09:00'}, + {'city': 'Tomsk', 'country': 'Asia', 'timezone': 'GMT+07:00'}, + {'city': 'Ujung Pandang', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Ulaanbaatar', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Ulan Bator', 'country': 'Asia', 'timezone': 'GMT+08:00'}, + {'city': 'Urumqi', 'country': 'Asia', 'timezone': 'GMT+06:00'}, + {'city': 'Ust-Nera', 'country': 'Asia', 'timezone': 'GMT+10:00'}, + {'city': 'Vientiane', 'country': 'Asia', 'timezone': 'GMT+07:00'}, + {'city': 'Vladivostok', 'country': 'Asia', 'timezone': 'GMT+10:00'}, + {'city': 'Yakutsk', 'country': 'Asia', 'timezone': 'GMT+09:00'}, + {'city': 'Yangon', 'country': 'Asia', 'timezone': 'GMT+06:30'}, + {'city': 'Yekaterinburg', 'country': 'Asia', 'timezone': 'GMT+05:00'}, + {'city': 'Yerevan', 'country': 'Asia', 'timezone': 'GMT+04:00'}, + {'city': 'Azores', 'country': 'Atlantic', 'timezone': 'GMT-01:00'}, + {'city': 'Bermuda', 'country': 'Atlantic', 'timezone': 'GMT-03:00'}, + {'city': 'Canary', 'country': 'Atlantic', 'timezone': 'GMT+00:00'}, + {'city': 'Cape Verde', 'country': 'Atlantic', 'timezone': 'GMT-01:00'}, + {'city': 'Faeroe', 'country': 'Atlantic', 'timezone': 'GMT+00:00'}, + {'city': 'Faroe', 'country': 'Atlantic', 'timezone': 'GMT+00:00'}, + {'city': 'Jan Mayen', 'country': 'Atlantic', 'timezone': 'GMT+01:00'}, + {'city': 'Madeira', 'country': 'Atlantic', 'timezone': 'GMT+00:00'}, + {'city': 'Reykjavik', 'country': 'Atlantic', 'timezone': 'GMT+00:00'}, + {'city': 'South Georgia', 'country': 'Atlantic', 'timezone': 'GMT-02:00'}, + {'city': 'St Helena', 'country': 'Atlantic', 'timezone': 'GMT+00:00'}, + {'city': 'Stanley', 'country': 'Atlantic', 'timezone': 'GMT-03:00'}, + {'city': 'ACT', 'country': 'Australia', 'timezone': 'GMT+11:00'}, + {'city': 'Adelaide', 'country': 'Australia', 'timezone': 'GMT+10:30'}, + {'city': 'Brisbane', 'country': 'Australia', 'timezone': 'GMT+10:00'}, + {'city': 'Broken Hill', 'country': 'Australia', 'timezone': 'GMT+10:30'}, + {'city': 'Canberra', 'country': 'Australia', 'timezone': 'GMT+11:00'}, + {'city': 'Currie', 'country': 'Australia', 'timezone': 'GMT+11:00'}, + {'city': 'Darwin', 'country': 'Australia', 'timezone': 'GMT+09:30'}, + {'city': 'Eucla', 'country': 'Australia', 'timezone': 'GMT+08:45'}, + {'city': 'Hobart', 'country': 'Australia', 'timezone': 'GMT+11:00'}, + {'city': 'LHI', 'country': 'Australia', 'timezone': 'GMT+11:00'}, + {'city': 'Lindeman', 'country': 'Australia', 'timezone': 'GMT+10:00'}, + {'city': 'Lord Howe', 'country': 'Australia', 'timezone': 'GMT+11:00'}, + {'city': 'Melbourne', 'country': 'Australia', 'timezone': 'GMT+11:00'}, + {'city': 'NSW', 'country': 'Australia', 'timezone': 'GMT+11:00'}, + {'city': 'North', 'country': 'Australia', 'timezone': 'GMT+09:30'}, + {'city': 'Perth', 'country': 'Australia', 'timezone': 'GMT+08:00'}, + {'city': 'Queensland', 'country': 'Australia', 'timezone': 'GMT+10:00'}, + {'city': 'South', 'country': 'Australia', 'timezone': 'GMT+10:30'}, + {'city': 'Sydney', 'country': 'Australia', 'timezone': 'GMT+11:00'}, + {'city': 'Tasmania', 'country': 'Australia', 'timezone': 'GMT+11:00'}, + {'city': 'Victoria', 'country': 'Australia', 'timezone': 'GMT+11:00'}, + {'city': 'West', 'country': 'Australia', 'timezone': 'GMT+08:00'}, + {'city': 'Yancowinna', 'country': 'Australia', 'timezone': 'GMT+10:30'}, + {'city': 'Acre', 'country': 'Brazil', 'timezone': 'GMT-05:00'}, + {'city': 'DeNoronha', 'country': 'Brazil', 'timezone': 'GMT-02:00'}, + {'city': 'East', 'country': 'Brazil', 'timezone': 'GMT-03:00'}, + {'city': 'West', 'country': 'Brazil', 'timezone': 'GMT-04:00'}, + {'city': 'CET', 'country': 'Unknown', 'timezone': 'GMT+01:00'}, + {'city': 'CST6CDT', 'country': 'Unknown', 'timezone': 'GMT-05:00'}, + {'city': 'Atlantic', 'country': 'Canada', 'timezone': 'GMT-03:00'}, + {'city': 'Central', 'country': 'Canada', 'timezone': 'GMT-05:00'}, + {'city': 'Eastern', 'country': 'Canada', 'timezone': 'GMT-04:00'}, + {'city': 'Mountain', 'country': 'Canada', 'timezone': 'GMT-06:00'}, + {'city': 'Newfoundland', 'country': 'Canada', 'timezone': 'GMT-02:30'}, + {'city': 'Pacific', 'country': 'Canada', 'timezone': 'GMT-07:00'}, + {'city': 'Saskatchewan', 'country': 'Canada', 'timezone': 'GMT-06:00'}, + {'city': 'Yukon', 'country': 'Canada', 'timezone': 'GMT-07:00'}, + {'city': 'Continental', 'country': 'Chile', 'timezone': 'GMT-03:00'}, + {'city': 'EasterIsland', 'country': 'Chile', 'timezone': 'GMT-05:00'}, + {'city': 'Cuba', 'country': 'Unknown', 'timezone': 'GMT-04:00'}, + {'city': 'EET', 'country': 'Unknown', 'timezone': 'GMT+02:00'}, + {'city': 'EST', 'country': 'Unknown', 'timezone': 'GMT-05:00'}, + {'city': 'EST5EDT', 'country': 'Unknown', 'timezone': 'GMT-04:00'}, + {'city': 'Egypt', 'country': 'Unknown', 'timezone': 'GMT+02:00'}, + {'city': 'Eire', 'country': 'Unknown', 'timezone': 'GMT+00:00'}, + {'city': 'GMT', 'country': 'Etc', 'timezone': 'GMT+00:00'}, + {'city': 'GMT+0', 'country': 'Etc', 'timezone': 'GMT+00:00'}, + {'city': 'GMT+1', 'country': 'Etc', 'timezone': 'GMT-01:00'}, + {'city': 'GMT+10', 'country': 'Etc', 'timezone': 'GMT-10:00'}, + {'city': 'GMT+11', 'country': 'Etc', 'timezone': 'GMT-11:00'}, + {'city': 'GMT+12', 'country': 'Etc', 'timezone': 'GMT-12:00'}, + {'city': 'GMT+2', 'country': 'Etc', 'timezone': 'GMT-02:00'}, + {'city': 'GMT+3', 'country': 'Etc', 'timezone': 'GMT-03:00'}, + {'city': 'GMT+4', 'country': 'Etc', 'timezone': 'GMT-04:00'}, + {'city': 'GMT+5', 'country': 'Etc', 'timezone': 'GMT-05:00'}, + {'city': 'GMT+6', 'country': 'Etc', 'timezone': 'GMT-06:00'}, + {'city': 'GMT+7', 'country': 'Etc', 'timezone': 'GMT-07:00'}, + {'city': 'GMT+8', 'country': 'Etc', 'timezone': 'GMT-08:00'}, + {'city': 'GMT+9', 'country': 'Etc', 'timezone': 'GMT-09:00'}, + {'city': 'GMT-0', 'country': 'Etc', 'timezone': 'GMT+00:00'}, + {'city': 'GMT-1', 'country': 'Etc', 'timezone': 'GMT+01:00'}, + {'city': 'GMT-10', 'country': 'Etc', 'timezone': 'GMT+10:00'}, + {'city': 'GMT-11', 'country': 'Etc', 'timezone': 'GMT+11:00'}, + {'city': 'GMT-12', 'country': 'Etc', 'timezone': 'GMT+12:00'}, + {'city': 'GMT-13', 'country': 'Etc', 'timezone': 'GMT+13:00'}, + {'city': 'GMT-14', 'country': 'Etc', 'timezone': 'GMT+14:00'}, + {'city': 'GMT-2', 'country': 'Etc', 'timezone': 'GMT+02:00'}, + {'city': 'GMT-3', 'country': 'Etc', 'timezone': 'GMT+03:00'}, + {'city': 'GMT-4', 'country': 'Etc', 'timezone': 'GMT+04:00'}, + {'city': 'GMT-5', 'country': 'Etc', 'timezone': 'GMT+05:00'}, + {'city': 'GMT-6', 'country': 'Etc', 'timezone': 'GMT+06:00'}, + {'city': 'GMT-7', 'country': 'Etc', 'timezone': 'GMT+07:00'}, + {'city': 'GMT-8', 'country': 'Etc', 'timezone': 'GMT+08:00'}, + {'city': 'GMT-9', 'country': 'Etc', 'timezone': 'GMT+09:00'}, + {'city': 'GMT0', 'country': 'Etc', 'timezone': 'GMT+00:00'}, + {'city': 'Greenwich', 'country': 'Etc', 'timezone': 'GMT+00:00'}, + {'city': 'UCT', 'country': 'Etc', 'timezone': 'GMT+00:00'}, + {'city': 'UTC', 'country': 'Etc', 'timezone': 'GMT+00:00'}, + {'city': 'Universal', 'country': 'Etc', 'timezone': 'GMT+00:00'}, + {'city': 'Zulu', 'country': 'Etc', 'timezone': 'GMT+00:00'}, + {'city': 'Amsterdam', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Andorra', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Astrakhan', 'country': 'Europe', 'timezone': 'GMT+04:00'}, + {'city': 'Athens', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Belfast', 'country': 'Europe', 'timezone': 'GMT+00:00'}, + {'city': 'Belgrade', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Berlin', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Bratislava', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Brussels', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Bucharest', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Budapest', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Busingen', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Chisinau', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Copenhagen', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Dublin', 'country': 'Europe', 'timezone': 'GMT+00:00'}, + {'city': 'Gibraltar', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Guernsey', 'country': 'Europe', 'timezone': 'GMT+00:00'}, + {'city': 'Helsinki', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Isle of Man', 'country': 'Europe', 'timezone': 'GMT+00:00'}, + {'city': 'Istanbul', 'country': 'Europe', 'timezone': 'GMT+03:00'}, + {'city': 'Jersey', 'country': 'Europe', 'timezone': 'GMT+00:00'}, + {'city': 'Kaliningrad', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Kiev', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Kirov', 'country': 'Europe', 'timezone': 'GMT+03:00'}, + {'city': 'Kyiv', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Lisbon', 'country': 'Europe', 'timezone': 'GMT+00:00'}, + {'city': 'Ljubljana', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'London', 'country': 'Europe', 'timezone': 'GMT+00:00'}, + {'city': 'Luxembourg', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Madrid', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Malta', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Mariehamn', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Minsk', 'country': 'Europe', 'timezone': 'GMT+03:00'}, + {'city': 'Monaco', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Moscow', 'country': 'Europe', 'timezone': 'GMT+03:00'}, + {'city': 'Nicosia', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Oslo', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Paris', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Podgorica', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Prague', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Riga', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Rome', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Samara', 'country': 'Europe', 'timezone': 'GMT+04:00'}, + {'city': 'San Marino', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Sarajevo', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Saratov', 'country': 'Europe', 'timezone': 'GMT+04:00'}, + {'city': 'Simferopol', 'country': 'Europe', 'timezone': 'GMT+03:00'}, + {'city': 'Skopje', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Sofia', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Stockholm', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Tallinn', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Tirane', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Tiraspol', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Ulyanovsk', 'country': 'Europe', 'timezone': 'GMT+04:00'}, + {'city': 'Uzhgorod', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Vaduz', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Vatican', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Vienna', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Vilnius', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Volgograd', 'country': 'Europe', 'timezone': 'GMT+03:00'}, + {'city': 'Warsaw', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Zagreb', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'Zaporozhye', 'country': 'Europe', 'timezone': 'GMT+02:00'}, + {'city': 'Zurich', 'country': 'Europe', 'timezone': 'GMT+01:00'}, + {'city': 'GB', 'country': 'Unknown', 'timezone': 'GMT+00:00'}, + {'city': 'GB-Eire', 'country': 'Unknown', 'timezone': 'GMT+00:00'}, + {'city': 'GMT', 'country': 'Unknown', 'timezone': 'GMT+00:00'}, + {'city': 'GMT+0', 'country': 'Unknown', 'timezone': 'GMT+00:00'}, + {'city': 'GMT-0', 'country': 'Unknown', 'timezone': 'GMT+00:00'}, + {'city': 'GMT0', 'country': 'Unknown', 'timezone': 'GMT+00:00'}, + {'city': 'Greenwich', 'country': 'Unknown', 'timezone': 'GMT+00:00'}, + {'city': 'HST', 'country': 'Unknown', 'timezone': 'GMT-10:00'}, + {'city': 'Hongkong', 'country': 'Unknown', 'timezone': 'GMT+08:00'}, + {'city': 'Iceland', 'country': 'Unknown', 'timezone': 'GMT+00:00'}, + {'city': 'Antananarivo', 'country': 'Indian', 'timezone': 'GMT+03:00'}, + {'city': 'Chagos', 'country': 'Indian', 'timezone': 'GMT+06:00'}, + {'city': 'Christmas', 'country': 'Indian', 'timezone': 'GMT+07:00'}, + {'city': 'Cocos', 'country': 'Indian', 'timezone': 'GMT+06:30'}, + {'city': 'Comoro', 'country': 'Indian', 'timezone': 'GMT+03:00'}, + {'city': 'Kerguelen', 'country': 'Indian', 'timezone': 'GMT+05:00'}, + {'city': 'Mahe', 'country': 'Indian', 'timezone': 'GMT+04:00'}, + {'city': 'Maldives', 'country': 'Indian', 'timezone': 'GMT+05:00'}, + {'city': 'Mauritius', 'country': 'Indian', 'timezone': 'GMT+04:00'}, + {'city': 'Mayotte', 'country': 'Indian', 'timezone': 'GMT+03:00'}, + {'city': 'Reunion', 'country': 'Indian', 'timezone': 'GMT+04:00'}, + {'city': 'Iran', 'country': 'Unknown', 'timezone': 'GMT+03:30'}, + {'city': 'Israel', 'country': 'Unknown', 'timezone': 'GMT+02:00'}, + {'city': 'Jamaica', 'country': 'Unknown', 'timezone': 'GMT-05:00'}, + {'city': 'Japan', 'country': 'Unknown', 'timezone': 'GMT+09:00'}, + {'city': 'Kwajalein', 'country': 'Unknown', 'timezone': 'GMT+12:00'}, + {'city': 'Libya', 'country': 'Unknown', 'timezone': 'GMT+02:00'}, + {'city': 'MET', 'country': 'Unknown', 'timezone': 'GMT+01:00'}, + {'city': 'MST', 'country': 'Unknown', 'timezone': 'GMT-07:00'}, + {'city': 'MST7MDT', 'country': 'Unknown', 'timezone': 'GMT-06:00'}, + {'city': 'BajaNorte', 'country': 'Mexico', 'timezone': 'GMT-07:00'}, + {'city': 'BajaSur', 'country': 'Mexico', 'timezone': 'GMT-07:00'}, + {'city': 'General', 'country': 'Mexico', 'timezone': 'GMT-06:00'}, + {'city': 'NZ', 'country': 'Unknown', 'timezone': 'GMT+13:00'}, + {'city': 'NZ-CHAT', 'country': 'Unknown', 'timezone': 'GMT+13:45'}, + {'city': 'Navajo', 'country': 'Unknown', 'timezone': 'GMT-06:00'}, + {'city': 'PRC', 'country': 'Unknown', 'timezone': 'GMT+08:00'}, + {'city': 'PST8PDT', 'country': 'Unknown', 'timezone': 'GMT-07:00'}, + {'city': 'Apia', 'country': 'Pacific', 'timezone': 'GMT+13:00'}, + {'city': 'Auckland', 'country': 'Pacific', 'timezone': 'GMT+13:00'}, + {'city': 'Bougainville', 'country': 'Pacific', 'timezone': 'GMT+11:00'}, + {'city': 'Chatham', 'country': 'Pacific', 'timezone': 'GMT+13:45'}, + {'city': 'Chuuk', 'country': 'Pacific', 'timezone': 'GMT+10:00'}, + {'city': 'Easter', 'country': 'Pacific', 'timezone': 'GMT-05:00'}, + {'city': 'Efate', 'country': 'Pacific', 'timezone': 'GMT+11:00'}, + {'city': 'Enderbury', 'country': 'Pacific', 'timezone': 'GMT+13:00'}, + {'city': 'Fakaofo', 'country': 'Pacific', 'timezone': 'GMT+13:00'}, + {'city': 'Fiji', 'country': 'Pacific', 'timezone': 'GMT+12:00'}, + {'city': 'Funafuti', 'country': 'Pacific', 'timezone': 'GMT+12:00'}, + {'city': 'Galapagos', 'country': 'Pacific', 'timezone': 'GMT-06:00'}, + {'city': 'Gambier', 'country': 'Pacific', 'timezone': 'GMT-09:00'}, + {'city': 'Guadalcanal', 'country': 'Pacific', 'timezone': 'GMT+11:00'}, + {'city': 'Guam', 'country': 'Pacific', 'timezone': 'GMT+10:00'}, + {'city': 'Honolulu', 'country': 'Pacific', 'timezone': 'GMT-10:00'}, + {'city': 'Johnston', 'country': 'Pacific', 'timezone': 'GMT-10:00'}, + {'city': 'Kanton', 'country': 'Pacific', 'timezone': 'GMT+13:00'}, + {'city': 'Kiritimati', 'country': 'Pacific', 'timezone': 'GMT+14:00'}, + {'city': 'Kosrae', 'country': 'Pacific', 'timezone': 'GMT+11:00'}, + {'city': 'Kwajalein', 'country': 'Pacific', 'timezone': 'GMT+12:00'}, + {'city': 'Majuro', 'country': 'Pacific', 'timezone': 'GMT+12:00'}, + {'city': 'Marquesas', 'country': 'Pacific', 'timezone': 'GMT-09:30'}, + {'city': 'Midway', 'country': 'Pacific', 'timezone': 'GMT-11:00'}, + {'city': 'Nauru', 'country': 'Pacific', 'timezone': 'GMT+12:00'}, + {'city': 'Niue', 'country': 'Pacific', 'timezone': 'GMT-11:00'}, + {'city': 'Norfolk', 'country': 'Pacific', 'timezone': 'GMT+12:00'}, + {'city': 'Noumea', 'country': 'Pacific', 'timezone': 'GMT+11:00'}, + {'city': 'Pago Pago', 'country': 'Pacific', 'timezone': 'GMT-11:00'}, + {'city': 'Palau', 'country': 'Pacific', 'timezone': 'GMT+09:00'}, + {'city': 'Pitcairn', 'country': 'Pacific', 'timezone': 'GMT-08:00'}, + {'city': 'Pohnpei', 'country': 'Pacific', 'timezone': 'GMT+11:00'}, + {'city': 'Ponape', 'country': 'Pacific', 'timezone': 'GMT+11:00'}, + {'city': 'Port Moresby', 'country': 'Pacific', 'timezone': 'GMT+10:00'}, + {'city': 'Rarotonga', 'country': 'Pacific', 'timezone': 'GMT-10:00'}, + {'city': 'Saipan', 'country': 'Pacific', 'timezone': 'GMT+10:00'}, + {'city': 'Samoa', 'country': 'Pacific', 'timezone': 'GMT-11:00'}, + {'city': 'Tahiti', 'country': 'Pacific', 'timezone': 'GMT-10:00'}, + {'city': 'Tarawa', 'country': 'Pacific', 'timezone': 'GMT+12:00'}, + {'city': 'Tongatapu', 'country': 'Pacific', 'timezone': 'GMT+13:00'}, + {'city': 'Truk', 'country': 'Pacific', 'timezone': 'GMT+10:00'}, + {'city': 'Wake', 'country': 'Pacific', 'timezone': 'GMT+12:00'}, + {'city': 'Wallis', 'country': 'Pacific', 'timezone': 'GMT+12:00'}, + {'city': 'Yap', 'country': 'Pacific', 'timezone': 'GMT+10:00'}, + {'city': 'Poland', 'country': 'Unknown', 'timezone': 'GMT+01:00'}, + {'city': 'Portugal', 'country': 'Unknown', 'timezone': 'GMT+00:00'}, + {'city': 'ROC', 'country': 'Unknown', 'timezone': 'GMT+08:00'}, + {'city': 'ROK', 'country': 'Unknown', 'timezone': 'GMT+09:00'}, + {'city': 'Singapore', 'country': 'Unknown', 'timezone': 'GMT+08:00'}, + {'city': 'Turkey', 'country': 'Unknown', 'timezone': 'GMT+03:00'}, + {'city': 'UCT', 'country': 'Unknown', 'timezone': 'GMT+00:00'}, + {'city': 'Alaska', 'country': 'US', 'timezone': 'GMT-08:00'}, + {'city': 'Aleutian', 'country': 'US', 'timezone': 'GMT-09:00'}, + {'city': 'Arizona', 'country': 'US', 'timezone': 'GMT-07:00'}, + {'city': 'Central', 'country': 'US', 'timezone': 'GMT-05:00'}, + {'city': 'East-Indiana', 'country': 'US', 'timezone': 'GMT-04:00'}, + {'city': 'Eastern', 'country': 'US', 'timezone': 'GMT-04:00'}, + {'city': 'Hawaii', 'country': 'US', 'timezone': 'GMT-10:00'}, + {'city': 'Indiana-Starke', 'country': 'US', 'timezone': 'GMT-05:00'}, + {'city': 'Michigan', 'country': 'US', 'timezone': 'GMT-04:00'}, + {'city': 'Mountain', 'country': 'US', 'timezone': 'GMT-06:00'}, + {'city': 'Pacific', 'country': 'US', 'timezone': 'GMT-07:00'}, + {'city': 'Samoa', 'country': 'US', 'timezone': 'GMT-11:00'}, + {'city': 'UTC', 'country': 'Unknown', 'timezone': 'GMT+00:00'}, + {'city': 'Universal', 'country': 'Unknown', 'timezone': 'GMT+00:00'}, + {'city': 'W-SU', 'country': 'Unknown', 'timezone': 'GMT+03:00'}, + {'city': 'WET', 'country': 'Unknown', 'timezone': 'GMT+00:00'}, + {'city': 'Zulu', 'country': 'Unknown', 'timezone': 'GMT+00:00'} +]; \ No newline at end of file