From 902326b3c2a6516e47e55a9bab8554ce54d013d9 Mon Sep 17 00:00:00 2001 From: richard Date: Wed, 2 Dec 1998 20:16:23 +0000 Subject: [PATCH] natural language stuff, tidying and bugfixing. git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@3368 72102866-910b-0410-8b05-ffd578937521 --- ChangeLog | 14 + Headers/gnustep/base/Foundation.h | 21 +- Headers/gnustep/base/NSDate.h | 22 +- Headers/gnustep/base/NSUserDefaults.h | 6 +- Source/GNUmakefile | 2 + Source/Makefile.postamble | 2 +- Source/NSDate.m | 694 +++++++++++++++++++++++++- Source/externs.m | 10 + 8 files changed, 753 insertions(+), 18 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4a1c27599..4e004d64a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,17 @@ +Wed Dec 2 20:30:00 1998 Richard Frith-Macdonald + + * src/GNUmakefile: Added NSDateFormatter + * src/Makefile.postamle: Bugfix in installation - was adding service + entries when not needed. + * src/NSDate.m: natural language support. + * src/externs.m: natural language support. + * src/include/Foundation.h: Added missing headers + * src/include/NSDate.h: natural language stuff. + * src/include/NSDateFormatter.h: Contributed by camile + * src/include/NSDecimalNumber.h: header - no implementation yet. + * src/include/NSDecimal.h: header - no implementation yet. + * src/include/NSUserDewfaults.h: natural language stuff. + Tue Dec 1 09:31:59 1998 Adam Fedor * src/Makefile.postamble: new variable INSTALL_ROOT_DIR, such that diff --git a/Headers/gnustep/base/Foundation.h b/Headers/gnustep/base/Foundation.h index 384143cd3..5eefe1d84 100644 --- a/Headers/gnustep/base/Foundation.h +++ b/Headers/gnustep/base/Foundation.h @@ -28,6 +28,7 @@ #include #include + #include #include #include @@ -38,14 +39,20 @@ #include #include #include +#include #include -#include #include +#include #include +#include +#include +#include #include #include #include +#include #include +#include #include #include #include @@ -54,15 +61,23 @@ #include #include #include +#include +#include #include +#include +#include +#include #include #include +#include #include +#include #include -#include #include -#include +#include #include #include +#include +#include #endif /* __Foundation_h_GNUSTEP_BASE_INCLUDE */ diff --git a/Headers/gnustep/base/NSDate.h b/Headers/gnustep/base/NSDate.h index 4bcb1b037..7400eb770 100644 --- a/Headers/gnustep/base/NSDate.h +++ b/Headers/gnustep/base/NSDate.h @@ -47,9 +47,6 @@ typedef double NSTimeInterval; + (id) date; + (id) dateWithString: (NSString*)description; -+ (id) dateWithNaturalLanguageString: (NSString *)string; -+ (id) dateWithNaturalLanguageString: (NSString *)string - locale: (NSDictionary *)localeDictionary; + (id) dateWithTimeIntervalSinceNow: (NSTimeInterval)seconds; + (id) dateWithTimeIntervalSince1970: (NSTimeInterval)seconds; + (id) dateWithTimeIntervalSinceReferenceDate: (NSTimeInterval)seconds; @@ -60,7 +57,6 @@ typedef double NSTimeInterval; - (id) initWithTimeInterval: (NSTimeInterval)secsToBeAdded sinceDate: (NSDate*)anotherDate; - (id) initWithTimeIntervalSinceNow: (NSTimeInterval)secsToBeAdded; -- (id) initWithTimeIntervalSince1970: (NSTimeInterval)seconds; - (id) initWithTimeIntervalSinceReferenceDate: (NSTimeInterval)secs; // Converting to NSCalendar @@ -112,15 +108,23 @@ typedef double NSTimeInterval; + (NSDictionary *)abbreviationDictionary; - (NSString *)timeZoneName; -/* Returns an dictionary that maps abbreviations to the array - containing all the time zone names that use the abbreviation. - Not in OpenStep. */ -+ (NSDictionary *)abbreviationMap; - //Getting Arrays of Time Zones + (NSArray *)timeZoneArray; - (NSArray *)timeZoneDetailArray; +#ifndef STRICT_OPENSTEP ++ (id) dateWithNaturalLanguageString: (NSString *)string; ++ (id) dateWithNaturalLanguageString: (NSString *)string + locale: (NSDictionary *)localeDictionary; +- (id) initWithTimeIntervalSince1970: (NSTimeInterval)seconds; +#endif + +#ifndef NO_GNUSTEP +/* Returns an dictionary that maps abbreviations to the array + containing all the time zone names that use the abbreviation. */ ++ (NSDictionary *)abbreviationMap; +#endif + @end diff --git a/Headers/gnustep/base/NSUserDefaults.h b/Headers/gnustep/base/NSUserDefaults.h index 24424b115..0439ae1f1 100644 --- a/Headers/gnustep/base/NSUserDefaults.h +++ b/Headers/gnustep/base/NSUserDefaults.h @@ -62,7 +62,7 @@ extern NSString *NSCurrencyString; extern NSString *NSDecimalDigits; extern NSString *NSAMPMDesignation; -/* NeXTSTEP 4.0 includes some more language-dependent constants: +#ifndef STRICT_OPENSTEP extern NSString *NSHourNameDesignations; extern NSString *NSYearMonthWeekDesignations; extern NSString *NSEarlierTimeDesignations; @@ -72,9 +72,7 @@ extern NSString *NSNextDayDesignations; extern NSString *NSNextNextDayDesignations; extern NSString *NSPriorDayDesignations; extern NSString *NSDateTimeOrdering; - -Perhaps one day they will be part of OpenStep and we should implement them. -*/ +#endif /* Get Information about a User */ extern NSString *NSUserName(void); diff --git a/Source/GNUmakefile b/Source/GNUmakefile index 9fbedc143..ad2a1317f 100644 --- a/Source/GNUmakefile +++ b/Source/GNUmakefile @@ -305,6 +305,7 @@ NSCountedSet.m \ NSConnection.m \ NSData.m \ NSDate.m \ +NSDateFormatter.m \ NSDebug.m \ NSDictionary.m \ NSDistantObject.m \ @@ -406,6 +407,7 @@ Foundation/NSConcreteValue.h \ Foundation/NSConnection.h \ Foundation/NSData.h \ Foundation/NSDate.h \ +Foundation/NSDateFormatter.h \ Foundation/NSDebug.h \ Foundation/NSDictionary.h \ Foundation/NSDistantObject.h \ diff --git a/Source/Makefile.postamble b/Source/Makefile.postamble index cba7608ab..4b93c9dca 100644 --- a/Source/Makefile.postamble +++ b/Source/Makefile.postamble @@ -63,7 +63,7 @@ after-install:: services=$(INSTALL_ROOT_DIR)/etc/services.add; \ echo "GNUstep addons for /etc/services written to $$services"; \ fi; \ - if [ "`fgrep gdomap $$services >/dev/null`" = "" ]; then \ + if [ "`fgrep gdomap $$services 2>/dev/null`" = "" ]; then \ set -x; \ echo "gdomap 538/tcp # GNUstep distrib objects" >> $$services; \ echo "gdomap 538/udp # GNUstep distrib objects" >> $$services; \ diff --git a/Source/NSDate.m b/Source/NSDate.m index a9ba2b8d9..a46f5cca7 100644 --- a/Source/NSDate.m +++ b/Source/NSDate.m @@ -1,9 +1,10 @@ /* Implementation for NSDate for GNUStep - Copyright (C) 1995, 1996, 1997 Free Software Foundation, Inc. + Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc. Written by: Jeremy Bettis Rewritten by: Scott Christley Date: March 1995 + Modifications by: Richard Frith-Macdonald This file is part of the GNUstep Base Library. @@ -36,6 +37,8 @@ #include #include #include +#include +#include #ifndef __WIN32__ #include #endif /* !__WIN32__ */ @@ -59,11 +62,30 @@ #define DISTANT_FUTURE (DISTANT_YEARS * 365.0 * 24 * 60 * 60) #define DISTANT_PAST (-DISTANT_FUTURE) +static NSString* +findInArray(NSArray *array, unsigned pos, NSString *str) +{ + unsigned index; + unsigned limit = [array count]; + + for (index = pos; index < limit; index++) + { + NSString *item; + + item = [array objectAtIndex: index]; + if ([str caseInsensitiveCompare: item] == NSOrderedSame) + return item; + } + return nil; +} + /* The implementation of NSDate. */ @implementation NSDate +static BOOL debug = NO; + + (void) initialize { if (self == [NSDate class]) @@ -75,6 +97,10 @@ NSArray *long_month; NSArray *short_day; NSArray *short_month; + NSArray *earlyt; + NSArray *latert; + NSArray *hour_names; + NSArray *ymw_names; ampm = [NSArray arrayWithObjects: @"AM", @"PM", nil]; short_month = [NSArray arrayWithObjects: @@ -123,12 +149,42 @@ @"Friday", @"Saturday", nil]; + earlyt = [NSArray arrayWithObjects: + @"prior", + @"last", + @"past", + @"ago", + nil]; + latert = [NSArray arrayWithObjects: + @"next", + nil]; + ymw_names = [NSArray arrayWithObjects: + @"year", + @"month", + @"week", + nil]; + hour_names = [NSArray arrayWithObjects: + [NSArray arrayWithObjects: @"0", @"midnight", nil], + [NSArray arrayWithObjects: @"12", @"noon", @"lunch", nil], + [NSArray arrayWithObjects: @"10", @"morning", nil], + [NSArray arrayWithObjects: @"14", @"afternoon", nil], + [NSArray arrayWithObjects: @"19", @"dinner", nil], + nil]; registrationDefaults = [NSDictionary dictionaryWithObjectsAndKeys: ampm, NSAMPMDesignation, long_month, NSMonthNameArray, long_day, NSWeekDayNameArray, short_month, NSShortMonthNameArray, short_day, NSShortWeekDayNameArray, + @"DMYH", NSDateTimeOrdering, + @"tomorrow", NSNextDayDesignations, + @"nextday", NSNextNextDayDesignations, + @"yesterday", NSPriorDayDesignations, + @"today", NSThisDayDesignations, + earlyt, NSEarlierTimeDesignations, + latert, NSLaterTimeDesignations, + hour_names, NSHourNameDesignations, + ymw_names, NSYearMonthWeekDesignations, nil]; [defs registerDefaults: registrationDefaults]; } @@ -184,6 +240,642 @@ return [[[self alloc] init] autorelease]; } ++ (id) dateWithNaturalLanguageString: (NSString*)string +{ + [self dateWithNaturalLanguageString: string + locale: nil]; +} + ++ (id) dateWithNaturalLanguageString: (NSString*)string + locale: (NSDictionary*)locale +{ + NSCharacterSet *ws; + NSCharacterSet *digits; + NSScanner *scanner; + NSString *tmp; + NSString *dto; + NSArray *ymw; + NSMutableArray *words; + unsigned index; + unsigned length; + NSCalendarDate *theDate; + BOOL hadHour = NO; + BOOL hadMinute = NO; + BOOL hadSecond = NO; + BOOL hadDay = NO; + BOOL hadMonth = NO; + BOOL hadYear = NO; + BOOL hadWeekDay = NO; + int weekDay = 0; + int dayOfWeek = 0; + int modMonth = 0; + int modYear = 0; + int modDay = 0; + int D, M, Y; + int modWeek; + int h = 12; + int m = 0; + int s = 0; + unsigned dtoIndex; + + if (locale == nil) + locale = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation]; + + ws = [NSCharacterSet whitespaceAndNewlineCharacterSet]; + digits = [NSCharacterSet decimalDigitCharacterSet]; + scanner = [NSScanner scannerWithString: string]; + words = [NSMutableArray arrayWithCapacity: 10]; + + theDate = (NSCalendarDate*)[NSCalendarDate date]; + Y = [theDate yearOfCommonEra]; + M = [theDate monthOfYear]; + D = [theDate dayOfMonth]; + dayOfWeek = [theDate dayOfWeek]; + + [scanner scanCharactersFromSet: ws intoString: 0]; + while ([scanner scanUpToCharactersFromSet: ws intoString: &tmp] == YES) + { + [words addObject: tmp]; + [scanner scanCharactersFromSet: ws intoString: 0]; + } + + /* + * Scan the array for day specifications and remove them. + */ + if (hadDay == NO) + { + NSString *tdd = [locale objectForKey: NSThisDayDesignations]; + NSString *ndd = [locale objectForKey: NSNextDayDesignations]; + NSString *pdd = [locale objectForKey: NSPriorDayDesignations]; + NSString *nndd = [locale objectForKey: NSNextNextDayDesignations]; + + for (index = 0; hadDay == NO && index < [words count]; index++) + { + tmp = [words objectAtIndex: index]; + + if ([tmp caseInsensitiveCompare: tdd] == NSOrderedSame) + { + hadDay = YES; + } + else if ([tmp caseInsensitiveCompare: ndd] == NSOrderedSame) + { + modDay++; + hadDay = YES; + } + else if ([tmp caseInsensitiveCompare: nndd] == NSOrderedSame) + { + modDay += 2; + hadDay = YES; + } + else if ([tmp caseInsensitiveCompare: pdd] == NSOrderedSame) + { + modDay--; + hadDay = YES; + } + if (hadDay) + { + hadMonth = YES; + hadYear = YES; + [words removeObjectAtIndex: index]; + } + } + } + + /* + * Scan the array for month specifications and remove them. + */ + if (hadMonth == NO) + { + NSArray *lm = [locale objectForKey: NSMonthNameArray]; + NSArray *sm = [locale objectForKey: NSShortMonthNameArray]; + + for (index = 0; hadMonth == NO && index < [words count]; index++) + { + NSString *mname; + + tmp = [words objectAtIndex: index]; + + if ((mname = findInArray(lm, 0, tmp)) != nil) + { + modMonth += M - [lm indexOfObjectIdenticalTo: mname] - 1; + hadMonth = YES; + } + else if ((mname = findInArray(sm, 0, tmp)) != nil) + { + modMonth += M - [sm indexOfObjectIdenticalTo: mname] - 1; + hadMonth = YES; + } + + if (mname != nil) + { + hadMonth = YES; + [words removeObjectAtIndex: index]; + } + } + } + + /* + * Scan the array for weekday specifications and remove them. + */ + if (hadWeekDay == NO) + { + NSArray *lw = [locale objectForKey: NSWeekDayNameArray]; + NSArray *sw = [locale objectForKey: NSShortWeekDayNameArray]; + + for (index = 0; hadWeekDay == NO && index < [words count]; index++) + { + NSString *dname; + + tmp = [words objectAtIndex: index]; + + if ((dname = findInArray(lw, 0, tmp)) != nil) + { + weekDay = [lw indexOfObjectIdenticalTo: dname]; + } + else if ((dname = findInArray(sw, 0, tmp)) != nil) + { + weekDay = [sw indexOfObjectIdenticalTo: dname]; + } + + if (dname != nil) + { + hadWeekDay = YES; + [words removeObjectAtIndex: index]; + } + } + } + + /* + * Scan the array for year month week modifiers and remove them. + * Going by the documentation, these modifiers adjust the date by + * plus or minus a week, month, or year. + */ + ymw = [locale objectForKey: NSYearMonthWeekDesignations]; + if (ymw != nil && [ymw count] > 0) + { + unsigned c = [ymw count]; + NSString *yname = [ymw objectAtIndex: 0]; + NSString *mname = c > 1 ? [ymw objectAtIndex: 1] : nil; + NSString *wname = c > 2 ? [ymw objectAtIndex: 2] : nil; + NSArray *early = [locale objectForKey: NSEarlierTimeDesignations]; + NSArray *later = [locale objectForKey: NSLaterTimeDesignations]; + + for (index = 0; index < [words count]; index++) + { + tmp = [words objectAtIndex: index]; + + /* + * See if the current word is a year, month, or week. + */ + if (findInArray(ymw, 0, tmp)) + { + BOOL hadAdjective = NO; + int adjective = 0; + NSString *adj = nil; + + /* + * See if there is a prefix adjective + */ + if (index > 0) + { + adj = [words objectAtIndex: index - 1]; + + if (findInArray(early, 0, adj)) + { + hadAdjective = YES; + adjective = -1; + } + else if (findInArray(later, 0, adj)) + { + hadAdjective = YES; + adjective = 1; + } + if (hadAdjective) + { + [words removeObjectAtIndex: --index]; + } + } + /* + * See if there is a prefix adjective + */ + if (hadAdjective == NO && index < [words count] - 1) + { + NSString *adj = [words objectAtIndex: index + 1]; + + if (findInArray(early, 0, adj)) + { + hadAdjective = YES; + adjective = -1; + } + else if (findInArray(later, 0, adj)) + { + hadAdjective = YES; + adjective = 1; + } + if (hadAdjective) + { + [words removeObjectAtIndex: index]; + } + } + /* + * Record the adjective information. + */ + if (hadAdjective) + { + if ([tmp caseInsensitiveCompare: yname] == NSOrderedSame) + { + modYear += adjective; + hadYear = YES; + } + else if ([tmp caseInsensitiveCompare: mname] == NSOrderedSame) + { + modMonth += adjective; + hadMonth = YES; + } + else + { + if (hadWeekDay) + { + modDay += weekDay - dayOfWeek; + } + modDay += 7*adjective; + hadDay = YES; + hadMonth = YES; + hadYear = YES; + } + } + /* + * Remove from list of words. + */ + [words removeObjectAtIndex: index]; + } + } + } + + /* Scan for hour of the day */ + if (hadHour == NO) + { + NSArray *hours = [locale objectForKey: NSHourNameDesignations]; + unsigned hLimit = [hours count]; + unsigned hIndex; + + for (index = 0; hadHour == NO && index < [words count]; index++) + { + tmp = [words objectAtIndex: index]; + + for (hIndex = 0; hadHour == NO && hIndex < hLimit; hIndex++) + { + NSArray *names; + + names = [hours objectAtIndex: hIndex]; + if (findInArray(names, 1, tmp) != nil) + { + h = [[names objectAtIndex: 0] intValue]; + hadHour = YES; + hadMinute = YES; + hadSecond = YES; + } + } + } + } + + /* + * Now re-scan the string for numeric information. + */ + + dto = [locale objectForKey: NSDateTimeOrdering]; + if (dto == nil) + { + if (debug) + NSLog(@"no NSDateTimeOrdering - default to DMYH.\n"); + dto = @"DMYH"; + } + length = [dto length]; + if (length > 4) + { + if (debug) + NSLog(@"too many characters in NSDateTimeOrdering - truncating.\n"); + length = 4; + } + + dtoIndex = 0; + scanner = [NSScanner scannerWithString: string]; + [scanner scanUpToCharactersFromSet: digits intoString: 0]; + while ([scanner scanCharactersFromSet: digits intoString: &tmp] == YES) + { + int num = [tmp intValue]; + + if ([scanner scanUpToCharactersFromSet: digits intoString: &tmp] == NO) + { + tmp = nil; + } + /* + * Numbers separated by colons are a time specification. + */ + if (tmp && ([tmp characterAtIndex: 0] == (unichar)':')) + { + BOOL done = NO; + + do + { + if (hadHour == NO) + { + if (num > 23) + { + if (debug) + NSLog(@"hour (%d) too large - ignored.\n", num); + else + return nil; + } + else + { + h = num; + m = 0; + s = 0; + hadHour = YES; + } + } + else if (hadMinute == NO) + { + if (num > 59) + { + if (debug) + NSLog(@"minute (%d) too large - ignored.\n", num); + else + return nil; + } + else + { + m = num; + s = 0; + hadMinute = YES; + } + } + else if (hadSecond == NO) + { + if (num > 59) + { + if (debug) + NSLog(@"second (%d) too large - ignored.\n", num); + else + return nil; + } + else + { + s = num; + hadSecond = YES; + } + } + else + { + if (debug) + NSLog(@"odd time spec - excess numbers ignored.\n"); + } + + done = YES; + if (tmp && ([tmp characterAtIndex: 0] == (unichar)':')) + { + if ([scanner scanCharactersFromSet: digits intoString: &tmp]) + { + num = [tmp intValue]; + done = NO; + if ([scanner scanUpToCharactersFromSet: digits + intoString: &tmp] == NO) + { + tmp = nil; + } + } + } + } + while (done == NO); + } + else + { + BOOL mustSkip = YES; + + while ((dtoIndex < [dto length]) && (mustSkip == YES)) + { + switch ([dto characterAtIndex: dtoIndex]) + { + case 'D': + if (hadDay) + dtoIndex++; + else + mustSkip = NO; + break; + + case 'M': + if (hadMonth) + dtoIndex++; + else + mustSkip = NO; + break; + + case 'Y': + if (hadYear) + dtoIndex++; + else + mustSkip = NO; + break; + + case 'H': + if (hadHour) + dtoIndex++; + else + mustSkip = NO; + break; + + default: + dtoIndex++; + if (debug) + NSLog(@"odd char (unicode %d) in NSDateTimeOrdering.\n", + [dto characterAtIndex: index]); + break; + } + } + if (dtoIndex >= [dto length]) + { + if (debug) + NSLog(@"odd date specification - excess numbers ignored.\n"); + break; + } + switch ([dto characterAtIndex: dtoIndex]) + { + case 'D': + if (num < 1) + { + if (debug) + NSLog(@"day (0) too small - ignored.\n"); + else + return nil; + } + else if (num > 31) + { + if (debug) + NSLog(@"day (%d) too large - ignored.\n", num); + else + return nil; + } + else + { + D = num; + hadDay = YES; + } + break; + case 'M': + if (num < 1) + { + if (debug) + NSLog(@"month (0) too small - ignored.\n"); + else + return nil; + } + else if (num > 12) + { + if (debug) + NSLog(@"month (%d) too large - ignored.\n", num); + else + return nil; + } + else + { + M = num; + hadMonth = YES; + } + break; + case 'Y': + if (num < 100) + { + if (num < 70) + { + Y = num + 2000; + } + else + { + Y = num + 1900; + } + if (debug) + NSLog(@"year (%d) adjusted to %d.\n", num, Y); + } + else + { + Y = num; + } + hadYear = YES; + break; + case 'H': + { + BOOL shouldIgnore = NO; + + /* + * Check the next text to see if it is an am/pm + * designation. + */ + if (tmp) + { + NSArray *ampm; + NSString *mod; + + ampm = [locale objectForKey: NSAMPMDesignation]; + mod = findInArray(ampm, 0, tmp); + if (mod) + { + if (num > 11) + { + if (debug) + NSLog(@"hour (%d) too large - ignored.\n", + num); + else + return nil; + shouldIgnore = YES; + } + else if (mod == [ampm objectAtIndex: 1]) + { + num += 12; + } + } + } + if (shouldIgnore == NO) + { + if (num > 23) + { + if (debug) + NSLog(@"hour (%d) too large - ignored.\n", num); + else + return nil; + } + else + { + hadHour = YES; + h = num; + } + } + break; + } + default: + if (debug) + NSLog(@"unexpected char (unicode%d) in NSDateTimeOrdering.\n", + [dto characterAtIndex: index]); + break; + } + } + } + + /* + * If we had no date or time information - we give up, otherwise + * we can use reasonable defaults for any missing info. + * Missing date => today + * Missing time => 12:00 + * If we had a week/month/year modifier without a day, we assume today. + * If we had a day name without any more day detail - adjust to that + * day this week. + */ + if (hadDay == NO && hadWeekDay == YES) + { + modDay += weekDay - dayOfWeek; + hadDay = YES; + } + if (hadDay == NO && hadHour == NO) + { + if (modDay == NO && modMonth == NO && modYear == NO) + { + return nil; + } + } + + /* + * Build a calendar date we can adjust easily. + */ + theDate = [NSCalendarDate dateWithYear: Y + month: M + day: D + hour: h + minute: m + second: s + timeZone: [NSTimeZone defaultTimeZone]]; + + /* + * Adjust the date by year month or days if necessary. + */ + if (modYear || modMonth || modDay) + { + theDate = [theDate dateByAddingYears: modYear + months: modMonth + days: modDay + hours: 0 + minutes: 0 + seconds: 0]; + } + if (hadWeekDay && [theDate dayOfWeek] != weekDay) + { + if (debug) + NSLog(@"Date resulted in wrong day of week.\n"); + return nil; + } + return [self dateWithTimeIntervalSinceReferenceDate: + [theDate timeIntervalSinceReferenceDate]]; +} + + (id) dateWithString: (NSString*)description { return [[[self alloc] initWithString: description] autorelease]; diff --git a/Source/externs.m b/Source/externs.m index c18ca0605..a7da81828 100644 --- a/Source/externs.m +++ b/Source/externs.m @@ -143,6 +143,16 @@ NSString *NSCurrencyString = @"NSCurrencyString"; NSString *NSDecimalDigits = @"NSDecimalDigits"; NSString *NSAMPMDesignation = @"NSAMPMDesignation"; +NSString *NSHourNameDesignations = @"NSHourNameDesignations"; +NSString *NSYearMonthWeekDesignations = @"NSYearMonthWeekDesignations"; +NSString *NSEarlierTimeDesignations = @"NSEarlierTimeDesignations"; +NSString *NSLaterTimeDesignations = @"NSLaterTimeDesignations"; +NSString *NSThisDayDesignations = @"NSThisDayDesignations"; +NSString *NSNextDayDesignations = @"NSNextDayDesignations"; +NSString *NSNextNextDayDesignations = @"NSNextNextDayDesignations"; +NSString *NSPriorDayDesignations = @"NSPriorDayDesignations"; +NSString *NSDateTimeOrdering = @"NSDateTimeOrdering"; + /* Standard MapTable callbacks */ const NSMapTableKeyCallBacks NSIntMapKeyCallBacks =