1 /****************************************************************************** 2 * 3 * ISOWeekNum.c 4 * return a date's week number, according to ISO 8601 5 * Version: 1.0 6 * 7 * Copyright (c) 2002 Robert Watkins 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 22 * 23 *****************************************************************************/ 24 25 #include 26 #include "ISOWeekNum.h" // this is no more than the function declaration 27 28 Int32 ISOWeekNum(DateType *dP) 29 { 30 Int32 weekNum; 31 DateType firstMonday = { firstYear, 1, 1 }; 32 DateType date0101 = { firstYear, 1, 1 }; 33 DateType date3112 = { firstYear, 12, 31 }; 34 // Note: "dow" stands for "day of the week" 35 Int16 dowDP = DayOfWeek(dP->month, dP->day, dP->year + firstYear); 36 Int16 dow0101 = DayOfWeek(1, 1, dP->year + firstYear); 37 Int16 dow3112 = DayOfWeek(12, 31, dP->year + firstYear); 38 Int16 dow0[7] = { 6, 0, 1, 2, 3, 4, 5 }; // 0-based dow array (PalmOS thinks Sunday is day 0!) 39 40 firstMonday.year = dP->year; 41 date0101.year = dP->year; 42 date3112.year = dP->year; 43 44 if ((dP->month == 12) && (dP->day > (31 - dow3112)) && (dow3112 < thursday)) { 45 // day in question belongs in first week of following year 46 weekNum = 1; 47 } 48 else { 49 if (dow0[dow0101] > dow0[thursday]) { // jan1 is Fri, Sat or Sun 50 // see if day in question belongs in last week of previous year 51 if ((dP->month == 1) && (dP->day < (8 - dow0[dow0101]))) { 52 Int16 dowPrev0101; 53 if (firstMonday.year == 0) { return weekNum = 53; } // special case due to PalmOS limitations 54 firstMonday.year--; 55 firstMonday.month = 1; 56 firstMonday.day = 1; 57 dowPrev0101 = DayOfWeek(1, 1, firstMonday.year + firstYear); 58 if (dow0[dowPrev0101] > dow0[thursday]) { // jan1 of previous year is Fri, Sat or Sun 59 // set firstMonday to monday after jan1 of previous year 60 DateAdjust(&firstMonday, (7 - dow0[dowPrev0101])); 61 } 62 else { 63 // set firstMonday to monday before jan1 of previous year 64 DateAdjust(&firstMonday, -(dow0[dowPrev0101])); 65 } 66 } 67 else { 68 // set firstMonday to monday after jan1 69 DateAdjust(&firstMonday, (7 - dow0[dow0101])); 70 } 71 } 72 else { 73 // set firstMonday to monday before jan1 74 DateAdjust(&firstMonday, -(dow0[dow0101])); 75 } 76 // count weeks from firstMonday (zero based) and add 1 to get week number 77 weekNum = ((DateToDays(*dP) - DateToDays(firstMonday)) / daysInWeek) + 1; 78 } 79 80 return weekNum; 81 } 82