#include <iostream> using namespace std; int ymdToWeekNumber (int y, int m, int d) { // reject out-of-range input if ((y < 1583)||(y > 25000)) return 0; if ((m < 1)||(m > 12)) return 0; if ((d < 1)||(d > 31)) return 0; // compute correction for year // If Jan. 1 falls on: Mo Tu We Th Fr Sa Su // then the correction is: 0 +1 +2 +3 -3 -2 -1 int corr = ((y + 2 + (y-1)/4 - (y-1)/100 + (y-1)/400) % 7) - 3; // compute day of the year (in range 1-366) int doy = d; if (m > 1) doy += 31; if (m > 2) doy += (((y%100) ? (y%4) : (y%400)) ? 28 : 29); if (m > 3) doy += 31; if (m > 4) doy += 30; if (m > 5) doy += 31; if (m > 6) doy += 30; if (m > 7) doy += 31; if (m > 8) doy += 31; if (m > 9) doy += 30; if (m > 10) doy += 31; if (m > 11) doy += 30; // compute corrected day number int cdn = corr + doy; // compute number of weeks, rounding up to nearest whole week // this gives us our week number int wknum = ((cdn + 6) / 7); // check for boundary conditions: // if our calculation would give us "week 0", // then it is really the final week of the previous year // and we need to find out whether that is week 52 or week 53 if (wknum < 1) { // first, compute correction for the previous year corr = ((y + 1 + (y-2)/4 - (y-2)/100 + (y-2)/400) % 7) - 3; // then, compute day of year with respect to that same previous year doy = d + ((((y-1)%100) ? ((y-1)%4) : ((y-1)%400)) ? 365 : 366); // finally, re-compute the corrected day number and the week number cdn = corr + doy; wknum = ((cdn + 6) / 7); return wknum; } // if our calculation would give us "week 53", // we need to find out whether week 53 really exists, // or whether it is week 1 of the following year if (wknum > 52) { // check for year beginning on Thurs. if (corr==3) return 53; // check for leap year beginning on Wed. if (((y%4)==0) && (corr==2)) return 53; // otherwise, there is no week 53 return 1; } return wknum; } int main() { cout << "Week number test\n"; int y, m, d; srand(15000); for (int i=1996; i<=2030; i++) { y=i; m=1; d=1; cout << y << "/" << m << "/" << d << " "; cout << ymdToWeekNumber(y,m,d) << "\n"; m=1+(rand()%2); d=2+(rand()%26); cout << y << "/" << m << "/" << d << " "; cout << ymdToWeekNumber(y,m,d) << "\n"; m=2; d=28; cout << y << "/" << m << "/" << d << " "; cout << ymdToWeekNumber(y,m,d) << "\n"; if ((y%4)==0) { m=2; d=29; cout << y << "/" << m << "/" << d << " "; cout << ymdToWeekNumber(y,m,d) << "\n"; } m=3; d=1; cout << y << "/" << m << "/" << d << " "; cout << ymdToWeekNumber(y,m,d) << "\n"; m=3+(rand()%4); d=2+(rand()%29); cout << y << "/" << m << "/" << d << " "; cout << ymdToWeekNumber(y,m,d) << "\n"; m=7+(rand()%3); d=1+(rand()%30); cout << y << "/" << m << "/" << d << " "; cout << ymdToWeekNumber(y,m,d) << "\n"; m=10+(rand()%3); d=1+(rand()%30); cout << y << "/" << m << "/" << d << " "; cout << ymdToWeekNumber(y,m,d) << "\n"; m=12; d=31; cout << y << "/" << m << "/" << d << " "; cout << ymdToWeekNumber(y,m,d) << "\n"; } return 0; }
Standard input is empty
Week number test 1996/1/1 1 1996/2/21 8 1996/2/28 9 1996/2/29 9 1996/3/1 9 1996/5/12 19 1996/7/1 27 1996/11/3 44 1996/12/31 1 1997/1/1 1 1997/2/23 8 1997/2/28 9 1997/3/1 9 1997/5/15 20 1997/8/19 34 1997/10/28 44 1997/12/31 1 1998/1/1 1 1998/2/14 7 1998/2/28 9 1998/3/1 9 1998/4/27 18 1998/8/9 32 1998/11/1 44 1998/12/31 53 1999/1/1 53 1999/2/15 7 1999/2/28 8 1999/3/1 9 1999/5/9 18 1999/7/29 30 1999/12/21 51 1999/12/31 52 2000/1/1 52 2000/2/20 7 2000/2/28 9 2000/2/29 9 2000/3/1 9 2000/4/14 15 2000/9/20 38 2000/10/13 41 2000/12/31 52 2001/1/1 1 2001/2/21 8 2001/2/28 9 2001/3/1 9 2001/6/13 24 2001/7/30 31 2001/12/20 51 2001/12/31 1 2002/1/1 1 2002/1/6 1 2002/2/28 9 2002/3/1 9 2002/4/25 17 2002/8/19 34 2002/12/25 52 2002/12/31 1 2003/1/1 1 2003/1/18 3 2003/2/28 9 2003/3/1 9 2003/6/6 23 2003/8/16 33 2003/10/8 41 2003/12/31 1 2004/1/1 1 2004/2/2 6 2004/2/28 9 2004/2/29 9 2004/3/1 10 2004/5/2 18 2004/7/6 28 2004/12/22 52 2004/12/31 53 2005/1/1 53 2005/1/8 1 2005/2/28 9 2005/3/1 9 2005/6/6 23 2005/7/12 28 2005/12/20 51 2005/12/31 52 2006/1/1 52 2006/2/12 6 2006/2/28 9 2006/3/1 9 2006/5/29 22 2006/9/3 35 2006/11/27 48 2006/12/31 52 2007/1/1 1 2007/2/21 8 2007/2/28 9 2007/3/1 9 2007/6/29 26 2007/7/29 30 2007/11/30 48 2007/12/31 1 2008/1/1 1 2008/2/11 7 2008/2/28 9 2008/2/29 9 2008/3/1 9 2008/5/5 19 2008/8/14 33 2008/11/20 47 2008/12/31 1 2009/1/1 1 2009/2/19 8 2009/2/28 9 2009/3/1 9 2009/6/19 25 2009/9/29 40 2009/10/27 44 2009/12/31 53 2010/1/1 53 2010/1/20 3 2010/2/28 8 2010/3/1 9 2010/5/3 18 2010/9/5 35 2010/10/4 40 2010/12/31 52 2011/1/1 52 2011/2/11 6 2011/2/28 9 2011/3/1 9 2011/4/20 16 2011/7/11 28 2011/11/13 45 2011/12/31 52 2012/1/1 52 2012/2/22 8 2012/2/28 9 2012/2/29 9 2012/3/1 9 2012/6/27 26 2012/8/30 35 2012/10/5 40 2012/12/31 1 2013/1/1 1 2013/2/23 8 2013/2/28 9 2013/3/1 9 2013/4/30 18 2013/9/16 38 2013/12/15 50 2013/12/31 1 2014/1/1 1 2014/2/11 7 2014/2/28 9 2014/3/1 9 2014/6/28 26 2014/8/20 34 2014/11/9 45 2014/12/31 1 2015/1/1 1 2015/1/18 3 2015/2/28 9 2015/3/1 9 2015/6/29 27 2015/7/29 31 2015/10/16 42 2015/12/31 53 2016/1/1 53 2016/1/27 4 2016/2/28 8 2016/2/29 9 2016/3/1 9 2016/3/22 12 2016/8/1 31 2016/10/21 42 2016/12/31 52 2017/1/1 52 2017/2/9 6 2017/2/28 9 2017/3/1 9 2017/6/18 24 2017/8/18 33 2017/10/14 41 2017/12/31 52 2018/1/1 1 2018/1/23 4 2018/2/28 9 2018/3/1 9 2018/6/22 25 2018/9/3 36 2018/11/25 47 2018/12/31 1 2019/1/1 1 2019/1/8 2 2019/2/28 9 2019/3/1 9 2019/5/28 22 2019/7/7 27 2019/11/9 45 2019/12/31 1 2020/1/1 1 2020/2/25 9 2020/2/28 9 2020/2/29 9 2020/3/1 9 2020/5/9 19 2020/9/12 37 2020/12/10 50 2020/12/31 53 2021/1/1 53 2021/1/2 53 2021/2/28 8 2021/3/1 9 2021/3/6 9 2021/9/17 37 2021/10/26 43 2021/12/31 52 2022/1/1 52 2022/1/9 1 2022/2/28 9 2022/3/1 9 2022/4/3 13 2022/7/5 27 2022/11/2 44 2022/12/31 52 2023/1/1 52 2023/1/19 3 2023/2/28 9 2023/3/1 9 2023/6/7 23 2023/9/30 39 2023/10/11 41 2023/12/31 52 2024/1/1 1 2024/1/27 4 2024/2/28 9 2024/2/29 9 2024/3/1 9 2024/4/10 15 2024/8/18 33 2024/12/5 49 2024/12/31 1 2025/1/1 1 2025/2/11 7 2025/2/28 9 2025/3/1 9 2025/4/22 17 2025/7/15 29 2025/10/23 43 2025/12/31 1 2026/1/1 1 2026/2/25 9 2026/2/28 9 2026/3/1 9 2026/5/2 18 2026/8/16 33 2026/10/18 42 2026/12/31 53 2027/1/1 53 2027/1/26 4 2027/2/28 8 2027/3/1 9 2027/4/9 14 2027/7/7 27 2027/10/20 42 2027/12/31 52 2028/1/1 52 2028/2/15 7 2028/2/28 9 2028/2/29 9 2028/3/1 9 2028/6/8 23 2028/9/27 39 2028/10/13 41 2028/12/31 52 2029/1/1 1 2029/1/17 3 2029/2/28 9 2029/3/1 9 2029/5/5 18 2029/8/9 32 2029/10/27 43 2029/12/31 1 2030/1/1 1 2030/1/12 2 2030/2/28 9 2030/3/1 9 2030/6/3 23 2030/7/9 28 2030/12/3 49 2030/12/31 1