/// month->days. Map MONTH_DAY = { 1: 31, 2: 28, 3: 31, 4: 30, 5: 31, 6: 30, 7: 31, 8: 31, 9: 30, 10: 31, 11: 30, 12: 31, }; /// ISO 8601 标准的时间格式字符串 /// 时间与日期的格式化工具类(自定义基于Dart原生Api-DateTime实现) class DateTimeUtils { static String full = 'yyyy-MM-dd HH:mm:ss'; //如 2023-05-25 12:05:03 // ===================================== 反格式化时间 ↓ ===================================== /* 根据指定日期格式得到原生的DateTime对象 使用: final date = DateTimeUtils.getDateTime('2023-10-21'); 打印结果 DateTime 对象为:2023-10-21 00:00:00.000 final date = DateTimeUtils.getDateTime('2023-10-21 12:08:55'); 打印结果 DateTime 对象为:2023-10-21 12:08:55.000 final date = DateTimeUtils.getDateTime('2023-10-21 12:55'); 打印结果 DateTime 对象为:2023-10-21 12:55:00.000 final date = DateTimeUtils.getDateTime('2023/10/21 12:08:55'); 这样就不行,因为 2023/10/21 12:08:55 不是标准格式无法转换为 DateTime 对象,必须要 2012-02-27 或 2012-02-27 13:27:00 标准格式 */ static DateTime? getDateTime(String dateStr, {bool? isUtc}) { DateTime? dateTime = DateTime.tryParse(dateStr); if (isUtc != null) { if (isUtc) { dateTime = dateTime?.toUtc(); } else { dateTime = dateTime?.toLocal(); } } return dateTime; } /* 根据指定的毫秒时间戳得到原生的DateTime对象 使用: final date = DateTimeUtils.getDateTimeByMs(1682304352000) 打印结果 DateTime 对象为:2023-04-24 10:45:52.000 */ static DateTime getDateTimeByMs(int ms, {bool isUtc = false}) { return DateTime.fromMillisecondsSinceEpoch(ms, isUtc: isUtc); } /* 根据日期格式得到对应的毫秒值 使用: final date = DateTimeUtils.getDateMsByTimeStr('2023-10-21'); 打印结果为:1697817600000 final date = DateTimeUtils.getDateMsByTimeStr('2023-10-21 12:08:55'); 打印结果为:1697861335000 final date = DateTimeUtils.getDateMsByTimeStr('2023-10-21 12:55'); 打印结果为:1697864100000 */ static int? getDateMsByTimeStr(String dateStr, {bool? isUtc}) { DateTime? dateTime = getDateTime(dateStr, isUtc: isUtc); return dateTime?.millisecondsSinceEpoch; } /* 获取当前系统日期的毫秒值 使用: final date = DateTimeUtils.getNowDateMs(); 打印结果为:1697817600000 */ static int getNowDateMs() { return DateTime.now().millisecondsSinceEpoch; } // ===================================== 反格式化时间 ↑ ===================================== // ===================================== 格式化时间 ↓ ===================================== /* 获取当前系统日期的格式化时间值。默认格式为 yyyy-MM-dd HH:mm:ss 使用: final date = DateTimeUtils.getNowDateStr(); 打印结果为:2023-10-09 09:54:26 final date = DateTimeUtils.getNowDateStr(format: 'yyyy-MM-dd'); 打印结果为:2023-10-09 final date = DateTimeUtils.getNowDateStr(format: 'yyyy-MM-dd HH:mm'); 打印结果为:2023-10-09 09:55 final date = DateTimeUtils.getNowDateStr(format: 'yyyy-MMM-dd HH:mm'); 打印结果为:2023-Oct-09 09:56 final date = DateTimeUtils.getNowDateStr(format: 'yyyy/MMM/dd HH:mm'); 打印结果为:2023/Oct/09 09:57 final date = DateTimeUtils.getNowDateStr(format: 'dd MMM yyyy HH:mm'); 打印结果为:09 Oct 2023 09:58 */ static String formatNowDateStr({String? format, bool isMonthEn = true, bool isMonthEnShort = true}) { return formatDate(DateTime.now(), format: format, isMonthEn: isMonthEn, isMonthEnShort: isMonthEnShort); } /* 根据指定的毫秒时间戳格式化时间值。默认格式为 yyyy-MM-dd HH:mm:ss 使用: final date = DateTimeUtils.formatDateMs(1682304352000,format: 'yyyy-MM-dd') 打印结果为:2023-04-24 final date = DateTimeUtils.formatDateMs(1682304352000,format: 'dd MMM yyyy HH:mm'); 打印结果为:24 Apr 2023 10:45 */ static String formatDateMs(int ms, {bool isUtc = false, String? format, bool isMonthEn = true, bool isMonthEnShort = true}) { return formatDate(getDateTimeByMs(ms, isUtc: isUtc), format: format, isMonthEn: isMonthEn, isMonthEnShort: isMonthEnShort); } /* 根据指定的日期字符串格式化时间值。默认格式为 yyyy-MM-dd HH:mm:ss @Parmas dateStr 参数必须是标准格式如 2012-02-27 或 2012-02-27 13:27:00 ,format的转换格式可以随便写 使用: final date = DateTimeUtils.formatDateStr('2023-10-21 12:08:55',format: 'dd MMM yyyy'); 打印结果为:21 Oct 2023 12:08 final date = DateTimeUtils.formatDateStr('2023-10-21 12:08:55',format: 'yyyy-MM-dd'); 打印结果为:2023-10-21 final date = DateTimeUtils.formatDateStr('2023/10/21 12:08:55',format: 'yyyy-MM-dd'); 这样就不行,因为 2023/10/21 12:08:55 不是标准格式无法转换为 DateTime 对象 */ static String formatDateStr(String dateStr, {bool? isUtc, String? format, bool isMonthEn = true, bool isMonthEnShort = true}) { return formatDate(getDateTime(dateStr, isUtc: isUtc), format: format, isMonthEn: isMonthEn, isMonthEnShort: isMonthEnShort); } /* 总方法 - 根据标准的 DateTime 来格式化时间。默认格式为 yyyy-MM-dd HH:mm:ss 使用: final date = DateTimeUtils.formatDate(date, format: "yyyy-MM-dd"); 打印结果为:2023-10-09 */ static String formatDate(DateTime? dateTime, {String? format, bool isMonthEn = true, bool isMonthEnShort = true}) { if (dateTime == null) return ''; format = format ?? full; //对Year的处理 if (format.contains('yy')) { String year = dateTime.year.toString(); if (format.contains('yyyy')) { format = format.replaceAll('yyyy', year); } else { format = format.replaceAll('yy', year.substring(year.length - 2, year.length)); } } //对Month的处理 int month = dateTime.month; if (format.contains("M")) { if (format.contains("MM")) { if (format.contains("MMM")) { if (format.contains("MMMM")) { //处理4个M,英文显示 format = format.replaceAll("MMMM", getMonthEnStr(month, true, false)); } else { //处理3个M,英文显示 format = format.replaceAll("MMM", getMonthEnStr(month, isMonthEn, isMonthEnShort)); } } else { //处理2个M format = format.replaceAll("MM", month < 10 ? '0$month' : month.toString()); } } else { //处理1个M format = format.replaceAll("M", month.toString()); } } //对其他的处理 format = _comFormat(dateTime.day, format, 'd', 'dd'); format = _comFormat(dateTime.hour, format, 'H', 'HH'); format = _comFormat(dateTime.minute, format, 'm', 'mm'); format = _comFormat(dateTime.second, format, 's', 'ss'); format = _comFormat(dateTime.millisecond, format, 'S', 'SSS'); return format; } //格式化1位数为2位数,前面加0 如:2008-01-05 08:05:04 static String _comFormat(int value, String format, String single, String full) { if (format.contains(single)) { if (format.contains(full)) { format = format.replaceAll(full, value < 10 ? '0$value' : value.toString()); } else { format = format.replaceAll(single, value.toString()); } } return format; } // 返回自己的月份字符串信息 static String getMonthEnStr(int month, bool isMonthEn, bool isMonthEnShort) { String monthStr = month.toString(); switch (month) { case 1: monthStr = !isMonthEn ? month.toString() : isMonthEnShort ? "Jan" : "January"; break; case 2: monthStr = !isMonthEn ? month.toString() : isMonthEnShort ? "Feb" : "February"; break; case 3: monthStr = !isMonthEn ? month.toString() : isMonthEnShort ? "Mar" : "March"; break; case 4: monthStr = !isMonthEn ? month.toString() : isMonthEnShort ? "Apr" : "April"; break; case 5: monthStr = !isMonthEn ? month.toString() : isMonthEnShort ? "May" : "May"; break; case 6: monthStr = !isMonthEn ? month.toString() : isMonthEnShort ? "Jun" : "June"; break; case 7: monthStr = !isMonthEn ? month.toString() : isMonthEnShort ? "Jul" : "July"; break; case 8: monthStr = !isMonthEn ? month.toString() : isMonthEnShort ? "Aug" : "August"; break; case 9: monthStr = !isMonthEn ? month.toString() : isMonthEnShort ? "Sep" : "September"; break; case 10: monthStr = !isMonthEn ? month.toString() : isMonthEnShort ? "Oct" : "October"; break; case 11: monthStr = !isMonthEn ? month.toString() : isMonthEnShort ? "Nov" : "November"; break; case 12: monthStr = !isMonthEn ? month.toString() : isMonthEnShort ? "Dec" : "December"; break; } return monthStr; } /// 获取输入时间是星期几 static String getWeekdayByMs(int milliseconds, {bool isUtc = false, String languageCode = 'en', bool short = false}) { DateTime dateTime = getDateTimeByMs(milliseconds, isUtc: isUtc); return getWeekday(dateTime, languageCode: languageCode, short: short); } /* 根据标准的 DateTime 对象,获取 weekDay 属性,并返回自己的星期字符串 */ static String getWeekday(DateTime? dateTime, {String languageCode = 'zh', bool short = false}) { if (dateTime == null) return ""; String weekday = ""; switch (dateTime.weekday) { case 1: weekday = languageCode == 'zh' ? '星期一' : 'Monday'; break; case 2: weekday = languageCode == 'zh' ? '星期二' : 'Tuesday'; break; case 3: weekday = languageCode == 'zh' ? '星期三' : 'Wednesday'; break; case 4: weekday = languageCode == 'zh' ? '星期四' : 'Thursday'; break; case 5: weekday = languageCode == 'zh' ? '星期五' : 'Friday'; break; case 6: weekday = languageCode == 'zh' ? '星期六' : 'Saturday'; break; case 7: weekday = languageCode == 'zh' ? '星期日' : 'Sunday'; break; default: break; } return languageCode == 'zh' ? (short ? weekday.replaceAll('星期', '周') : weekday) : weekday.substring(0, short ? 3 : weekday.length); } /// 在今年的第几天. static int getDayOfYear(DateTime dateTime) { int year = dateTime.year; int month = dateTime.month; int days = dateTime.day; for (int i = 1; i < month; i++) { days = days + MONTH_DAY[i]!; } if (isLeapYearByYear(year) && month > 2) { days = days + 1; } return days; } /// 在今年的第几天. static int getDayOfYearByMs(int ms, {bool isUtc = false}) { return getDayOfYear(DateTime.fromMillisecondsSinceEpoch(ms, isUtc: isUtc)); } /// 是否是当天. static bool isToday(int? milliseconds, {bool isUtc = false, int? locMs}) { if (milliseconds == null || milliseconds == 0) return false; DateTime old = DateTime.fromMillisecondsSinceEpoch(milliseconds, isUtc: isUtc); DateTime now; if (locMs != null) { now = DateTimeUtils.getDateTimeByMs(locMs); } else { now = isUtc ? DateTime.now().toUtc() : DateTime.now().toLocal(); } return old.year == now.year && old.month == now.month && old.day == now.day; } /// 是否是昨天. static bool isYesterday(DateTime dateTime, DateTime locDateTime) { if (yearIsEqual(dateTime, locDateTime)) { int spDay = getDayOfYear(locDateTime) - getDayOfYear(dateTime); return spDay == 1; } else { return ((locDateTime.year - dateTime.year == 1) && dateTime.month == 12 && locDateTime.month == 1 && dateTime.day == 31 && locDateTime.day == 1); } } /// 是否是昨天. static bool isYesterdayByMs(int ms, int locMs) { return isYesterday(DateTime.fromMillisecondsSinceEpoch(ms), DateTime.fromMillisecondsSinceEpoch(locMs)); } /// 是否是本周. static bool isWeek(int? ms, {bool isUtc = false, int? locMs}) { if (ms == null || ms <= 0) { return false; } DateTime _old = DateTime.fromMillisecondsSinceEpoch(ms, isUtc: isUtc); DateTime _now; if (locMs != null) { _now = DateTimeUtils.getDateTimeByMs(locMs, isUtc: isUtc); } else { _now = isUtc ? DateTime.now().toUtc() : DateTime.now().toLocal(); } DateTime old = _now.millisecondsSinceEpoch > _old.millisecondsSinceEpoch ? _old : _now; DateTime now = _now.millisecondsSinceEpoch > _old.millisecondsSinceEpoch ? _now : _old; return (now.weekday >= old.weekday) && (now.millisecondsSinceEpoch - old.millisecondsSinceEpoch <= 7 * 24 * 60 * 60 * 1000); } /// 是否同年. static bool yearIsEqual(DateTime dateTime, DateTime locDateTime) { return dateTime.year == locDateTime.year; } /// 是否同年. static bool yearIsEqualByMs(int ms, int locMs) { return yearIsEqual(DateTime.fromMillisecondsSinceEpoch(ms), DateTime.fromMillisecondsSinceEpoch(locMs)); } /// 是否是闰年 static bool isLeapYear(DateTime dateTime) { return isLeapYearByYear(dateTime.year); } /// 是否是闰年 static bool isLeapYearByYear(int year) { return year % 4 == 0 && year % 100 != 0 || year % 400 == 0; } /// 输入时间距离当前时间有多少年 static int distanceCurrentYear(DateTime date) { Duration difference = DateTime.now().difference(date); return (difference.inDays / 365).floor(); } /// 输入时间距离当前时间有多少天 static int distanceCurrentDay(DateTime date) { Duration difference = DateTime.now().difference(date); return difference.inDays; } }