date_time_util.dart 8.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344
  1. import "package:flutter/cupertino.dart";
  2. import 'package:flutter/foundation.dart';
  3. import 'package:intl/intl.dart';
  4. import "package:photos/generated/l10n.dart";
  5. const Set<int> monthWith31Days = {1, 3, 5, 7, 8, 10, 12};
  6. const Set<int> monthWith30Days = {4, 6, 9, 11};
  7. Map<int, String> _months = {
  8. 1: "Jan",
  9. 2: "Feb",
  10. 3: "Mar",
  11. 4: "Apr",
  12. 5: "May",
  13. 6: "Jun",
  14. 7: "Jul",
  15. 8: "Aug",
  16. 9: "Sep",
  17. 10: "Oct",
  18. 11: "Nov",
  19. 12: "Dec",
  20. };
  21. Map<int, String> _fullMonths = {
  22. 1: "January",
  23. 2: "February",
  24. 3: "March",
  25. 4: "April",
  26. 5: "May",
  27. 6: "June",
  28. 7: "July",
  29. 8: "August",
  30. 9: "September",
  31. 10: "October",
  32. 11: "November",
  33. 12: "December",
  34. };
  35. Map<int, String> _days = {
  36. 1: "Mon",
  37. 2: "Tue",
  38. 3: "Wed",
  39. 4: "Thu",
  40. 5: "Fri",
  41. 6: "Sat",
  42. 7: "Sun",
  43. };
  44. final currentYear = DateTime.now().year;
  45. const searchStartYear = 1970;
  46. //Jun 2022
  47. String getMonthAndYear(DateTime dateTime) {
  48. return _months[dateTime.month]! + " " + dateTime.year.toString();
  49. }
  50. int daysBetween(DateTime from, DateTime to) {
  51. from = DateTime(from.year, from.month, from.day);
  52. to = DateTime(to.year, to.month, to.day);
  53. return (to.difference(from).inHours / 24).round();
  54. }
  55. bool areFromSameDay(int firstCreationTime, int secondCreationTime) {
  56. final firstDate = DateTime.fromMicrosecondsSinceEpoch(firstCreationTime);
  57. final secondDate = DateTime.fromMicrosecondsSinceEpoch(secondCreationTime);
  58. return firstDate.year == secondDate.year &&
  59. firstDate.month == secondDate.month &&
  60. firstDate.day == secondDate.day;
  61. }
  62. //Thu, 30 Jun
  63. String getDayAndMonth(DateTime dateTime) {
  64. return _days[dateTime.weekday]! +
  65. ", " +
  66. dateTime.day.toString() +
  67. " " +
  68. _months[dateTime.month]!;
  69. }
  70. //30 Jun, 2022
  71. String getDateAndMonthAndYear(DateTime dateTime) {
  72. return dateTime.day.toString() +
  73. " " +
  74. _months[dateTime.month]! +
  75. ", " +
  76. dateTime.year.toString();
  77. }
  78. // Create link default names:
  79. // Same day: "Dec 19, 2022"
  80. // Same month: "Dec 19 - 22, 2022"
  81. // Base case: "Dec 19, 2022 - Jan 7, 2023"
  82. String getNameForDateRange(int firstCreationTime, int secondCreationTime) {
  83. final startTime = DateTime.fromMicrosecondsSinceEpoch(firstCreationTime);
  84. final endTime = DateTime.fromMicrosecondsSinceEpoch(secondCreationTime);
  85. // different year
  86. if (startTime.year != endTime.year) {
  87. return "${_months[startTime.month]!} ${startTime.day}, ${startTime.year} - "
  88. "${_months[endTime.month]!} ${endTime.day}, ${endTime.year}";
  89. }
  90. // same year, diff month
  91. if (startTime.month != endTime.month) {
  92. return "${_months[startTime.month]!} ${startTime.day} - "
  93. "${_months[endTime.month]!} ${endTime.day}, ${endTime.year}";
  94. }
  95. // same month and year, diff day
  96. if (startTime.day != endTime.day) {
  97. return "${_months[startTime.month]!} ${startTime.day} - "
  98. "${_months[endTime.month]!} ${endTime.day}, ${endTime.year}";
  99. }
  100. // same day
  101. return "${_months[endTime.month]!} ${endTime.day}, ${endTime.year}";
  102. }
  103. String getDay(DateTime dateTime) {
  104. return _days[dateTime.weekday]!;
  105. }
  106. String getMonth(DateTime dateTime) {
  107. return _months[dateTime.month]!;
  108. }
  109. String getFullMonth(DateTime dateTime) {
  110. return _fullMonths[dateTime.month]!;
  111. }
  112. String getAbbreviationOfYear(DateTime dateTime) {
  113. return (dateTime.year % 100).toString();
  114. }
  115. //14:32
  116. String getTime(DateTime dateTime) {
  117. final hours = dateTime.hour > 9
  118. ? dateTime.hour.toString()
  119. : "0" + dateTime.hour.toString();
  120. final minutes = dateTime.minute > 9
  121. ? dateTime.minute.toString()
  122. : "0" + dateTime.minute.toString();
  123. return hours + ":" + minutes;
  124. }
  125. //11:22 AM
  126. String getTimeIn12hrFormat(DateTime dateTime) {
  127. return DateFormat.jm().format(dateTime);
  128. }
  129. //Thu, Jun 30, 2022 - 14:32
  130. String getFormattedTime(DateTime dateTime) {
  131. return getDay(dateTime) +
  132. ", " +
  133. getMonth(dateTime) +
  134. " " +
  135. dateTime.day.toString() +
  136. ", " +
  137. dateTime.year.toString() +
  138. " - " +
  139. getTime(dateTime);
  140. }
  141. //30 Jun'22
  142. String getFormattedDate(DateTime dateTime) {
  143. return dateTime.day.toString() +
  144. " " +
  145. getMonth(dateTime) +
  146. "'" +
  147. getAbbreviationOfYear(dateTime);
  148. }
  149. String getFullDate(DateTime dateTime) {
  150. return getDay(dateTime) +
  151. ", " +
  152. getMonth(dateTime) +
  153. " " +
  154. dateTime.day.toString() +
  155. " " +
  156. dateTime.year.toString();
  157. }
  158. String daysLeft(int futureTime) {
  159. final int daysLeft = ((futureTime - DateTime.now().microsecondsSinceEpoch) /
  160. Duration.microsecondsPerDay)
  161. .ceil();
  162. return '$daysLeft day' + (daysLeft <= 1 ? "" : "s");
  163. }
  164. String formatDuration(Duration position) {
  165. final ms = position.inMilliseconds;
  166. int seconds = ms ~/ 1000;
  167. final int hours = seconds ~/ 3600;
  168. seconds = seconds % 3600;
  169. final minutes = seconds ~/ 60;
  170. seconds = seconds % 60;
  171. final hoursString = hours >= 10
  172. ? '$hours'
  173. : hours == 0
  174. ? '00'
  175. : '0$hours';
  176. final minutesString = minutes >= 10
  177. ? '$minutes'
  178. : minutes == 0
  179. ? '00'
  180. : '0$minutes';
  181. final secondsString = seconds >= 10
  182. ? '$seconds'
  183. : seconds == 0
  184. ? '00'
  185. : '0$seconds';
  186. final formattedTime =
  187. '${hoursString == '00' ? '' : hoursString + ':'}$minutesString:$secondsString';
  188. return formattedTime;
  189. }
  190. bool isLeapYear(DateTime dateTime) {
  191. final year = dateTime.year;
  192. if (year % 4 == 0) {
  193. if (year % 100 == 0) {
  194. if (year % 400 == 0) {
  195. return true;
  196. } else {
  197. return false;
  198. }
  199. } else {
  200. return true;
  201. }
  202. } else {
  203. return false;
  204. }
  205. }
  206. String getDayTitle(BuildContext context, int timestamp) {
  207. final date = DateTime.fromMicrosecondsSinceEpoch(timestamp);
  208. final now = DateTime.now();
  209. var title = getDayAndMonth(date);
  210. if (date.year == now.year && date.month == now.month) {
  211. if (date.day == now.day) {
  212. title = S.of(context).dayToday;
  213. } else if (date.day == now.day - 1) {
  214. title = S.of(context).dayYesterday;
  215. }
  216. }
  217. if (date.year != DateTime.now().year) {
  218. title += " " + date.year.toString();
  219. }
  220. return title;
  221. }
  222. String secondsToHHMMSS(int value) {
  223. int h, m, s;
  224. h = value ~/ 3600;
  225. m = ((value - h * 3600)) ~/ 60;
  226. s = value - (h * 3600) - (m * 60);
  227. final String hourLeft =
  228. h.toString().length < 2 ? "0" + h.toString() : h.toString();
  229. final String minuteLeft =
  230. m.toString().length < 2 ? "0" + m.toString() : m.toString();
  231. final String secondsLeft =
  232. s.toString().length < 2 ? "0" + s.toString() : s.toString();
  233. final String result = "$hourLeft:$minuteLeft:$secondsLeft";
  234. return result;
  235. }
  236. bool isValidDate({
  237. required int day,
  238. required int month,
  239. required int year,
  240. }) {
  241. if (day < 0 || day > 31 || month < 0 || month > 12 || year < 0) {
  242. return false;
  243. }
  244. if (monthWith30Days.contains(month) && day > 30) {
  245. return false;
  246. }
  247. if (month == 2) {
  248. if (day > 29) {
  249. return false;
  250. }
  251. if (day == 29 && year % 4 != 0) {
  252. return false;
  253. }
  254. }
  255. return true;
  256. }
  257. final RegExp exp = RegExp('[\\.A-Za-z]*');
  258. DateTime? parseDateTimeFromFileNameV2(
  259. String fileName, {
  260. /* to avoid parsing incorrect date time from the filename, the max and min
  261. year limits the chances of parsing incorrect date times
  262. */
  263. int minYear = 1990,
  264. int? maxYear,
  265. }) {
  266. // add next year to avoid corner cases for 31st Dec
  267. maxYear ??= currentYear + 1;
  268. String val = fileName.replaceAll(exp, '');
  269. if (val.isNotEmpty && !isNumeric(val[0])) {
  270. val = val.substring(1, val.length);
  271. }
  272. if (val.isNotEmpty && !isNumeric(val[val.length - 1])) {
  273. val = val.substring(0, val.length - 1);
  274. }
  275. final int countOfHyphen = val.split("-").length - 1;
  276. final int countUnderScore = val.split("_").length - 1;
  277. String valForParser = val;
  278. if (countOfHyphen == 1) {
  279. valForParser = val.replaceAll("-", "T");
  280. } else if (countUnderScore == 1 || countUnderScore == 2) {
  281. valForParser = val.replaceFirst("_", "T");
  282. if (countUnderScore == 2) {
  283. valForParser = valForParser.split("_")[0];
  284. }
  285. } else if (countOfHyphen == 2) {
  286. valForParser = val.replaceAll(".", ":");
  287. } else if (countOfHyphen == 6) {
  288. final splits = val.split("-");
  289. valForParser =
  290. "${splits[0]}${splits[1]}${splits[2]}T${splits[3]}${splits[4]}${splits[5]}";
  291. }
  292. final result = DateTime.tryParse(valForParser);
  293. if (kDebugMode && result == null) {
  294. debugPrint("Failed to parse $fileName dateTime from $valForParser");
  295. }
  296. if (result != null && result.year >= minYear && result.year <= maxYear) {
  297. return result;
  298. }
  299. return null;
  300. }
  301. bool isNumeric(String? s) {
  302. if (s == null) {
  303. return false;
  304. }
  305. return double.tryParse(s) != null;
  306. }