最近遇到一个需求,计算当前年份有多少周,网上查阅了资料得到以下计算方式:
/// Calculates number of weeks for a given year as per https://en.wikipedia.org/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 https://en.wikipedia.org/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:2021-03-15 00:00:00.000
// flutter: target week end day:2021-03-21 23:59:59.999
}
其中,最先得到周的最后一天的0点0分,倒推7天后,因为是从0点0分开始的,所以要加上1天的时间。完整的一周就是从2021-03-15 00:00:00.000 到 2021-03-21 23:59:59.999,超过1毫秒就跑到下周去了。
至于每年开始的第一周和每年末尾的最后一周算法我参考的https://en.wikipedia.org/wiki/ISO_week_date 上面有公式。