mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +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
540821fe94
commit
2b484cbee4
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>
|
||||
|
||||
* src/Makefile.postamble: new variable INSTALL_ROOT_DIR, such that
|
||||
|
|
|
@ -28,6 +28,7 @@
|
|||
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <Foundation/NSObject.h>
|
||||
|
||||
#include <Foundation/NSArchiver.h>
|
||||
#include <Foundation/NSArray.h>
|
||||
#include <Foundation/NSAttributedString.h>
|
||||
|
@ -38,14 +39,20 @@
|
|||
#include <Foundation/NSCoder.h>
|
||||
#include <Foundation/NSConnection.h>
|
||||
#include <Foundation/NSDate.h>
|
||||
#include <Foundation/NSDateFormatter.h>
|
||||
#include <Foundation/NSData.h>
|
||||
#include <Foundation/NSDebug.h>
|
||||
#include <Foundation/NSDictionary.h>
|
||||
#include <Foundation/NSDecimalNumber.h>
|
||||
#include <Foundation/NSDistantObject.h>
|
||||
#include <Foundation/NSDistributedLock.h>
|
||||
#include <Foundation/NSDistributedNotificationCenter.h>
|
||||
#include <Foundation/NSEnumerator.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSFileHandle.h>
|
||||
#include <Foundation/NSFileManager.h>
|
||||
#include <Foundation/NSFormatter.h>
|
||||
#include <Foundation/NSHashTable.h>
|
||||
#include <Foundation/NSGeometry.h>
|
||||
#include <Foundation/NSHost.h>
|
||||
#include <Foundation/NSInvocation.h>
|
||||
#include <Foundation/NSLock.h>
|
||||
|
@ -54,15 +61,23 @@
|
|||
#include <Foundation/NSNotification.h>
|
||||
#include <Foundation/NSNotificationQueue.h>
|
||||
#include <Foundation/NSPortCoder.h>
|
||||
#include <Foundation/NSPortMessage.h>
|
||||
#include <Foundation/NSPortNameServer.h>
|
||||
#include <Foundation/NSProcessInfo.h>
|
||||
#include <Foundation/NSProtocolChecker.h>
|
||||
#include <Foundation/NSProxy.h>
|
||||
#include <Foundation/NSRange.h>
|
||||
#include <Foundation/NSRunLoop.h>
|
||||
#include <Foundation/NSScanner.h>
|
||||
#include <Foundation/NSSerialization.h>
|
||||
#include <Foundation/NSSet.h>
|
||||
#include <Foundation/NSString.h>
|
||||
#include <Foundation/NSTask.h>
|
||||
#include <Foundation/NSTimer.h>
|
||||
#include <Foundation/NSThread.h>
|
||||
#include <Foundation/NSValue.h>
|
||||
#include <Foundation/NSTimer.h>
|
||||
#include <Foundation/NSUndoManager.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/NSValue.h>
|
||||
#include <Foundation/NSZone.h>
|
||||
|
||||
#endif /* __Foundation_h_GNUSTEP_BASE_INCLUDE */
|
||||
|
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 \
|
||||
|
|
|
@ -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; \
|
||||
|
|
694
Source/NSDate.m
694
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 <jeremy@hksys.com>
|
||||
Rewritten by: Scott Christley <scottc@net-community.com>
|
||||
Date: March 1995
|
||||
Modifications by: Richard Frith-Macdonald <richard@brainstorm.co.uk>
|
||||
|
||||
This file is part of the GNUstep Base Library.
|
||||
|
||||
|
@ -36,6 +37,8 @@
|
|||
#include <Foundation/NSCoder.h>
|
||||
#include <Foundation/NSException.h>
|
||||
#include <Foundation/NSUserDefaults.h>
|
||||
#include <Foundation/NSCharacterSet.h>
|
||||
#include <Foundation/NSScanner.h>
|
||||
#ifndef __WIN32__
|
||||
#include <time.h>
|
||||
#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];
|
||||
|
|
|
@ -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 =
|
||||
|
|
Loading…
Reference in a new issue