mirror of
https://github.com/gnustep/libs-base.git
synced 2025-05-31 00:30:53 +00:00
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
This commit is contained in:
parent
46ba14cf6b
commit
902326b3c2
8 changed files with 753 additions and 18 deletions
14
ChangeLog
14
ChangeLog
|
@ -1,3 +1,17 @@
|
||||||
|
Wed Dec 2 20:30:00 1998 Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
|
* 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 <fedor@ultra.doc.com>
|
Tue Dec 1 09:31:59 1998 Adam Fedor <fedor@ultra.doc.com>
|
||||||
|
|
||||||
* src/Makefile.postamble: new variable INSTALL_ROOT_DIR, such that
|
* src/Makefile.postamble: new variable INSTALL_ROOT_DIR, such that
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
#include <Foundation/NSDebug.h>
|
#include <Foundation/NSDebug.h>
|
||||||
#include <Foundation/NSObject.h>
|
#include <Foundation/NSObject.h>
|
||||||
|
|
||||||
#include <Foundation/NSArchiver.h>
|
#include <Foundation/NSArchiver.h>
|
||||||
#include <Foundation/NSArray.h>
|
#include <Foundation/NSArray.h>
|
||||||
#include <Foundation/NSAttributedString.h>
|
#include <Foundation/NSAttributedString.h>
|
||||||
|
@ -38,14 +39,20 @@
|
||||||
#include <Foundation/NSCoder.h>
|
#include <Foundation/NSCoder.h>
|
||||||
#include <Foundation/NSConnection.h>
|
#include <Foundation/NSConnection.h>
|
||||||
#include <Foundation/NSDate.h>
|
#include <Foundation/NSDate.h>
|
||||||
|
#include <Foundation/NSDateFormatter.h>
|
||||||
#include <Foundation/NSData.h>
|
#include <Foundation/NSData.h>
|
||||||
#include <Foundation/NSDebug.h>
|
|
||||||
#include <Foundation/NSDictionary.h>
|
#include <Foundation/NSDictionary.h>
|
||||||
|
#include <Foundation/NSDecimalNumber.h>
|
||||||
#include <Foundation/NSDistantObject.h>
|
#include <Foundation/NSDistantObject.h>
|
||||||
|
#include <Foundation/NSDistributedLock.h>
|
||||||
|
#include <Foundation/NSDistributedNotificationCenter.h>
|
||||||
|
#include <Foundation/NSEnumerator.h>
|
||||||
#include <Foundation/NSException.h>
|
#include <Foundation/NSException.h>
|
||||||
#include <Foundation/NSFileHandle.h>
|
#include <Foundation/NSFileHandle.h>
|
||||||
#include <Foundation/NSFileManager.h>
|
#include <Foundation/NSFileManager.h>
|
||||||
|
#include <Foundation/NSFormatter.h>
|
||||||
#include <Foundation/NSHashTable.h>
|
#include <Foundation/NSHashTable.h>
|
||||||
|
#include <Foundation/NSGeometry.h>
|
||||||
#include <Foundation/NSHost.h>
|
#include <Foundation/NSHost.h>
|
||||||
#include <Foundation/NSInvocation.h>
|
#include <Foundation/NSInvocation.h>
|
||||||
#include <Foundation/NSLock.h>
|
#include <Foundation/NSLock.h>
|
||||||
|
@ -54,15 +61,23 @@
|
||||||
#include <Foundation/NSNotification.h>
|
#include <Foundation/NSNotification.h>
|
||||||
#include <Foundation/NSNotificationQueue.h>
|
#include <Foundation/NSNotificationQueue.h>
|
||||||
#include <Foundation/NSPortCoder.h>
|
#include <Foundation/NSPortCoder.h>
|
||||||
|
#include <Foundation/NSPortMessage.h>
|
||||||
|
#include <Foundation/NSPortNameServer.h>
|
||||||
#include <Foundation/NSProcessInfo.h>
|
#include <Foundation/NSProcessInfo.h>
|
||||||
|
#include <Foundation/NSProtocolChecker.h>
|
||||||
|
#include <Foundation/NSProxy.h>
|
||||||
|
#include <Foundation/NSRange.h>
|
||||||
#include <Foundation/NSRunLoop.h>
|
#include <Foundation/NSRunLoop.h>
|
||||||
#include <Foundation/NSScanner.h>
|
#include <Foundation/NSScanner.h>
|
||||||
|
#include <Foundation/NSSerialization.h>
|
||||||
#include <Foundation/NSSet.h>
|
#include <Foundation/NSSet.h>
|
||||||
|
#include <Foundation/NSString.h>
|
||||||
#include <Foundation/NSTask.h>
|
#include <Foundation/NSTask.h>
|
||||||
#include <Foundation/NSTimer.h>
|
|
||||||
#include <Foundation/NSThread.h>
|
#include <Foundation/NSThread.h>
|
||||||
#include <Foundation/NSValue.h>
|
#include <Foundation/NSTimer.h>
|
||||||
#include <Foundation/NSUndoManager.h>
|
#include <Foundation/NSUndoManager.h>
|
||||||
#include <Foundation/NSUserDefaults.h>
|
#include <Foundation/NSUserDefaults.h>
|
||||||
|
#include <Foundation/NSValue.h>
|
||||||
|
#include <Foundation/NSZone.h>
|
||||||
|
|
||||||
#endif /* __Foundation_h_GNUSTEP_BASE_INCLUDE */
|
#endif /* __Foundation_h_GNUSTEP_BASE_INCLUDE */
|
||||||
|
|
|
@ -47,9 +47,6 @@ typedef double NSTimeInterval;
|
||||||
|
|
||||||
+ (id) date;
|
+ (id) date;
|
||||||
+ (id) dateWithString: (NSString*)description;
|
+ (id) dateWithString: (NSString*)description;
|
||||||
+ (id) dateWithNaturalLanguageString: (NSString *)string;
|
|
||||||
+ (id) dateWithNaturalLanguageString: (NSString *)string
|
|
||||||
locale: (NSDictionary *)localeDictionary;
|
|
||||||
+ (id) dateWithTimeIntervalSinceNow: (NSTimeInterval)seconds;
|
+ (id) dateWithTimeIntervalSinceNow: (NSTimeInterval)seconds;
|
||||||
+ (id) dateWithTimeIntervalSince1970: (NSTimeInterval)seconds;
|
+ (id) dateWithTimeIntervalSince1970: (NSTimeInterval)seconds;
|
||||||
+ (id) dateWithTimeIntervalSinceReferenceDate: (NSTimeInterval)seconds;
|
+ (id) dateWithTimeIntervalSinceReferenceDate: (NSTimeInterval)seconds;
|
||||||
|
@ -60,7 +57,6 @@ typedef double NSTimeInterval;
|
||||||
- (id) initWithTimeInterval: (NSTimeInterval)secsToBeAdded
|
- (id) initWithTimeInterval: (NSTimeInterval)secsToBeAdded
|
||||||
sinceDate: (NSDate*)anotherDate;
|
sinceDate: (NSDate*)anotherDate;
|
||||||
- (id) initWithTimeIntervalSinceNow: (NSTimeInterval)secsToBeAdded;
|
- (id) initWithTimeIntervalSinceNow: (NSTimeInterval)secsToBeAdded;
|
||||||
- (id) initWithTimeIntervalSince1970: (NSTimeInterval)seconds;
|
|
||||||
- (id) initWithTimeIntervalSinceReferenceDate: (NSTimeInterval)secs;
|
- (id) initWithTimeIntervalSinceReferenceDate: (NSTimeInterval)secs;
|
||||||
|
|
||||||
// Converting to NSCalendar
|
// Converting to NSCalendar
|
||||||
|
@ -112,15 +108,23 @@ typedef double NSTimeInterval;
|
||||||
+ (NSDictionary *)abbreviationDictionary;
|
+ (NSDictionary *)abbreviationDictionary;
|
||||||
- (NSString *)timeZoneName;
|
- (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
|
//Getting Arrays of Time Zones
|
||||||
+ (NSArray *)timeZoneArray;
|
+ (NSArray *)timeZoneArray;
|
||||||
- (NSArray *)timeZoneDetailArray;
|
- (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
|
@end
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -62,7 +62,7 @@ extern NSString *NSCurrencyString;
|
||||||
extern NSString *NSDecimalDigits;
|
extern NSString *NSDecimalDigits;
|
||||||
extern NSString *NSAMPMDesignation;
|
extern NSString *NSAMPMDesignation;
|
||||||
|
|
||||||
/* NeXTSTEP 4.0 includes some more language-dependent constants:
|
#ifndef STRICT_OPENSTEP
|
||||||
extern NSString *NSHourNameDesignations;
|
extern NSString *NSHourNameDesignations;
|
||||||
extern NSString *NSYearMonthWeekDesignations;
|
extern NSString *NSYearMonthWeekDesignations;
|
||||||
extern NSString *NSEarlierTimeDesignations;
|
extern NSString *NSEarlierTimeDesignations;
|
||||||
|
@ -72,9 +72,7 @@ extern NSString *NSNextDayDesignations;
|
||||||
extern NSString *NSNextNextDayDesignations;
|
extern NSString *NSNextNextDayDesignations;
|
||||||
extern NSString *NSPriorDayDesignations;
|
extern NSString *NSPriorDayDesignations;
|
||||||
extern NSString *NSDateTimeOrdering;
|
extern NSString *NSDateTimeOrdering;
|
||||||
|
#endif
|
||||||
Perhaps one day they will be part of OpenStep and we should implement them.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* Get Information about a User */
|
/* Get Information about a User */
|
||||||
extern NSString *NSUserName(void);
|
extern NSString *NSUserName(void);
|
||||||
|
|
|
@ -305,6 +305,7 @@ NSCountedSet.m \
|
||||||
NSConnection.m \
|
NSConnection.m \
|
||||||
NSData.m \
|
NSData.m \
|
||||||
NSDate.m \
|
NSDate.m \
|
||||||
|
NSDateFormatter.m \
|
||||||
NSDebug.m \
|
NSDebug.m \
|
||||||
NSDictionary.m \
|
NSDictionary.m \
|
||||||
NSDistantObject.m \
|
NSDistantObject.m \
|
||||||
|
@ -406,6 +407,7 @@ Foundation/NSConcreteValue.h \
|
||||||
Foundation/NSConnection.h \
|
Foundation/NSConnection.h \
|
||||||
Foundation/NSData.h \
|
Foundation/NSData.h \
|
||||||
Foundation/NSDate.h \
|
Foundation/NSDate.h \
|
||||||
|
Foundation/NSDateFormatter.h \
|
||||||
Foundation/NSDebug.h \
|
Foundation/NSDebug.h \
|
||||||
Foundation/NSDictionary.h \
|
Foundation/NSDictionary.h \
|
||||||
Foundation/NSDistantObject.h \
|
Foundation/NSDistantObject.h \
|
||||||
|
|
|
@ -63,7 +63,7 @@ after-install::
|
||||||
services=$(INSTALL_ROOT_DIR)/etc/services.add; \
|
services=$(INSTALL_ROOT_DIR)/etc/services.add; \
|
||||||
echo "GNUstep addons for /etc/services written to $$services"; \
|
echo "GNUstep addons for /etc/services written to $$services"; \
|
||||||
fi; \
|
fi; \
|
||||||
if [ "`fgrep gdomap $$services >/dev/null`" = "" ]; then \
|
if [ "`fgrep gdomap $$services 2>/dev/null`" = "" ]; then \
|
||||||
set -x; \
|
set -x; \
|
||||||
echo "gdomap 538/tcp # GNUstep distrib objects" >> $$services; \
|
echo "gdomap 538/tcp # GNUstep distrib objects" >> $$services; \
|
||||||
echo "gdomap 538/udp # GNUstep distrib objects" >> $$services; \
|
echo "gdomap 538/udp # GNUstep distrib objects" >> $$services; \
|
||||||
|
|
694
Source/NSDate.m
694
Source/NSDate.m
|
@ -1,9 +1,10 @@
|
||||||
/* Implementation for NSDate for GNUStep
|
/* 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 <jeremy@hksys.com>
|
Written by: Jeremy Bettis <jeremy@hksys.com>
|
||||||
Rewritten by: Scott Christley <scottc@net-community.com>
|
Rewritten by: Scott Christley <scottc@net-community.com>
|
||||||
Date: March 1995
|
Date: March 1995
|
||||||
|
Modifications by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||||
|
|
||||||
This file is part of the GNUstep Base Library.
|
This file is part of the GNUstep Base Library.
|
||||||
|
|
||||||
|
@ -36,6 +37,8 @@
|
||||||
#include <Foundation/NSCoder.h>
|
#include <Foundation/NSCoder.h>
|
||||||
#include <Foundation/NSException.h>
|
#include <Foundation/NSException.h>
|
||||||
#include <Foundation/NSUserDefaults.h>
|
#include <Foundation/NSUserDefaults.h>
|
||||||
|
#include <Foundation/NSCharacterSet.h>
|
||||||
|
#include <Foundation/NSScanner.h>
|
||||||
#ifndef __WIN32__
|
#ifndef __WIN32__
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#endif /* !__WIN32__ */
|
#endif /* !__WIN32__ */
|
||||||
|
@ -59,11 +62,30 @@
|
||||||
#define DISTANT_FUTURE (DISTANT_YEARS * 365.0 * 24 * 60 * 60)
|
#define DISTANT_FUTURE (DISTANT_YEARS * 365.0 * 24 * 60 * 60)
|
||||||
#define DISTANT_PAST (-DISTANT_FUTURE)
|
#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. */
|
/* The implementation of NSDate. */
|
||||||
|
|
||||||
@implementation NSDate
|
@implementation NSDate
|
||||||
|
|
||||||
|
static BOOL debug = NO;
|
||||||
|
|
||||||
+ (void) initialize
|
+ (void) initialize
|
||||||
{
|
{
|
||||||
if (self == [NSDate class])
|
if (self == [NSDate class])
|
||||||
|
@ -75,6 +97,10 @@
|
||||||
NSArray *long_month;
|
NSArray *long_month;
|
||||||
NSArray *short_day;
|
NSArray *short_day;
|
||||||
NSArray *short_month;
|
NSArray *short_month;
|
||||||
|
NSArray *earlyt;
|
||||||
|
NSArray *latert;
|
||||||
|
NSArray *hour_names;
|
||||||
|
NSArray *ymw_names;
|
||||||
|
|
||||||
ampm = [NSArray arrayWithObjects: @"AM", @"PM", nil];
|
ampm = [NSArray arrayWithObjects: @"AM", @"PM", nil];
|
||||||
short_month = [NSArray arrayWithObjects:
|
short_month = [NSArray arrayWithObjects:
|
||||||
|
@ -123,12 +149,42 @@
|
||||||
@"Friday",
|
@"Friday",
|
||||||
@"Saturday",
|
@"Saturday",
|
||||||
nil];
|
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:
|
registrationDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
|
||||||
ampm, NSAMPMDesignation,
|
ampm, NSAMPMDesignation,
|
||||||
long_month, NSMonthNameArray,
|
long_month, NSMonthNameArray,
|
||||||
long_day, NSWeekDayNameArray,
|
long_day, NSWeekDayNameArray,
|
||||||
short_month, NSShortMonthNameArray,
|
short_month, NSShortMonthNameArray,
|
||||||
short_day, NSShortWeekDayNameArray,
|
short_day, NSShortWeekDayNameArray,
|
||||||
|
@"DMYH", NSDateTimeOrdering,
|
||||||
|
@"tomorrow", NSNextDayDesignations,
|
||||||
|
@"nextday", NSNextNextDayDesignations,
|
||||||
|
@"yesterday", NSPriorDayDesignations,
|
||||||
|
@"today", NSThisDayDesignations,
|
||||||
|
earlyt, NSEarlierTimeDesignations,
|
||||||
|
latert, NSLaterTimeDesignations,
|
||||||
|
hour_names, NSHourNameDesignations,
|
||||||
|
ymw_names, NSYearMonthWeekDesignations,
|
||||||
nil];
|
nil];
|
||||||
[defs registerDefaults: registrationDefaults];
|
[defs registerDefaults: registrationDefaults];
|
||||||
}
|
}
|
||||||
|
@ -184,6 +240,642 @@
|
||||||
return [[[self alloc] init] autorelease];
|
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
|
+ (id) dateWithString: (NSString*)description
|
||||||
{
|
{
|
||||||
return [[[self alloc] initWithString: description] autorelease];
|
return [[[self alloc] initWithString: description] autorelease];
|
||||||
|
|
|
@ -143,6 +143,16 @@ NSString *NSCurrencyString = @"NSCurrencyString";
|
||||||
NSString *NSDecimalDigits = @"NSDecimalDigits";
|
NSString *NSDecimalDigits = @"NSDecimalDigits";
|
||||||
NSString *NSAMPMDesignation = @"NSAMPMDesignation";
|
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 */
|
/* Standard MapTable callbacks */
|
||||||
|
|
||||||
const NSMapTableKeyCallBacks NSIntMapKeyCallBacks =
|
const NSMapTableKeyCallBacks NSIntMapKeyCallBacks =
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue