date_model.dart 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452
  1. import 'package:flutter_datetime_picker/src/date_format.dart';
  2. import 'package:flutter_datetime_picker/src/i18n_model.dart';
  3. import 'package:flutter_commons_lang/flutter_commons_lang.dart';
  4. abstract class BasePickerModel {
  5. String leftStringAtIndex(int index);
  6. String middleStringAtIndex(int index);
  7. String rightStringAtIndex(int index);
  8. void setLeftIndex(int index);
  9. void setMiddleIndex(int index);
  10. void setRightIndex(int index);
  11. int currentLeftIndex();
  12. int currentMiddleIndex();
  13. int currentRightIndex();
  14. DateTime finalTime();
  15. String leftDivider();
  16. String rightDivider();
  17. List<int> layoutProportions();
  18. }
  19. class CommonPickerModel extends BasePickerModel {
  20. List<String> leftList;
  21. List<String> middleList;
  22. List<String> rightList;
  23. DateTime currentTime;
  24. int _currentLeftIndex;
  25. int _currentMiddleIndex;
  26. int _currentRightIndex;
  27. LocaleType locale;
  28. CommonPickerModel({this.currentTime, locale}) : this.locale = locale ?? LocaleType.en;
  29. @override
  30. String leftStringAtIndex(int index) {
  31. return null;
  32. }
  33. @override
  34. String middleStringAtIndex(int index) {
  35. return null;
  36. }
  37. @override
  38. String rightStringAtIndex(int index) {
  39. return null;
  40. }
  41. @override
  42. int currentLeftIndex() {
  43. return _currentLeftIndex;
  44. }
  45. @override
  46. int currentMiddleIndex() {
  47. return _currentMiddleIndex;
  48. }
  49. @override
  50. int currentRightIndex() {
  51. return _currentRightIndex;
  52. }
  53. @override
  54. void setLeftIndex(int index) {
  55. _currentLeftIndex = index;
  56. }
  57. @override
  58. void setMiddleIndex(int index) {
  59. _currentMiddleIndex = index;
  60. }
  61. @override
  62. void setRightIndex(int index) {
  63. _currentRightIndex = index;
  64. }
  65. @override
  66. String leftDivider() {
  67. return "";
  68. }
  69. @override
  70. String rightDivider() {
  71. return "";
  72. }
  73. @override
  74. List<int> layoutProportions() {
  75. return [1, 1, 1];
  76. }
  77. @override
  78. DateTime finalTime() {
  79. return null;
  80. }
  81. }
  82. class DatePickerModel extends CommonPickerModel {
  83. DateTime max;
  84. DateTime min;
  85. int maxYear;
  86. int minYear;
  87. int maxMonth;
  88. int minMonth;
  89. int maxDay;
  90. int minDay;
  91. DatePickerModel({DateTime currentTime, this.max, this.min, LocaleType locale}) : super(locale: locale) {
  92. if (currentTime != null) {
  93. if (max != null && currentTime.compareTo(max) > 0) {
  94. currentTime = max;
  95. } else if (min != null && currentTime.compareTo(min) < 0) {
  96. currentTime = min;
  97. }
  98. }
  99. this.currentTime = currentTime ?? DateTime.now();
  100. fillLeftLists();
  101. fillMiddleLists();
  102. fillRightLists();
  103. _currentLeftIndex = this.currentTime.year - minYear;
  104. _currentMiddleIndex = this.currentTime.month - minMonth;
  105. _currentRightIndex = this.currentTime.day - minDay;
  106. }
  107. void fillLeftLists() {
  108. maxYear = max?.year ?? 2050;
  109. minYear = min?.year ?? 1970;
  110. this.leftList = List.generate(maxYear - minYear + 1, (int index) {
  111. return '${minYear + index}${_localeYear()}';
  112. });
  113. }
  114. void fillMiddleLists() {
  115. minMonth = DateUtils.truncatedEquals(currentTime, min, DateUtils.YEAR) ? min?.month : 1;
  116. maxMonth = DateUtils.truncatedEquals(currentTime, max, DateUtils.YEAR) ? max.month : 12;
  117. this.middleList = List.generate(maxMonth - minMonth + 1, (int index) {
  118. return '${minMonth + index}${_localeMonth()}';
  119. });
  120. }
  121. void fillRightLists() {
  122. int dayCount = DateUtils.daysOfTheMonth(currentTime);
  123. maxDay = DateUtils.truncatedEquals(currentTime, max, DateUtils.MONTH) ? max.day : dayCount;
  124. minDay = DateUtils.truncatedEquals(currentTime, min, DateUtils.MONTH) ? min.day : 1;
  125. this.rightList = List.generate(maxDay - minDay + 1, (int index) {
  126. return '${minDay + index}${_localeDay()}';
  127. });
  128. }
  129. @override
  130. void setLeftIndex(int index) {
  131. if (index - minYear > maxYear) index = maxYear - minYear;
  132. super.setLeftIndex(index);
  133. int month = currentTime.month;
  134. currentTime = DateUtils.set(currentTime, year: index + minYear);
  135. fillMiddleLists();
  136. if (month > maxMonth) {
  137. setMiddleIndex(maxMonth - minMonth);
  138. } else if (month < minMonth) {
  139. setMiddleIndex(0);
  140. } else {
  141. setMiddleIndex(month - minMonth);
  142. }
  143. }
  144. @override
  145. void setMiddleIndex(int index) {
  146. if (index - minMonth > maxMonth) index = maxMonth - minMonth;
  147. super.setMiddleIndex(index);
  148. int day = currentTime.day;
  149. currentTime = DateUtils.set(currentTime, month: index + minMonth, day: 1);
  150. fillRightLists();
  151. if (day > maxDay) {
  152. setRightIndex(maxDay - minDay);
  153. } else if (day < minDay) {
  154. setRightIndex(0);
  155. } else {
  156. setRightIndex(day - minDay);
  157. }
  158. }
  159. @override
  160. void setRightIndex(int index) {
  161. if (index - minDay > maxDay) index = maxDay - minDay;
  162. super.setRightIndex(index);
  163. currentTime = DateUtils.set(currentTime, day: index + minDay);
  164. }
  165. @override
  166. String leftStringAtIndex(int index) {
  167. if (index >= 0 && index < leftList.length) {
  168. return leftList[index];
  169. } else {
  170. return null;
  171. }
  172. }
  173. @override
  174. String middleStringAtIndex(int index) {
  175. if (index >= 0 && index < middleList.length) {
  176. return middleList[index];
  177. } else {
  178. return null;
  179. }
  180. }
  181. @override
  182. String rightStringAtIndex(int index) {
  183. if (index >= 0 && index < rightList.length) {
  184. return rightList[index];
  185. } else {
  186. return null;
  187. }
  188. }
  189. String _localeYear() {
  190. if (locale == LocaleType.zh) {
  191. return '年';
  192. } else {
  193. return '';
  194. }
  195. }
  196. String _localeMonth() {
  197. if (locale == LocaleType.zh) {
  198. return '月';
  199. } else {
  200. return '';
  201. }
  202. }
  203. String _localeDay() {
  204. if (locale == LocaleType.zh) {
  205. return '日';
  206. } else {
  207. return '';
  208. }
  209. }
  210. @override
  211. DateTime finalTime() {
  212. final year = _currentLeftIndex + minYear;
  213. final month = _currentMiddleIndex + minMonth;
  214. final day = _currentRightIndex + 1;
  215. return DateTime(year, month, day);
  216. }
  217. }
  218. class TimePickerModel extends CommonPickerModel {
  219. DateTime max;
  220. DateTime min;
  221. int maxHour;
  222. int minHour;
  223. int maxMinute;
  224. int minMinute;
  225. int maxSecond;
  226. int minSecond;
  227. TimePickerModel({DateTime currentTime, this.max, this.min, LocaleType locale}) : super(locale: locale) {
  228. if (currentTime != null) {
  229. if (max != null && currentTime.compareTo(max) > 0) {
  230. currentTime = max;
  231. } else if (min != null && currentTime.compareTo(min) < 0) {
  232. currentTime = min;
  233. }
  234. }
  235. this.currentTime = currentTime ?? DateTime.now();
  236. maxHour = max?.hour ?? 23;
  237. minHour = min?.hour ?? 0;
  238. maxMinute = DateUtils.truncatedEquals(currentTime, max, DateUtils.MINUTE) ? max.minute : 59;
  239. minMinute = DateUtils.truncatedEquals(currentTime, min, DateUtils.MINUTE) ? min?.minute : 0;
  240. _currentLeftIndex = this.currentTime.hour;
  241. _currentMiddleIndex = this.currentTime.minute;
  242. _currentRightIndex = this.currentTime.second;
  243. fillLeftLists();
  244. fillMiddleLists();
  245. fillRightLists();
  246. }
  247. void fillLeftLists() {
  248. this.leftList = List.generate(maxHour - minHour + 1, (int index) {
  249. return digits(minHour + index, 2);
  250. });
  251. }
  252. void fillMiddleLists() {
  253. maxMinute = DateUtils.truncatedEquals(currentTime, max, DateUtils.HOUR) ? max?.minute : 59;
  254. minMinute = DateUtils.truncatedEquals(currentTime, min, DateUtils.HOUR) ? min?.minute : 0;
  255. this.middleList = List.generate(maxMinute - minMinute + 1, (int index) {
  256. return digits(minMinute + index, 2);
  257. });
  258. }
  259. void fillRightLists() {
  260. maxSecond = DateUtils.truncatedEquals(currentTime, max, DateUtils.MINUTE) ? max.second : 59;
  261. minSecond = DateUtils.truncatedEquals(currentTime, min, DateUtils.MINUTE) ? min.second : 0;
  262. this.rightList = List.generate(maxSecond - minSecond + 1, (int index) {
  263. return digits(minSecond + index, 2);
  264. });
  265. }
  266. @override
  267. void setLeftIndex(int index) {
  268. if (index - minHour > maxHour) index = maxHour - minHour;
  269. super.setLeftIndex(index);
  270. int minute = currentTime.minute;
  271. currentTime = DateUtils.set(currentTime, hour: index + minHour);
  272. fillMiddleLists();
  273. if (minute > maxMinute) {
  274. setMiddleIndex(maxMinute - minMinute);
  275. } else if (minute < minMinute) {
  276. setMiddleIndex(0);
  277. } else {
  278. setMiddleIndex(minute - minMinute);
  279. }
  280. }
  281. @override
  282. void setMiddleIndex(int index) {
  283. if (index - minMinute > maxMinute) index = maxMinute - minMinute;
  284. super.setMiddleIndex(index);
  285. int second = currentTime.second;
  286. currentTime = DateUtils.set(currentTime, minute: index + minMinute, second: 1);
  287. fillRightLists();
  288. if (second > maxSecond) {
  289. setRightIndex(maxSecond - minSecond);
  290. } else if (second < minSecond) {
  291. setRightIndex(0);
  292. } else {
  293. setRightIndex(second - minSecond);
  294. }
  295. }
  296. @override
  297. void setRightIndex(int index) {
  298. if (index - minSecond > maxSecond) index = maxSecond - minSecond;
  299. super.setRightIndex(index);
  300. currentTime = DateUtils.set(currentTime, second: index + minSecond);
  301. }
  302. @override
  303. String leftStringAtIndex(int index) {
  304. if (index >= 0 && index < leftList.length) {
  305. return leftList[index];
  306. } else {
  307. return null;
  308. }
  309. }
  310. @override
  311. String middleStringAtIndex(int index) {
  312. if (index >= 0 && index < middleList.length) {
  313. return middleList[index];
  314. } else {
  315. return null;
  316. }
  317. }
  318. @override
  319. String rightStringAtIndex(int index) {
  320. if (index >= 0 && index < rightList.length) {
  321. return rightList[index];
  322. } else {
  323. return null;
  324. }
  325. }
  326. @override
  327. String leftDivider() {
  328. return ":";
  329. }
  330. @override
  331. String rightDivider() {
  332. return ":";
  333. }
  334. @override
  335. DateTime finalTime() {
  336. return DateTime(currentTime.year, currentTime.month, currentTime.day, _currentLeftIndex, _currentMiddleIndex, _currentRightIndex);
  337. }
  338. }
  339. class DateTimePickerModel extends CommonPickerModel {
  340. DateTimePickerModel({DateTime currentTime, LocaleType locale}) : super(locale: locale) {
  341. this.currentTime = currentTime ?? DateTime.now();
  342. _currentLeftIndex = 0;
  343. _currentMiddleIndex = this.currentTime.hour;
  344. _currentRightIndex = this.currentTime.minute;
  345. }
  346. @override
  347. String leftStringAtIndex(int index) {
  348. DateTime time = currentTime.add(Duration(days: index));
  349. return formatDate(time, [ymdw], locale);
  350. }
  351. @override
  352. String middleStringAtIndex(int index) {
  353. if (index >= 0 && index < 24) {
  354. return digits(index, 2);
  355. } else {
  356. return null;
  357. }
  358. }
  359. @override
  360. String rightStringAtIndex(int index) {
  361. if (index >= 0 && index < 60) {
  362. return digits(index, 2);
  363. } else {
  364. return null;
  365. }
  366. }
  367. @override
  368. DateTime finalTime() {
  369. DateTime time = currentTime.add(Duration(days: _currentLeftIndex));
  370. return DateTime(time.year, time.month, time.day, _currentMiddleIndex, _currentRightIndex);
  371. }
  372. @override
  373. List<int> layoutProportions() {
  374. return [3, 1, 1];
  375. }
  376. @override
  377. String rightDivider() {
  378. return ':';
  379. }
  380. }