最近遇到一个需求,计算当前年份有多少周,网上查阅了资料得到以下计算方式:
/// Calculates number of weeks for a given year as per /wiki/ISO_week_date#Weeks_per_year/// 一年的最后一周(等于说就是一年总共多少周)static int numOfWeeks(int year) {DateTime dec28 = DateTime(year, 12, 28);int dayOfDec28 = int.parse(DateFormat("D").format(dec28));return ((dayOfDec28 - dec28.weekday + 10) / 7).floor();}/// Calculates week number from a date as per /wiki/ISO_week_date#Calculation/// 当前日期在当年度的第几周static int weekNumber(DateTime date) {int dayOfYear = int.parse(DateFormat("D").format(date));int woy = ((dayOfYear - date.weekday + 10) / 7).floor();if (woy < 1) {woy = numOfWeeks(date.year - 1);} else if (woy > numOfWeeks(date.year)) {woy = 1;}return woy;}
那么问题就来了,后续用到的时候需要将这个周当前序号还原成开始和结束的日期,想了半天最后用时间戳的方式将其转换回来:
/// 根据year年的第week周,查询本周的开始和截止日期static void weekToDayFormat(int year, int week) {int dayMills = 24 * 60 * 60 * 1000;int weekMills = 7 * dayMills;DateTime dateTime = DateTime(year, 1, 4);int targetTimeStamp =dateTime.millisecondsSinceEpoch + (week * 7 - dateTime.weekday) * dayMills;print('start :${DateTime.fromMillisecondsSinceEpoch(targetTimeStamp - weekMills + dayMills)}');print('end :${DateTime.fromMillisecondsSinceEpoch(targetTimeStamp + dayMills - 1)}');// flutter: target week start day:-03-15 00:00:00.000// flutter: target week end day:-03-21 23:59:59.999}
其中,最先得到周的最后一天的0点0分,倒推7天后,因为是从0点0分开始的,所以要加上1天的时间。完整的一周就是从-03-15 00:00:00.000 到-03-21 23:59:59.999,超过1毫秒就跑到下周去了。
至于每年开始的第一周和每年末尾的最后一周算法我参考的/wiki/ISO_week_date 上面有公式。