mirror of
https://github.com/gnustep/libs-base.git
synced 2025-04-22 16:33:29 +00:00
Started implementing new NSDateFormatter methods.
git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/base/trunk@31926 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
parent
ee6a2e5f51
commit
b3bf4189cc
6 changed files with 3073 additions and 16607 deletions
|
@ -1,3 +1,11 @@
|
|||
2011-01-22 Stefan Bidigaray <stefanbidi@gmail.com>
|
||||
|
||||
* configure:
|
||||
* configure.ac:
|
||||
* Headers/Additions/GNUstepBase/config.h.in: Added check for unicode/udat.h.
|
||||
* Headers/Foundation/NSDateFormatter.h:
|
||||
* Source/NSDateFormatter.m: Implemented a few methods.
|
||||
|
||||
2011-01-22 Stefan Bidigaray <stefanbidi@gmail.com>
|
||||
|
||||
* Headers/Foundation/NSDateFormatter.h:
|
||||
|
|
|
@ -621,6 +621,9 @@
|
|||
/* Define to 1 if you have the <unicode/unum.h> header file. */
|
||||
#undef HAVE_UNICODE_UNUM_H
|
||||
|
||||
/* Define to 1 if you have the <unicode/udat.h> header file. */
|
||||
#undef HAVE_UNICODE_UDAT_H
|
||||
|
||||
/* Define to 1 if you have the <unicode/uregex.h> header file. */
|
||||
#undef HAVE_UNICODE_UREGEX_H
|
||||
|
||||
|
|
|
@ -127,6 +127,12 @@ typedef NSUInteger NSDateFormatterBehavior;
|
|||
#if GS_EXPOSE(NSDateFormatter)
|
||||
NSString *_dateFormat;
|
||||
BOOL _allowsNaturalLanguage;
|
||||
NSUInteger _behavior;
|
||||
NSLocale *_locale;
|
||||
NSTimeZone *_tz;
|
||||
NSDateFormatterStyle _timeStyle;
|
||||
NSDateFormatterStyle _dateStyle;
|
||||
void *_formatter;
|
||||
#endif
|
||||
#if !GS_NONFRAGILE
|
||||
void *_unused;
|
||||
|
|
|
@ -27,17 +27,65 @@
|
|||
|
||||
#import "common.h"
|
||||
#define EXPOSE_NSDateFormatter_IVARS 1
|
||||
#import "Foundation/NSArray.h"
|
||||
#import "Foundation/NSDate.h"
|
||||
#import "Foundation/NSCalendar.h"
|
||||
#import "Foundation/NSCalendarDate.h"
|
||||
#import "Foundation/NSLocale.h"
|
||||
#import "Foundation/NSTimeZone.h"
|
||||
#import "Foundation/NSFormatter.h"
|
||||
#import "Foundation/NSDateFormatter.h"
|
||||
#import "Foundation/NSCoder.h"
|
||||
|
||||
#include <unicode/udat.h>
|
||||
|
||||
|
||||
|
||||
#define BUFFER_SIZE 1024
|
||||
|
||||
@interface NSDateFormatter (PrivateMethods)
|
||||
- (void) _resetUDateFormat;
|
||||
- (void) _setSymbols: (NSArray *) array : (NSInteger) symbol;
|
||||
- (NSArray *) _getSymbols: (NSInteger) symbol;
|
||||
@end
|
||||
|
||||
static inline NSInteger _NSToUDateFormatStyle (NSDateFormatterStyle style)
|
||||
{
|
||||
switch (style)
|
||||
{
|
||||
case NSDateFormatterNoStyle:
|
||||
return UDAT_NONE;
|
||||
case NSDateFormatterShortStyle:
|
||||
return UDAT_SHORT;
|
||||
case NSDateFormatterMediumStyle:
|
||||
return UDAT_MEDIUM;
|
||||
case NSDateFormatterLongStyle:
|
||||
return UDAT_LONG;
|
||||
case NSDateFormatterFullStyle:
|
||||
return UDAT_FULL;
|
||||
}
|
||||
return UDAT_NONE;
|
||||
}
|
||||
|
||||
@implementation NSDateFormatter
|
||||
|
||||
static NSDateFormatterBehavior _defaultBehavior = 0;
|
||||
|
||||
- (id) init
|
||||
{
|
||||
self = [super init];
|
||||
if (self == nil)
|
||||
return nil;
|
||||
|
||||
_behavior = _defaultBehavior;
|
||||
_locale = [NSLocale currentLocale];
|
||||
_tz = [NSTimeZone defaultTimeZone];
|
||||
|
||||
[self _resetUDateFormat];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL) allowsNaturalLanguage
|
||||
{
|
||||
return _allowsNaturalLanguage;
|
||||
|
@ -168,12 +216,12 @@ static NSDateFormatterBehavior _defaultBehavior = 0;
|
|||
|
||||
- (NSDateFormatterBehavior) formatterBehavior
|
||||
{
|
||||
return 0;
|
||||
return _behavior;
|
||||
}
|
||||
|
||||
- (void) setFormatterBehavior: (NSDateFormatterBehavior) behavior
|
||||
{
|
||||
return;
|
||||
_behavior = behavior;
|
||||
}
|
||||
|
||||
- (BOOL) generatesCalendarDates
|
||||
|
@ -188,23 +236,91 @@ static NSDateFormatterBehavior _defaultBehavior = 0;
|
|||
|
||||
- (BOOL) isLenient
|
||||
{
|
||||
#if GS_USE_ICU == 1
|
||||
return (BOOL)udat_isLenient (_formatter);
|
||||
#else
|
||||
return NO;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void) setLenient: (BOOL) flag
|
||||
{
|
||||
#if GS_USE_ICU == 1
|
||||
udat_setLenient (_formatter, flag);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
- (NSDate *) dateFromString: (NSString *) string
|
||||
{
|
||||
#if GS_USE_ICU == 1
|
||||
NSDate *result = nil;
|
||||
UDate date;
|
||||
UChar *text;
|
||||
int32_t textLength;
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
int32_t pPos = 0;
|
||||
|
||||
textLength = [string length];
|
||||
text = NSZoneMalloc ([self zone], sizeof(UChar) * textLength);
|
||||
if (text == NULL)
|
||||
return nil;
|
||||
|
||||
[string getCharacters: text range: NSMakeRange (0, textLength)];
|
||||
|
||||
date = udat_parse (_formatter, text, textLength, &pPos, &err);
|
||||
if (U_SUCCESS(err))
|
||||
result =
|
||||
[NSDate dateWithTimeIntervalSince1970: (NSTimeInterval)(date / 1000.0)];
|
||||
|
||||
NSZoneFree ([self zone], text);
|
||||
return result;
|
||||
#else
|
||||
return nil;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (NSString *) stringFromDate: (NSDate *) date
|
||||
{
|
||||
#if GS_USE_ICU == 1
|
||||
NSString *result;
|
||||
int32_t length;
|
||||
unichar buffer[BUFFER_SIZE];
|
||||
unichar *string = buffer;
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
|
||||
length = udat_format (_formatter,
|
||||
[date timeIntervalSince1970] * 1000.0,
|
||||
string,
|
||||
BUFFER_SIZE,
|
||||
NULL,
|
||||
&err);
|
||||
if (U_FAILURE(err))
|
||||
return nil;
|
||||
if (length > BUFFER_SIZE)
|
||||
{
|
||||
string = NSZoneMalloc ([self zone], sizeof(UChar) * length);
|
||||
udat_format (_formatter,
|
||||
[date timeIntervalSince1970] * 1000.0,
|
||||
string,
|
||||
length,
|
||||
NULL,
|
||||
&err);
|
||||
if (U_FAILURE(err))
|
||||
return nil;
|
||||
}
|
||||
|
||||
result = [NSString stringWithCharacters: string length: length];
|
||||
|
||||
if (length > BUFFER_SIZE)
|
||||
NSZoneFree ([self zone], string);
|
||||
|
||||
return result;
|
||||
#else
|
||||
return nil;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (BOOL) getObjectValue: (out id *) obj
|
||||
|
@ -217,27 +333,42 @@ static NSDateFormatterBehavior _defaultBehavior = 0;
|
|||
|
||||
- (void) setDateFormat: (NSString *) string
|
||||
{
|
||||
#if GS_USE_ICU == 1
|
||||
UChar *pattern;
|
||||
int32_t patternLength;
|
||||
|
||||
patternLength = [string length];
|
||||
pattern = NSZoneMalloc ([self zone], sizeof(UChar) * patternLength);
|
||||
[string getCharacters: pattern range: NSMakeRange(0, patternLength)];
|
||||
|
||||
udat_applyPattern (_formatter, 0, pattern, patternLength);
|
||||
|
||||
NSZoneFree ([self zone], pattern);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (NSDateFormatterStyle) dateStyle
|
||||
{
|
||||
return 0;
|
||||
return _dateStyle;
|
||||
}
|
||||
|
||||
- (void) setDateStyle: (NSDateFormatterStyle) style
|
||||
{
|
||||
return;
|
||||
_dateStyle = style;
|
||||
[self _resetUDateFormat];
|
||||
}
|
||||
|
||||
- (NSDateFormatterStyle) timeStyle
|
||||
{
|
||||
return 0;
|
||||
return _timeStyle;
|
||||
}
|
||||
|
||||
- (void) setTimeStyle: (NSDateFormatterStyle) style
|
||||
{
|
||||
return;
|
||||
_timeStyle = style;
|
||||
[self _resetUDateFormat];
|
||||
}
|
||||
|
||||
- (NSCalendar *) calendar
|
||||
|
@ -262,22 +393,34 @@ static NSDateFormatterBehavior _defaultBehavior = 0;
|
|||
|
||||
- (NSLocale *) locale
|
||||
{
|
||||
return nil;
|
||||
return _locale;
|
||||
}
|
||||
|
||||
- (void) setLocale: (NSLocale *) locale
|
||||
{
|
||||
return;
|
||||
if (locale == _locale)
|
||||
return;
|
||||
if (_locale != nil)
|
||||
RELEASE(_locale);
|
||||
|
||||
_locale = RETAIN(locale);
|
||||
[self _resetUDateFormat];
|
||||
}
|
||||
|
||||
- (NSTimeZone *) timeZone
|
||||
{
|
||||
return nil;
|
||||
return _tz;
|
||||
}
|
||||
|
||||
- (void) setTimeZone: (NSTimeZone *) tz
|
||||
{
|
||||
return;
|
||||
if (tz == _tz)
|
||||
return;
|
||||
if (_tz != nil)
|
||||
RELEASE(_tz);
|
||||
|
||||
_tz = RETAIN(tz);
|
||||
[self _resetUDateFormat];
|
||||
}
|
||||
|
||||
- (NSDate *) twoDigitStartDate
|
||||
|
@ -506,7 +649,16 @@ static NSDateFormatterBehavior _defaultBehavior = 0;
|
|||
dateStyle: (NSDateFormatterStyle) dateStyle
|
||||
timeStyle: (NSDateFormatterStyle) timeStyle
|
||||
{
|
||||
return nil;
|
||||
NSString *result;
|
||||
NSDateFormatter *fmt = [[self alloc] init];
|
||||
|
||||
[fmt setDateStyle: dateStyle];
|
||||
[fmt setTimeStyle: timeStyle];
|
||||
|
||||
result = [fmt stringFromDate: date];
|
||||
RELEASE(fmt);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
+ (NSString *) dateFormatFromTemplate: (NSString *) template
|
||||
|
@ -525,6 +677,106 @@ static NSDateFormatterBehavior _defaultBehavior = 0;
|
|||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation NSDateFormatter (PrivateMethods)
|
||||
- (void) _resetUDateFormat
|
||||
{
|
||||
#if GS_USE_ICU == 1
|
||||
UChar *tzID;
|
||||
int32_t tzIDLength;
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
|
||||
if (_formatter)
|
||||
udat_close (_formatter);
|
||||
|
||||
tzIDLength = [[_tz name] length];
|
||||
tzID = NSZoneMalloc ([self zone], sizeof(UChar) * tzIDLength);
|
||||
[[_tz name] getCharacters: tzID range: NSMakeRange (0, tzIDLength)];
|
||||
|
||||
_formatter = udat_open (_NSToUDateFormatStyle(_timeStyle),
|
||||
_NSToUDateFormatStyle(_dateStyle),
|
||||
[[_locale localeIdentifier] UTF8String],
|
||||
tzID,
|
||||
tzIDLength,
|
||||
NULL,
|
||||
0,
|
||||
&err);
|
||||
if (U_FAILURE(err))
|
||||
_formatter = NULL;
|
||||
|
||||
NSZoneFree ([self zone], tzID);
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (void) _setSymbols: (NSArray *) array : (NSInteger) symbol
|
||||
{
|
||||
#if GS_USE_ICU == 1
|
||||
int idx = 0;
|
||||
int count = udat_countSymbols (_formatter, symbol);
|
||||
|
||||
if ([array count] != count)
|
||||
return;
|
||||
|
||||
while (idx < count)
|
||||
{
|
||||
int length;
|
||||
UChar *value;
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
NSString *string = [array objectAtIndex: idx];
|
||||
|
||||
length = [string length];
|
||||
value = NSZoneMalloc ([self zone], sizeof(unichar) * length);
|
||||
[string getCharacters: value range: NSMakeRange(0, length)];
|
||||
|
||||
udat_setSymbols (_formatter, symbol, idx, value, length, &err);
|
||||
|
||||
NSZoneFree ([self zone], value);
|
||||
|
||||
++idx;
|
||||
}
|
||||
#else
|
||||
return;
|
||||
#endif
|
||||
}
|
||||
|
||||
- (NSArray *) _getSymbols: (NSInteger) symbol
|
||||
{
|
||||
#if GS_USE_ICU == 1
|
||||
NSMutableArray *mArray;
|
||||
int idx = 0;
|
||||
int count = udat_countSymbols (_formatter, symbol);
|
||||
|
||||
mArray = [NSMutableArray arrayWithCapacity: count];
|
||||
while (idx < count)
|
||||
{
|
||||
int length;
|
||||
unichar buffer[BUFFER_SIZE];
|
||||
unichar *value = buffer;
|
||||
UErrorCode err = U_ZERO_ERROR;
|
||||
|
||||
length =
|
||||
udat_getSymbols (_formatter, symbol, idx, value, BUFFER_SIZE, &err);
|
||||
if (length > BUFFER_SIZE)
|
||||
{
|
||||
value = NSZoneMalloc ([self zone], sizeof(unichar) * length);
|
||||
udat_getSymbols (_formatter, symbol, idx, value, length, &err);
|
||||
}
|
||||
|
||||
[mArray addObject: [NSString stringWithCharacters: value length: length]];
|
||||
|
||||
if (length > BUFFER_SIZE)
|
||||
NSZoneFree ([self zone], value);
|
||||
|
||||
++idx;
|
||||
}
|
||||
|
||||
return [NSArray arrayWithArray: mArray];;
|
||||
#else
|
||||
return nil;
|
||||
#endif
|
||||
}
|
||||
@end
|
||||
|
||||
|
|
|
@ -2690,7 +2690,7 @@ if test $enable_icu = yes; then
|
|||
AC_CHECK_ICU(4.0, have_icu=yes, have_icu=no)
|
||||
if test "$have_icu" = "yes"; then
|
||||
AC_MSG_RESULT(yes)
|
||||
AC_CHECK_HEADERS(unicode/uloc.h unicode/ulocdata.h unicode/ucurr.h unicode/uregex.h unicode/ucal.h unicode/unum.h)
|
||||
AC_CHECK_HEADERS(unicode/uloc.h unicode/ulocdata.h unicode/ucurr.h unicode/uregex.h unicode/ucal.h unicode/unum.h unicode/udat.h)
|
||||
LIBS="$LIBS $ICU_LIBS"
|
||||
HAVE_ICU=1
|
||||
else
|
||||
|
|
Loading…
Reference in a new issue