age_zodiac_sign_util.dart 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178
  1. import 'package:intl/intl.dart';
  2. import '../resource/assets.gen.dart';
  3. class AgeZodiacSignUtil {
  4. AgeZodiacSignUtil._();
  5. static List<Zodiac> zodiacs = [
  6. Zodiac(name: '白羊座', image: Assets.images.iconAries),
  7. Zodiac(name: '金牛座', image: Assets.images.iconTaurus),
  8. Zodiac(name: '双子座', image: Assets.images.iconGemini),
  9. Zodiac(name: '巨蟹座', image: Assets.images.iconCancer),
  10. Zodiac(name: '狮子座', image: Assets.images.iconLeo),
  11. Zodiac(name: '处女座', image: Assets.images.iconVirgo),
  12. Zodiac(name: '天秤座', image: Assets.images.iconLibra),
  13. Zodiac(name: '天蝎座', image: Assets.images.iconScorpio),
  14. Zodiac(name: '射手座', image: Assets.images.iconSagittarius),
  15. Zodiac(name: '摩羯座', image: Assets.images.iconCapricorn),
  16. Zodiac(name: '水瓶座', image: Assets.images.iconAquarius),
  17. Zodiac(name: '双鱼座', image: Assets.images.iconPisces),
  18. ];
  19. /// 计算星座(传入 DateTime)
  20. /// 通过生日获取 Zodiac 对象(包含名称和图片)
  21. static Zodiac getZodiacSign(DateTime date) {
  22. int month = date.month;
  23. int day = date.day;
  24. String sign;
  25. if ((month == 3 && day >= 21) || (month == 4 && day <= 19)) {
  26. sign = '白羊座';
  27. } else if ((month == 4 && day >= 20) || (month == 5 && day <= 20)) {
  28. sign = '金牛座';
  29. } else if ((month == 5 && day >= 21) || (month == 6 && day <= 20)) {
  30. sign = '双子座';
  31. } else if ((month == 6 && day >= 21) || (month == 7 && day <= 22)) {
  32. sign = '巨蟹座';
  33. } else if ((month == 7 && day >= 23) || (month == 8 && day <= 22)) {
  34. sign = '狮子座';
  35. } else if ((month == 8 && day >= 23) || (month == 9 && day <= 22)) {
  36. sign = '处女座';
  37. } else if ((month == 9 && day >= 23) || (month == 10 && day <= 22)) {
  38. sign = '天秤座';
  39. } else if ((month == 10 && day >= 23) || (month == 11 && day <= 21)) {
  40. sign = '天蝎座';
  41. } else if ((month == 11 && day >= 22) || (month == 12 && day <= 21)) {
  42. sign = '射手座';
  43. } else if ((month == 12 && day >= 22) || (month == 1 && day <= 19)) {
  44. sign = '摩羯座';
  45. } else if ((month == 1 && day >= 20) || (month == 2 && day <= 18)) {
  46. sign = '水瓶座';
  47. } else if ((month == 2 && day >= 19) || (month == 3 && day <= 20)) {
  48. sign = '双鱼座';
  49. } else {
  50. return const Zodiac(name: '未知星座', image: AssetGenImage('')); // 空图片占位
  51. }
  52. return zodiacs.firstWhere(
  53. (zodiac) => zodiac.name == sign,
  54. orElse: () => const Zodiac(name: '未知星座', image: AssetGenImage('')),
  55. );
  56. }
  57. /// 计算年龄(传入 DateTime)
  58. static int calculateAge(DateTime birthDate) {
  59. DateTime currentDate = DateTime.now();
  60. int age = currentDate.year - birthDate.year;
  61. if (currentDate.month < birthDate.month ||
  62. (currentDate.month == birthDate.month &&
  63. currentDate.day < birthDate.day)) {
  64. age--;
  65. }
  66. return age;
  67. }
  68. /// 从字符串计算星座
  69. static Zodiac getZodiacSignFromString(
  70. String dateStr, {
  71. String format = 'yyyy-MM-dd',
  72. }) {
  73. try {
  74. DateTime date = DateFormat(format).parse(dateStr);
  75. return getZodiacSign(date);
  76. } catch (e) {
  77. return const Zodiac(name: '未知星座', image: AssetGenImage(''));
  78. }
  79. }
  80. /// 从字符串计算年龄
  81. static int? calculateAgeFromString(
  82. String dateStr, {
  83. String format = 'yyyy-MM-dd',
  84. }) {
  85. try {
  86. DateTime date = DateFormat(format).parse(dateStr);
  87. return calculateAge(date);
  88. } catch (e) {
  89. return null;
  90. }
  91. }
  92. /// 格式化生日(传入字符串)
  93. static String? formatBirthdayFromString(
  94. String? dateStr, {
  95. String outputFormat = 'yyyy-MM-dd',
  96. }) {
  97. if (dateStr == null || dateStr.isEmpty) return null;
  98. final possibleFormats = [
  99. 'yyyy-MM-dd',
  100. 'yyyy/MM/dd',
  101. 'yyyy-MM-dd HH:mm:ss',
  102. 'yyyy/MM/dd HH:mm:ss',
  103. "yyyy-MM-dd'T'HH:mm:ss'Z'",
  104. "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
  105. 'yyyy-MM-dd HH:mm:sss',
  106. ];
  107. for (var format in possibleFormats) {
  108. try {
  109. DateTime date = DateFormat(format).parseStrict(dateStr);
  110. return DateFormat(outputFormat).format(date);
  111. } catch (e) {
  112. // 忽略失败,尝试下一个格式
  113. }
  114. }
  115. return null;
  116. }
  117. static Zodiac getZodiacWithGenderLabel(
  118. String birthStr,
  119. int genderCode, {
  120. String format = 'yyyy-MM-dd',
  121. }) {
  122. final zodiac = getZodiacSignFromString(birthStr, format: format);
  123. final gender = genderCode == 1 ? '男' : genderCode == 2 ? '女' : '';
  124. final baseName = zodiac.name.replaceAll('座', '');
  125. return Zodiac(name: '$baseName$gender', image: zodiac.image);
  126. }
  127. }
  128. class Zodiac {
  129. final String name;
  130. final AssetGenImage image;
  131. const Zodiac({required this.name, required this.image});
  132. }
  133. class DateComponents {
  134. final String yearPart;
  135. final String monthPart;
  136. final String dayPart;
  137. const DateComponents({
  138. required this.yearPart,
  139. required this.monthPart,
  140. required this.dayPart,
  141. });
  142. /// 从 DateTime 生成格式化数据
  143. factory DateComponents.fromDateTime(DateTime date) {
  144. return DateComponents(
  145. yearPart: DateFormat('yyyy').format(date),
  146. monthPart: DateFormat('MM').format(date),
  147. dayPart: DateFormat('dd').format(date),
  148. );
  149. }
  150. static String getZodiacLabel(Zodiac zodiac, String gender) {
  151. final name = zodiac.name.replaceAll('座', '');
  152. return '$name$gender'; // gender: '男' 或 '女'
  153. }
  154. String toFormattedString() => '$yearPart年$monthPart月$dayPart日';
  155. }