diff --git a/ChangeLog b/ChangeLog index d9263b308..62b6915a5 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2003-01-09 Richard Frith-Macdonald + + * Source/Additions/GSCategories.m: Additional ([weekOfYear]) method + for NSCalendarDate. + * Headers/gnustep/base/GSCategories.h: ditto + 2003-01-07 Richard Frith-Macdonald * Source/NSLock.m: diff --git a/Headers/gnustep/base/GSCategories.h b/Headers/gnustep/base/GSCategories.h new file mode 100644 index 000000000..4781871b8 --- /dev/null +++ b/Headers/gnustep/base/GSCategories.h @@ -0,0 +1,38 @@ +#ifndef INCLUDED_GS_CATEGORIES_H +#define INCLUDED_GS_CATEGORIES_H +/* Declaration of extension methods to standard classes + + Copyright (C) 2003 Free Software Foundation, Inc. + + Written by: Richard Frith-Macdonald + + This file is part of the GNUstep Base Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. + + AutogsdocSource: Additions/GSCategories.m + +*/ + +#ifndef NO_GNUSTEP + +@interface NSCalendarDate (GSCategories) + +- (int) weekOfYear; + +@end + +#endif /* NO_GNUSTEP */ +#endif /* INCLUDED_GS_CATEGORIES_H */ diff --git a/Source/Additions/GNUmakefile b/Source/Additions/GNUmakefile index d1855feb3..1c756b2fe 100644 --- a/Source/Additions/GNUmakefile +++ b/Source/Additions/GNUmakefile @@ -32,6 +32,7 @@ include ../../config.mak SUBPROJECT_NAME = Additions Additions_OBJC_FILES =\ + GSCategories.m \ GSObjCRuntime.m \ GCObject.m \ GCArray.m \ diff --git a/Source/Additions/GSCategories.m b/Source/Additions/GSCategories.m new file mode 100644 index 000000000..8d45f7939 --- /dev/null +++ b/Source/Additions/GSCategories.m @@ -0,0 +1,84 @@ +/* Implementation of extension methods to standard classes + + Copyright (C) 2003 Free Software Foundation, Inc. + + Written by: Richard Frith-Macdonald + + This file is part of the GNUstep Base Library. + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Library General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Library General Public License for more details. + + You should have received a copy of the GNU Library General Public + License along with this library; if not, write to the Free + Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111 USA. + +*/ +#include + +@implementation NSCalendarDate (GSCategories) + +/** + * The ISO standard week of the year is based on the first week of the + * year being that week (starting on monday) for which the thursday + * is on or after the first of january.
+ * This has the effect that, if january first is a friday, saturday or + * sunday, the days of that week (up to and including the sunday) are + * considered to be in week 53 of the preceeding year. Similarly if the + * last day of the year is a monday tuesday or wednesday, these days are + * part of week 1 of the next year. + */ +- (int) weekOfYear +{ + int dayOfWeek = [self dayOfWeek]; + int dayOfYear; + + /* + * Whether a week is considered to be in a year or not depends on its + * thursday ... so find thursday for the receivers week. + * NB. this may result in a date which is not in the same year as the + * receiver. + */ + if (dayOfWeek != 4) + { + CREATE_AUTORELEASE_POOL(arp); + NSCalendarDate *thursday; + + /* + * A week starts on monday ... so adjust from 0 to 7 so that a + * sunday is counted as the last day of the week. + */ + if (dayOfWeek == 0) + { + dayOfWeek = 7; + } + thursday = [self dateByAddingYears: 0 + months: 0 + days: 4 - dayOfWeek + hours: 0 + minutes: 0 + seconds: 0]; + dayOfYear = [thursday dayOfYear]; + RELEASE(arp); + } + else + { + dayOfYear = [self dayOfYear]; + } + + /* + * Round up to a week boundary, so that when we divide by seven we + * get a result in the range 1 to 53 as mandated by the ISO standard. + */ + dayOfYear += (7 - dayOfYear % 7); + return dayOfYear / 7; +} + +@end diff --git a/Source/DocMakefile b/Source/DocMakefile index cae7ac827..d507067c1 100644 --- a/Source/DocMakefile +++ b/Source/DocMakefile @@ -34,6 +34,7 @@ Base_DOC_INSTALL_DIR = Developer Base_AGSDOC_FILES = \ ../Documentation/Base.gsdoc \ +GSCategories.h \ GSIArray.h \ GSIMap.h \ GSMime.h \ diff --git a/Source/GNUmakefile b/Source/GNUmakefile index 8e5cd2080..9abf5102e 100644 --- a/Source/GNUmakefile +++ b/Source/GNUmakefile @@ -117,6 +117,7 @@ libgnustep-base.def GNU_HEADERS = \ DistributedObjects.h \ GCObject.h \ +GSCategories.h \ GSFileHandle.h \ GSLocale.h \ GSObjCRuntime.h \ diff --git a/Source/NSCalendarDate.m b/Source/NSCalendarDate.m index 073806d24..f18ac094f 100644 --- a/Source/NSCalendarDate.m +++ b/Source/NSCalendarDate.m @@ -39,6 +39,7 @@ #include #include #include +#include #include #include #include @@ -1963,7 +1964,7 @@ static inline int getDigits(const char *from, char *to, int limit) } /** - * Given a day number since the start of the era, returns the dat as a + * Given a day number since the start of the era, returns the date as a * day, month, and year. */ - (void) gregorianDateFromAbsolute: (int)d @@ -1971,16 +1972,7 @@ static inline int getDigits(const char *from, char *to, int limit) month: (int *)month year: (int *)year { - // Search forward year by year from approximate year - *year = d/366; - while (d >= absoluteGregorianDay(1, 1, (*year)+1)) - (*year)++; - // Search forward month by month from January - (*month) = 1; - while (d > absoluteGregorianDay(lastDayOfGregorianMonth(*month, *year), - *month, *year)) - (*month)++; - *day = d - absoluteGregorianDay(1, *month, *year) + 1; + gregorianDateFromAbsolute(d, day, month, year); } @end diff --git a/Testing/nsdate.m b/Testing/nsdate.m index 9df212eab..59167b966 100644 --- a/Testing/nsdate.m +++ b/Testing/nsdate.m @@ -1,6 +1,9 @@ #include +#include #include #include +#include +#include #ifdef __MS_WIN32__ int _MB_init_runtime() @@ -96,6 +99,7 @@ if ([(NSDate*) [NSCalendarDate date] compare: printf("NSCalendarDate tests\n"); { NSCalendarDate *c1; + NSTimeZone *gb = [NSTimeZone timeZoneWithName: @"GB"]; int m, y, d, a; // Create an NSCalendarDate with current date and time @@ -269,7 +273,7 @@ if ([(NSDate*) [NSCalendarDate date] compare: c = [c addYear:0 month:0 day:0 hour:-24 minute:0 second:0]; printf("Subtract twentyfour hours - %s\n", [DESCRIP_FORMAT(c) cString]); - c = [NSCalendarDate dateWithYear: 2002 month: 3 day: 31 hour: 1 minute: 30 second: 0 timeZone: [NSTimeZone timeZoneWithName: @"GB"]]; + c = [NSCalendarDate dateWithYear: 2002 month: 3 day: 31 hour: 1 minute: 30 second: 0 timeZone: gb]; printf("Build at %s\n", [[c description] cString]); c = [NSCalendarDate dateWithString: @"2002-09-27 01:59:00" @@ -283,6 +287,36 @@ if ([(NSDate*) [NSCalendarDate date] compare: seconds: 0]; printf("Subtract 180 %s\n", [DESCRIP_FORMAT(c1) cString]); + printf("Week of year tests ... "); + if ([[NSCalendarDate dateWithYear: 2002 month: 12 day: 29 hour: 0 + minute: 0 second: 0 timeZone: gb] weekOfYear] != 52) + printf("Failed on 2002/12/29 is week 52\n"); + if ([[NSCalendarDate dateWithYear: 2002 month: 12 day: 30 hour: 0 + minute: 0 second: 0 timeZone: gb] weekOfYear] != 1) + printf("Failed on 2002/12/30 is week 1\n"); + if ([[NSCalendarDate dateWithYear: 2002 month: 12 day: 31 hour: 0 + minute: 0 second: 0 timeZone: gb] weekOfYear] != 1) + printf("Failed on 2002/12/31 is week 1\n"); + if ([[NSCalendarDate dateWithYear: 2003 month: 1 day: 1 hour: 0 + minute: 0 second: 0 timeZone: gb] weekOfYear] != 1) + printf("Failed on 2003/01/01 is week 1\n"); + else if ([[NSCalendarDate dateWithYear: 2003 month: 1 day: 2 hour: 0 + minute: 0 second: 0 timeZone: gb] weekOfYear] != 1) + printf("Failed on 2003/01/02 is week 1\n"); + else if ([[NSCalendarDate dateWithYear: 2003 month: 1 day: 3 hour: 0 + minute: 0 second: 0 timeZone: gb] weekOfYear] != 1) + printf("Failed on 2003/01/03 is week 1\n"); + else if ([[NSCalendarDate dateWithYear: 2003 month: 1 day: 4 hour: 0 + minute: 0 second: 0 timeZone: gb] weekOfYear] != 1) + printf("Failed on 2003/01/04 is week 1\n"); + else if ([[NSCalendarDate dateWithYear: 2003 month: 1 day: 5 hour: 0 + minute: 0 second: 0 timeZone: gb] weekOfYear] != 1) + printf("Failed on 2003/01/05 is week 1\n"); + else if ([[NSCalendarDate dateWithYear: 2003 month: 1 day: 6 hour: 0 + minute: 0 second: 0 timeZone: gb] weekOfYear] != 2) + printf("Failed on 2003/01/06 is week 2\n"); + else + printf("All passed\n"); } [pool release];