#include <iostream> using namespace std; int ymdToWeekNumber (int y, int m, int d) { // reject out-of-range input if ((y < 1901)||(y > 2099)) 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 - 1881) * 5) / 4) % 7) - 3; // compute day of the year (in range 1-366) int doy = d; if (m > 1) doy += 31; if (m > 2) doy += (((y%4)==0) ? 29 : 28); 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; // check for boundary conditions // 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 (cdn > 364) { // 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; } // if our calculation would give us "week 0", // then go to the previous year // and find out whether we are in week 52 or week 53 if (cdn < 1) { // first, compute correction for the previous year corr = ((((y - 1882) * 5) / 4) % 7) - 3; // then, compute day of year with respect to that same previous year doy = d + (((y%4)==1)?366:365); // finally, re-compute the corrected day number cdn = corr + doy; } // compute number of weeks, rounding up to nearest whole week return ((cdn + 6) / 7); } int main() { cout << "Week number test\n"; int y, m, d; srand(8117); for (int i=2010; i<=2050; i++) { y=i; m=1; d=1; cout << y << "/" << m << "/" << d << " "; cout << ymdToWeekNumber(y,m,d) << "\n"; m=1+(rand()%3); d=2+(rand()%27); cout << y << "/" << m << "/" << d << " "; cout << ymdToWeekNumber(y,m,d) << "\n"; m=4+(rand()%3); d=1+(rand()%30); 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 2010/1/1 53 2010/2/26 8 2010/5/16 19 2010/8/20 33 2010/10/13 41 2010/12/31 52 2011/1/1 52 2011/3/26 12 2011/6/23 25 2011/8/26 34 2011/11/13 45 2011/12/31 52 2012/1/1 52 2012/1/28 4 2012/5/10 19 2012/7/28 30 2012/12/20 51 2012/12/31 1 2013/1/1 1 2013/3/19 12 2013/4/5 14 2013/8/10 32 2013/11/16 46 2013/12/31 1 2014/1/1 1 2014/3/22 12 2014/5/2 18 2014/8/6 32 2014/11/29 48 2014/12/31 1 2015/1/1 1 2015/1/16 3 2015/4/21 17 2015/8/17 34 2015/10/18 42 2015/12/31 53 2016/1/1 53 2016/1/14 2 2016/4/11 15 2016/7/24 29 2016/12/7 49 2016/12/31 52 2017/1/1 52 2017/3/2 9 2017/4/8 14 2017/9/5 36 2017/12/11 50 2017/12/31 52 2018/1/1 1 2018/2/6 6 2018/4/30 18 2018/7/10 28 2018/11/26 48 2018/12/31 1 2019/1/1 1 2019/3/6 10 2019/5/11 19 2019/7/3 27 2019/10/29 44 2019/12/31 1 2020/1/1 1 2020/3/21 12 2020/6/11 24 2020/9/1 36 2020/12/12 50 2020/12/31 53 2021/1/1 53 2021/1/28 4 2021/4/27 17 2021/8/4 31 2021/11/30 48 2021/12/31 52 2022/1/1 52 2022/2/17 7 2022/4/12 15 2022/7/11 28 2022/10/1 39 2022/12/31 52 2023/1/1 52 2023/1/22 3 2023/5/22 21 2023/9/1 35 2023/12/21 51 2023/12/31 52 2024/1/1 1 2024/2/7 6 2024/5/23 21 2024/9/2 36 2024/10/19 42 2024/12/31 1 2025/1/1 1 2025/2/18 8 2025/4/13 15 2025/8/28 35 2025/10/16 42 2025/12/31 1 2026/1/1 1 2026/1/23 4 2026/4/17 16 2026/9/17 38 2026/11/10 46 2026/12/31 53 2027/1/1 53 2027/2/5 5 2027/5/11 19 2027/7/5 27 2027/11/19 46 2027/12/31 52 2028/1/1 52 2028/2/12 6 2028/5/8 19 2028/9/15 37 2028/11/5 44 2028/12/31 52 2029/1/1 1 2029/2/2 5 2029/5/24 21 2029/8/21 34 2029/10/5 40 2029/12/31 1 2030/1/1 1 2030/1/11 2 2030/6/12 24 2030/7/29 31 2030/10/29 44 2030/12/31 1 2031/1/1 1 2031/2/25 9 2031/4/28 18 2031/7/23 30 2031/10/27 44 2031/12/31 1 2032/1/1 1 2032/3/13 11 2032/5/30 22 2032/9/22 39 2032/11/22 48 2032/12/31 53 2033/1/1 53 2033/2/20 7 2033/5/21 20 2033/7/8 27 2033/10/2 39 2033/12/31 52 2034/1/1 52 2034/1/2 1 2034/5/16 20 2034/9/18 38 2034/12/14 50 2034/12/31 52 2035/1/1 1 2035/2/25 8 2035/5/24 21 2035/8/18 33 2035/10/12 41 2035/12/31 1 2036/1/1 1 2036/2/12 7 2036/5/29 22 2036/9/7 36 2036/12/8 50 2036/12/31 1 2037/1/1 1 2037/2/11 7 2037/4/6 15 2037/7/15 29 2037/10/29 44 2037/12/31 53 2038/1/1 53 2038/1/19 3 2038/5/10 19 2038/8/11 32 2038/11/13 45 2038/12/31 52 2039/1/1 52 2039/1/8 1 2039/4/5 14 2039/9/10 36 2039/11/8 45 2039/12/31 52 2040/1/1 52 2040/2/17 7 2040/6/26 26 2040/8/10 32 2040/10/6 40 2040/12/31 1 2041/1/1 1 2041/2/17 7 2041/4/8 15 2041/7/10 28 2041/12/11 50 2041/12/31 1 2042/1/1 1 2042/3/21 12 2042/5/11 19 2042/9/4 36 2042/12/28 52 2042/12/31 1 2043/1/1 1 2043/1/26 5 2043/4/1 14 2043/7/2 27 2043/11/10 46 2043/12/31 53 2044/1/1 53 2044/3/24 12 2044/6/29 26 2044/9/21 38 2044/11/4 44 2044/12/31 52 2045/1/1 52 2045/1/24 4 2045/4/2 13 2045/7/9 27 2045/10/13 41 2045/12/31 52 2046/1/1 1 2046/3/22 12 2046/6/24 25 2046/9/30 39 2046/11/7 45 2046/12/31 1 2047/1/1 1 2047/3/3 9 2047/4/26 17 2047/7/14 28 2047/12/13 50 2047/12/31 1 2048/1/1 1 2048/1/3 1 2048/6/3 23 2048/8/28 35 2048/11/30 49 2048/12/31 53 2049/1/1 53 2049/1/24 3 2049/5/19 20 2049/8/26 34 2049/10/13 41 2049/12/31 52 2050/1/1 52 2050/1/22 3 2050/5/19 20 2050/9/12 37 2050/11/27 47 2050/12/31 52