mirror of
https://github.com/cappuccino/cappuccino.git
synced 2026-11-03 21:58:59 +00:00
Merge pull request #3321 from enquora/CPTimezone-modernize
Delegate CPTimezone data source to host browser
This commit is contained in:
4 files changed
+866
-2186
No files matched your search
+205
-205
@@ -46,19 +46,19 @@ CPDateFormatterBehavior10_0 = 1000;
|
||||
CPDateFormatterBehavior10_4 = 1040;
|
||||
|
||||
var defaultDateFormatterBehavior = CPDateFormatterBehavior10_4,
|
||||
relativeDateFormating,
|
||||
patternStringTokens;
|
||||
relativeDateFormatting,
|
||||
patternStringTokens;
|
||||
|
||||
var _separatorsCharacterSet = nil;
|
||||
|
||||
/*!
|
||||
@ingroup foundation
|
||||
@class CPDateFormatter
|
||||
@ingroup foundation
|
||||
@class CPDateFormatter
|
||||
|
||||
CPDateFormatter takes a CPDate value and formats it as text for
|
||||
display. It also supports the converse, taking text and interpreting it as a
|
||||
CPDate by configurable formatting rules.
|
||||
*/
|
||||
CPDateFormatter takes a CPDate value and formats it as text for
|
||||
display. It also supports the converse, taking text and interpreting it as a
|
||||
CPDate by configurable formatting rules.
|
||||
*/
|
||||
@implementation CPDateFormatter : CPFormatter
|
||||
{
|
||||
BOOL _allowNaturalLanguage @accessors(property=allowNaturalLanguage, readonly);
|
||||
@@ -83,22 +83,22 @@ var _separatorsCharacterSet = nil;
|
||||
if (self !== [CPDateFormatter class])
|
||||
return;
|
||||
|
||||
relativeDateFormating = @{
|
||||
@"fr" : [@"demain", 1, @"apr" + String.fromCharCode(233) + @"s-demain", 2, @"apr" + String.fromCharCode(233) + @"s-apr" + String.fromCharCode(233) + @"s-demain", 3, @"hier", -1, @"avant-hier", -2, @"avant-avant-hier", -3],
|
||||
@"en" : [@"tomorrow", 1, @"yesterday", -1],
|
||||
@"de" : [@"morgen", 1, @"gestern", -1, String.fromCharCode(129) + @"bermorgen", 2, @"vorgestern", -2],
|
||||
@"es" : []
|
||||
relativeDateFormatting = @{
|
||||
@"fr" : [@"demain", 1, @"apr" + String.fromCharCode(233) + @"s-demain", 2, @"apr" + String.fromCharCode(233) + @"s-apr" + String.fromCharCode(233) + @"s-demain", 3, @"hier", -1, @"avant-hier", -2, @"avant-avant-hier", -3],
|
||||
@"en" : [@"tomorrow", 1, @"yesterday", -1],
|
||||
@"de" : [@"morgen", 1, @"gestern", -1, String.fromCharCode(129) + @"bermorgen", 2, @"vorgestern", -2],
|
||||
@"es" : []
|
||||
};
|
||||
|
||||
patternStringTokens = [@"QQQ", @"qqq", @"QQQQ", @"qqqq", @"MMM", @"MMMM", @"LLL", @"LLLL", @"E", @"EE", @"EEE", @"eee", @"eeee", @"eeeee", @"a", @"z", @"zz", @"zzz", @"zzzz", @"Z", @"ZZ", @"ZZZ", @"ZZZZ", @"ZZZZZ", @"v", @"vv", @"vvv", @"vvvv", @"V", @"VV", @"VVV", @"VVVV"];
|
||||
}
|
||||
|
||||
/*! Return a string representation of the given date, dateStyle and timeStyle
|
||||
@param date the given date
|
||||
@param dateStyle the dateStyle
|
||||
@param timeStyle the timeStyle
|
||||
@return a CPString reprensenting the given date
|
||||
*/
|
||||
@param date the given date
|
||||
@param dateStyle the dateStyle
|
||||
@param timeStyle the timeStyle
|
||||
@return a CPString reprensenting the given date
|
||||
*/
|
||||
+ (CPString)localizedStringFromDate:(CPDate)date dateStyle:(CPDateFormatterStyle)dateStyle timeStyle:(CPDateFormatterStyle)timeStyle
|
||||
{
|
||||
var formatter = [[CPDateFormatter alloc] init];
|
||||
@@ -111,28 +111,29 @@ var _separatorsCharacterSet = nil;
|
||||
}
|
||||
|
||||
/*! Not yet implemented
|
||||
Return a string representation of the given template, opts and locale
|
||||
@param template the template
|
||||
@param opts, pass 0
|
||||
@param locale the locale
|
||||
@return a CPString representing the givent template
|
||||
*/
|
||||
Return a string representation of the given template, opts and locale
|
||||
@param template the template
|
||||
@param opts, pass 0
|
||||
@param locale the locale
|
||||
@return a CPString representing the givent template
|
||||
*/
|
||||
+ (CPString)dateFormatFromTemplate:(CPString)template options:(CPUInteger)opts locale:(CPLocale)locale
|
||||
{
|
||||
// TODO : check every template from cocoa and return a good format (have fun ^^)
|
||||
// TODO : check every template from cocoa and return a good format
|
||||
return template;
|
||||
}
|
||||
|
||||
/*! Return the defaultFormatterBehavior
|
||||
@return a CPDateFormatterBehavior
|
||||
*/
|
||||
@return a CPDateFormatterBehavior
|
||||
*/
|
||||
+ (CPDateFormatterBehavior)defaultFormatterBehavior
|
||||
{
|
||||
return defaultDateFormatterBehavior;
|
||||
}
|
||||
|
||||
/*! Set the defaultFormatterBehavior
|
||||
@param behavior
|
||||
*/
|
||||
@param behavior
|
||||
*/
|
||||
+ (void)setDefaultFormatterBehavior:(CPDateFormatterBehavior)behavior
|
||||
{
|
||||
defaultDateFormatterBehavior = behavior;
|
||||
@@ -147,8 +148,8 @@ var _separatorsCharacterSet = nil;
|
||||
}
|
||||
|
||||
/*! Init a dateFormatter
|
||||
@return a new CPDateFormatter
|
||||
*/
|
||||
@return a new CPDateFormatter
|
||||
*/
|
||||
- (id)init
|
||||
{
|
||||
if (self = [super init])
|
||||
@@ -163,10 +164,10 @@ var _separatorsCharacterSet = nil;
|
||||
}
|
||||
|
||||
/*! Init a dateFormatter with a format and the naturalLanguage
|
||||
@param format the format
|
||||
@param flag flag representation of allowNaturalLanguage
|
||||
@return a new CPDateFormatter
|
||||
*/
|
||||
@param format the format
|
||||
@param flag flag representation of allowNaturalLanguage
|
||||
@return a new CPDateFormatter
|
||||
*/
|
||||
- (id)initWithDateFormat:(CPString)format allowNaturalLanguage:(BOOL)flag
|
||||
{
|
||||
if (self = [self init])
|
||||
@@ -175,31 +176,31 @@ var _separatorsCharacterSet = nil;
|
||||
_allowNaturalLanguage = flag;
|
||||
}
|
||||
|
||||
return self
|
||||
return self;
|
||||
}
|
||||
|
||||
/*! Private init
|
||||
*/
|
||||
*/
|
||||
- (void)_init
|
||||
{
|
||||
var AMSymbol = [CPString stringWithFormat:@"%s", @"AM"],
|
||||
PMSymbol = [CPString stringWithFormat:@"%s", @"PM"],
|
||||
weekdaySymbols = [CPArray arrayWithObjects:@"Sunday", @"Monday", @"Tuesday", @"Wednesday", @"Thursday", @"Friday", @"Saturday"],
|
||||
shortWeekdaySymbols = [CPArray arrayWithObjects:@"Sun", @"Mon", @"Tue", @"Wed", @"Thu", @"Fri", @"Sat"],
|
||||
veryShortWeekdaySymbols = [CPArray arrayWithObjects:@"S", @"M", @"T", @"W", @"T", @"F", @"S"],
|
||||
standaloneWeekdaySymbols = [CPArray arrayWithObjects:@"Sunday", @"Monday", @"Tuesday", @"Wednesday", @"Thursday", @"Friday", @"Saturday"],
|
||||
shortStandaloneWeekdaySymbols = [CPArray arrayWithObjects:@"Sun", @"Mon", @"Tue", @"Wed", @"Thu", @"Fri", @"Sat"],
|
||||
veryShortStandaloneWeekdaySymbols = [CPArray arrayWithObjects:@"S", @"M", @"T", @"W", @"T", @"F", @"S"],
|
||||
monthSymbols = [CPArray arrayWithObjects:@"January", @"February", @"March", @"April", @"May", @"June", @"July", @"August", @"September", @"October", @"November", @"December"],
|
||||
shortMonthSymbols = [CPArray arrayWithObjects:@"Jan", @"Feb", @"Mar", @"Apr", @"May", @"Jun", @"Jul", @"Aug", @"Sep", @"Oct", @"Nov", @"Dec"],
|
||||
veryShortMonthSymbols = [CPArray arrayWithObjects:@"J", @"F", @"M", @"A", @"M", @"J", @"J", @"A", @"S", @"O", @"N", @"D"],
|
||||
standaloneMonthSymbols = [CPArray arrayWithObjects:@"January", @"February", @"March", @"April", @"May", @"June", @"July", @"August", @"September", @"October", @"November", @"December"],
|
||||
shortStandaloneMonthSymbols = [CPArray arrayWithObjects:@"Jan", @"Feb", @"Mar", @"Apr", @"May", @"Jun", @"Jul", @"Aug", @"Sep", @"Oct", @"Nov", @"Dec"],
|
||||
veryShortStandaloneMonthSymbols = [CPArray arrayWithObjects:@"J", @"F", @"M", @"A", @"M", @"J", @"J", @"A", @"S", @"O", @"N", @"D"],
|
||||
quarterSymbols = [CPArray arrayWithObjects:@"1st quarter", @"2nd quarter", @"3rd quarter", @"4th quarter"],
|
||||
shortQuarterSymbols = [CPArray arrayWithObjects:@"Q1", @"Q2", @"Q3", @"Q4"],
|
||||
standaloneQuarterSymbols = [CPArray arrayWithObjects:@"1st quarter", @"2nd quarter", @"3rd quarter", @"4th quarter"],
|
||||
shortStandaloneQuarterSymbols = [CPArray arrayWithObjects:@"Q1", @"Q2", @"Q3", @"Q4"];
|
||||
PMSymbol = [CPString stringWithFormat:@"%s", @"PM"],
|
||||
weekdaySymbols = [CPArray arrayWithObjects:@"Sunday", @"Monday", @"Tuesday", @"Wednesday", @"Thursday", @"Friday", @"Saturday"],
|
||||
shortWeekdaySymbols = [CPArray arrayWithObjects:@"Sun", @"Mon", @"Tue", @"Wed", @"Thu", @"Fri", @"Sat"],
|
||||
veryShortWeekdaySymbols = [CPArray arrayWithObjects:@"S", @"M", @"T", @"W", @"T", @"F", @"S"],
|
||||
standaloneWeekdaySymbols = [CPArray arrayWithObjects:@"Sunday", @"Monday", @"Tuesday", @"Wednesday", @"Thursday", @"Friday", @"Saturday"],
|
||||
shortStandaloneWeekdaySymbols = [CPArray arrayWithObjects:@"Sun", @"Mon", @"Tue", @"Wed", @"Thu", @"Fri", @"Sat"],
|
||||
veryShortStandaloneWeekdaySymbols = [CPArray arrayWithObjects:@"S", @"M", @"T", @"W", @"T", @"F", @"S"],
|
||||
monthSymbols = [CPArray arrayWithObjects:@"January", @"February", @"March", @"April", @"May", @"June", @"July", @"August", @"September", @"October", @"November", @"December"],
|
||||
shortMonthSymbols = [CPArray arrayWithObjects:@"Jan", @"Feb", @"Mar", @"Apr", @"May", @"Jun", @"Jul", @"Aug", @"Sep", @"Oct", @"Nov", @"Dec"],
|
||||
veryShortMonthSymbols = [CPArray arrayWithObjects:@"J", @"F", @"M", @"A", @"M", @"J", @"J", @"A", @"S", @"O", @"N", @"D"],
|
||||
standaloneMonthSymbols = [CPArray arrayWithObjects:@"January", @"February", @"March", @"April", @"May", @"June", @"July", @"August", @"September", @"October", @"November", @"December"],
|
||||
shortStandaloneMonthSymbols = [CPArray arrayWithObjects:@"Jan", @"Feb", @"Mar", @"Apr", @"May", @"Jun", @"Jul", @"Aug", @"Sep", @"Oct", @"Nov", @"Dec"],
|
||||
veryShortStandaloneMonthSymbols = [CPArray arrayWithObjects:@"J", @"F", @"M", @"A", @"M", @"J", @"J", @"A", @"S", @"O", @"N", @"D"],
|
||||
quarterSymbols = [CPArray arrayWithObjects:@"1st quarter", @"2nd quarter", @"3rd quarter", @"4th quarter"],
|
||||
shortQuarterSymbols = [CPArray arrayWithObjects:@"Q1", @"Q2", @"Q3", @"Q4"],
|
||||
standaloneQuarterSymbols = [CPArray arrayWithObjects:@"1st quarter", @"2nd quarter", @"3rd quarter", @"4th quarter"],
|
||||
shortStandaloneQuarterSymbols = [CPArray arrayWithObjects:@"Q1", @"Q2", @"Q3", @"Q4"];
|
||||
|
||||
_symbols = @{
|
||||
@"root" : @{
|
||||
@@ -235,7 +236,7 @@ var _separatorsCharacterSet = nil;
|
||||
// MARK: Setter Getter Helper
|
||||
|
||||
/*! Return symbols for the given language code
|
||||
*/
|
||||
*/
|
||||
- (CPDictionary)symbolsForLanguageCode:(CPString)languageCode
|
||||
{
|
||||
var languageSymbols = [_symbols valueForKey:languageCode];
|
||||
@@ -250,18 +251,18 @@ var _separatorsCharacterSet = nil;
|
||||
}
|
||||
|
||||
/*! Set the symbols for the given language code
|
||||
*/
|
||||
*/
|
||||
- (void)setSymbols:(CPDictionary)symbols forLanguageCode:(CPString)languageCode
|
||||
{
|
||||
[_symbols setValue:symbols forKey:languageCode];
|
||||
}
|
||||
|
||||
/*! Return a symbol specified by the given key for the given language code
|
||||
*/
|
||||
*/
|
||||
- (id)symbolForKey:(CPString)aKey languageCode:(CPString)languageCode
|
||||
{
|
||||
var languageSymbols = [self symbolsForLanguageCode:languageCode],
|
||||
symbol = [languageSymbols valueForKey:aKey];
|
||||
symbol = [languageSymbols valueForKey:aKey];
|
||||
|
||||
if (!symbol)
|
||||
{
|
||||
@@ -273,7 +274,7 @@ var _separatorsCharacterSet = nil;
|
||||
}
|
||||
|
||||
/*! Set the symbol specified by the given key for the given language code
|
||||
*/
|
||||
*/
|
||||
- (void)setSymbol:(CPString)aSymbol forKey:(CPString)aKey languageCode:(CPString)languageCode
|
||||
{
|
||||
var languageSymbols = [self symbolsForLanguageCode:languageCode];
|
||||
@@ -284,252 +285,252 @@ var _separatorsCharacterSet = nil;
|
||||
// MARK: Setter Getter
|
||||
|
||||
/*! Return AMSymbol
|
||||
*/
|
||||
*/
|
||||
- (CPString)AMSymbol
|
||||
{
|
||||
return [self symbolForKey:@"AMSymbol" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the AMSymbol
|
||||
*/
|
||||
*/
|
||||
- (void)setAMSymbol:(CPString)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"AMSymbol" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return a PMSymbol
|
||||
*/
|
||||
*/
|
||||
- (CPString)PMSymbol
|
||||
{
|
||||
return [self symbolForKey:@"PMSymbol" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the PMSymbol
|
||||
*/
|
||||
*/
|
||||
- (void)setPMSymbol:(CPString)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"PMSymbol" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return the weekdaySymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)weekdaySymbols
|
||||
{
|
||||
return [self symbolForKey:@"weekdaySymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the weekdaySymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setWeekdaySymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"weekdaySymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return a shortWeekdaySymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)shortWeekdaySymbols
|
||||
{
|
||||
return [self symbolForKey:@"shortWeekdaySymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the shortWeekdaySymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setShortWeekdaySymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"shortWeekdaySymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return veryShortWeekdaySymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)veryShortWeekdaySymbols
|
||||
{
|
||||
return [self symbolForKey:@"veryShortWeekdaySymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the veryShortWeekdaySymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setVeryShortWeekdaySymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"veryShortWeekdaySymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return the standaloneWeekdaySymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)standaloneWeekdaySymbols
|
||||
{
|
||||
return [self symbolForKey:@"standaloneWeekdaySymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the standaloneWeekdaySymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setStandaloneWeekdaySymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"standaloneWeekdaySymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return the shortStandaloneWeekdaySymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)shortStandaloneWeekdaySymbols
|
||||
{
|
||||
return [self symbolForKey:@"shortStandaloneWeekdaySymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the shortStandaloneWeekdaySymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setShortStandaloneWeekdaySymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"shortStandaloneWeekdaySymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return the veryShortStandaloneWeekdaySymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)veryShortStandaloneWeekdaySymbols
|
||||
{
|
||||
return [self symbolForKey:@"veryShortStandaloneWeekdaySymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the veryShortStandaloneWeekdaySymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setVeryShortStandaloneWeekdaySymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"veryShortStandaloneWeekdaySymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return the monthSymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)monthSymbols
|
||||
{
|
||||
return [self symbolForKey:@"monthSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the monthSymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setMonthSymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"monthSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return a shortMonthSymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)shortMonthSymbols
|
||||
{
|
||||
return [self symbolForKey:@"shortMonthSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the shortMonthSymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setShortMonthSymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"shortMonthSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return veryShortMonthSymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)veryShortMonthSymbols
|
||||
{
|
||||
return [self symbolForKey:@"veryShortMonthSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the veryShortMonthSymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setVeryShortMonthSymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"veryShortMonthSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return standaloneMonthSymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)standaloneMonthSymbols
|
||||
{
|
||||
return [self symbolForKey:@"standaloneMonthSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the standaloneMonthSymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setStandaloneMonthSymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"standaloneMonthSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return the shortStandaloneMonthSymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)shortStandaloneMonthSymbols
|
||||
{
|
||||
return [self symbolForKey:@"shortStandaloneMonthSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the shortStandaloneMonthSymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setShortStandaloneMonthSymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"shortStandaloneMonthSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return the veryShortStandaloneMonthSymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)veryShortStandaloneMonthSymbols
|
||||
{
|
||||
return [self symbolForKey:@"veryShortStandaloneMonthSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the veryShortStandaloneMonthSymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setVeryShortStandaloneMonthSymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"veryShortStandaloneMonthSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return the quarterSymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)quarterSymbols
|
||||
{
|
||||
return [self symbolForKey:@"quarterSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the quarterSymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setQuarterSymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"quarterSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return the shortQuarterSymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)shortQuarterSymbols
|
||||
{
|
||||
return [self symbolForKey:@"shortQuarterSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the shortQuarterSymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setShortQuarterSymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"shortQuarterSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return the standaloneQuarterSymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)standaloneQuarterSymbols
|
||||
{
|
||||
return [self symbolForKey:@"standaloneQuarterSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the standaloneQuarterSymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setStandaloneQuarterSymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"standaloneQuarterSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Return the shortStandaloneQuarterSymbols
|
||||
*/
|
||||
*/
|
||||
- (CPArray)shortStandaloneQuarterSymbols
|
||||
{
|
||||
return [self symbolForKey:@"shortStandaloneQuarterSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
}
|
||||
|
||||
/*! Set the shortStandaloneQuarterSymbols
|
||||
*/
|
||||
*/
|
||||
- (void)setShortStandaloneQuarterSymbols:(CPArray)aValue
|
||||
{
|
||||
[self setSymbol:aValue forKey:@"shortStandaloneQuarterSymbols" languageCode:[_locale objectForKey:CPLocaleLanguageCode]];
|
||||
@@ -540,18 +541,18 @@ var _separatorsCharacterSet = nil;
|
||||
// MARK: StringFromDate methods
|
||||
|
||||
/*! Return a string representation of a given date.
|
||||
This method returns (if possible) a representation of the given date with the dateFormat of the CPDateFormatter, otherwise it takes the dateStyle and timeStyle
|
||||
@param aDate the given date
|
||||
@return CPString the string representation
|
||||
*/
|
||||
This method returns (if possible) a representation of the given date with the dateFormat of the CPDateFormatter, otherwise it takes the dateStyle and timeStyle
|
||||
@param aDate the given date
|
||||
@return CPString the string representation
|
||||
*/
|
||||
- (CPString)stringFromDate:(CPDate)aDate
|
||||
{
|
||||
var format,
|
||||
relativeWord,
|
||||
result;
|
||||
relativeWord,
|
||||
result;
|
||||
|
||||
if (!aDate)
|
||||
return;
|
||||
return nil;
|
||||
|
||||
aDate = [aDate copy];
|
||||
[aDate _dateWithTimeZone:_timeZone];
|
||||
@@ -611,7 +612,7 @@ var _separatorsCharacterSet = nil;
|
||||
if ([self doesRelativeDateFormatting])
|
||||
{
|
||||
var language = [_locale objectForKey:CPLocaleLanguageCode],
|
||||
relativeWords = [relativeDateFormating valueForKey:language];
|
||||
relativeWords = [relativeDateFormatting valueForKey:language];
|
||||
|
||||
for (var i = 1; i < [relativeWords count]; i = i + 2)
|
||||
{
|
||||
@@ -687,10 +688,10 @@ var _separatorsCharacterSet = nil;
|
||||
}
|
||||
|
||||
/*! Return a string representation of the given objectValue.
|
||||
This method call the method stringFromDate if possible, otherwise it returns the description of the object
|
||||
@param anObject
|
||||
@return a string
|
||||
*/
|
||||
This method call the method stringFromDate if possible, otherwise it returns the description of the object
|
||||
@param anObject
|
||||
@return a string
|
||||
*/
|
||||
- (CPString)stringForObjectValue:(id)anObject
|
||||
{
|
||||
if ([anObject isKindOfClass:[CPDate class]])
|
||||
@@ -700,26 +701,26 @@ var _separatorsCharacterSet = nil;
|
||||
}
|
||||
|
||||
/*! Return a string
|
||||
This method call the method stringForObjectValue
|
||||
@param anObject
|
||||
@return a string
|
||||
*/
|
||||
This method call the method stringForObjectValue
|
||||
@param anObject
|
||||
@return a string
|
||||
*/
|
||||
- (CPString)editingStringForObjectValue:(id)anObject
|
||||
{
|
||||
return [self stringForObjectValue:anObject];
|
||||
}
|
||||
|
||||
/*! Return a string representation of the given date and format
|
||||
@patam aDate
|
||||
@param aFormat
|
||||
@return a string
|
||||
*/
|
||||
@patam aDate
|
||||
@param aFormat
|
||||
@return a string
|
||||
*/
|
||||
- (CPString)_stringFromDate:(CPDate)aDate format:(CPString)aFormat
|
||||
{
|
||||
var length = [aFormat length],
|
||||
currentToken = [CPString new],
|
||||
isTextToken = NO,
|
||||
result = [CPString new];
|
||||
currentToken = [CPString new],
|
||||
isTextToken = NO,
|
||||
result = [CPString new];
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
@@ -778,18 +779,18 @@ var _separatorsCharacterSet = nil;
|
||||
}
|
||||
|
||||
/*! Return a string representation of the given token and date
|
||||
@param aToken
|
||||
@param aDate
|
||||
@return a string
|
||||
*/
|
||||
@param aToken
|
||||
@param aDate
|
||||
@return a string
|
||||
*/
|
||||
- (CPString)_stringFromToken:(CPString)aToken date:(CPDate)aDate
|
||||
{
|
||||
if (![aToken length])
|
||||
return aToken;
|
||||
|
||||
var character = [aToken characterAtIndex:0],
|
||||
length = [aToken length],
|
||||
timeZone = _timeZone;
|
||||
length = [aToken length],
|
||||
timeZone = _timeZone;
|
||||
|
||||
switch (character)
|
||||
{
|
||||
@@ -902,13 +903,13 @@ var _separatorsCharacterSet = nil;
|
||||
d.setDate(d.getDate() + 4 - (d.getDay() || 7));
|
||||
|
||||
var yearStart = new Date(d.getFullYear(), 0, 1),
|
||||
weekOfYear = Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
|
||||
weekOfYear = Math.ceil((((d - yearStart) / 86400000) + 1) / 7);
|
||||
|
||||
return [self _stringValueForValue:(weekOfYear + 1) length:MAX(2, length)];
|
||||
|
||||
case @"W":
|
||||
var firstDay = new Date(aDate.getFullYear(), aDate.getMonth(), 1).getDay(),
|
||||
weekOfMonth = Math.ceil((aDate.getDate() + firstDay) / 7);
|
||||
weekOfMonth = Math.ceil((aDate.getDate() + firstDay) / 7);
|
||||
|
||||
return [self _stringValueForValue:weekOfMonth length:1];
|
||||
|
||||
@@ -919,14 +920,14 @@ var _separatorsCharacterSet = nil;
|
||||
|
||||
case @"D":
|
||||
var oneJan = new Date(aDate.getFullYear(), 0, 1),
|
||||
dayOfYear = Math.ceil((aDate - oneJan) / 86400000),
|
||||
currentLength = [[CPString stringWithFormat:@"%i", dayOfYear] length];
|
||||
dayOfYear = Math.ceil((aDate - oneJan) / 86400000),
|
||||
currentLength = [[CPString stringWithFormat:@"%i", dayOfYear] length];
|
||||
|
||||
return [self _stringValueForValue:dayOfYear length:MAX(currentLength, MIN(3, length))];
|
||||
|
||||
case @"F":
|
||||
var dayOfWeek = 1,
|
||||
day = aDate.getDate();
|
||||
day = aDate.getDate();
|
||||
|
||||
if (day > 7 && day < 15)
|
||||
dayOfWeek = 2;
|
||||
@@ -1065,10 +1066,10 @@ var _separatorsCharacterSet = nil;
|
||||
|
||||
case @"Z":
|
||||
var seconds = [timeZone secondsFromGMT],
|
||||
minutes = seconds / 60,
|
||||
hours = minutes / 60,
|
||||
result,
|
||||
diffMinutes = (hours - parseInt(hours)) * 100 * 60 / 100;
|
||||
minutes = seconds / 60,
|
||||
hours = minutes / 60,
|
||||
result,
|
||||
diffMinutes = (hours - parseInt(hours)) * 100 * 60 / 100;
|
||||
|
||||
if (length <= 3)
|
||||
{
|
||||
@@ -1082,7 +1083,7 @@ var _separatorsCharacterSet = nil;
|
||||
while ([result length] < 4)
|
||||
result = @"0" + result;
|
||||
|
||||
if (seconds > 0)
|
||||
if (seconds >= 0)
|
||||
result = @"+" + result;
|
||||
else
|
||||
result = @"-" + result;
|
||||
@@ -1164,10 +1165,10 @@ var _separatorsCharacterSet = nil;
|
||||
// MARK: datefromString
|
||||
|
||||
/*! Return a date of the given string
|
||||
This method returns (if possible) a representation of the given string with the dateFormat of the CPDateFormatter, otherwise it takes the dateStyle and timeStyle
|
||||
@param aString
|
||||
@return CPDate the date
|
||||
*/
|
||||
This method returns (if possible) a representation of the given string with the dateFormat of the CPDateFormatter, otherwise it takes the dateStyle and timeStyle
|
||||
@param aString
|
||||
@return CPDate the date
|
||||
*/
|
||||
- (CPDate)dateFromString:(CPString)aString
|
||||
{
|
||||
var format;
|
||||
@@ -1259,11 +1260,11 @@ var _separatorsCharacterSet = nil;
|
||||
}
|
||||
|
||||
/*! Returns a boolean if the given object has been changed or not depending of the given string (use of ref)
|
||||
@param anObject the given object
|
||||
@param aString
|
||||
@param anError, if it returns NO the describe error will be in anError (use of ref)
|
||||
@return aBoolean for the success or fail of the method
|
||||
*/
|
||||
@param anObject the given object
|
||||
@param aString
|
||||
@param anError, if it returns NO the describe error will be in anError (use of ref)
|
||||
@return aBoolean for the success or fail of the method
|
||||
*/
|
||||
- (BOOL)getObjectValue:(idRef)anObject forString:(CPString)aString errorDescription:(CPStringRef)anError
|
||||
{
|
||||
var value = [self dateFromString:aString];
|
||||
@@ -1281,10 +1282,10 @@ var _separatorsCharacterSet = nil;
|
||||
}
|
||||
|
||||
/*! Return a date representation of the given string and format
|
||||
@patam aDate
|
||||
@param aFormat
|
||||
@return a string
|
||||
*/
|
||||
@patam aDate
|
||||
@param aFormat
|
||||
@return a string
|
||||
*/
|
||||
- (CPDate)_dateFromString:(CPString)aString format:(CPString)aFormat
|
||||
{
|
||||
// Interpret @"" as the date 2000-01-01 00:00:00 +0000, like in Cocoa. No idea why they picked this particular date.
|
||||
@@ -1307,10 +1308,10 @@ var _separatorsCharacterSet = nil;
|
||||
return nil;
|
||||
|
||||
var currentToken = [CPString new],
|
||||
isTextToken = NO,
|
||||
tokens = [CPArray array],
|
||||
dateComponents = [CPArray array],
|
||||
patternTokens = [CPArray array];
|
||||
isTextToken = NO,
|
||||
tokens = [CPArray array],
|
||||
dateComponents = [CPArray array],
|
||||
patternTokens = [CPArray array];
|
||||
|
||||
for (var i = 0; i < [aFormat length]; i++)
|
||||
{
|
||||
@@ -1431,19 +1432,19 @@ var _separatorsCharacterSet = nil;
|
||||
- (CPDate)_dateFromTokens:(CPArray)tokens dateComponents:(CPArray)dateComponents
|
||||
{
|
||||
var timeZoneseconds = [_timeZone secondsFromGMT],
|
||||
dateArray = [2000, 01, 01, 00, 00, 00, @"+0000"],
|
||||
isPM = NO,
|
||||
dayOfYear,
|
||||
dayIndexInWeek,
|
||||
weekOfYear,
|
||||
weekOfMonth;
|
||||
dateArray = [2000, 1, 1, 0, 0, 0],
|
||||
isPM = NO,
|
||||
dayOfYear,
|
||||
dayIndexInWeek,
|
||||
weekOfYear,
|
||||
weekOfMonth;
|
||||
|
||||
for (var i = 0; i < [tokens count]; i++)
|
||||
{
|
||||
var token = [tokens objectAtIndex:i],
|
||||
dateComponent = [dateComponents objectAtIndex:i],
|
||||
character = [token characterAtIndex:0],
|
||||
length = [token length];
|
||||
dateComponent = [dateComponents objectAtIndex:i],
|
||||
character = [token characterAtIndex:0],
|
||||
length = [token length];
|
||||
|
||||
switch (character)
|
||||
{
|
||||
@@ -1454,9 +1455,9 @@ var _separatorsCharacterSet = nil;
|
||||
|
||||
case @"y":
|
||||
var u = _twoDigitStartDate.getFullYear() % 10,
|
||||
d = parseInt(_twoDigitStartDate.getFullYear() / 10) % 10,
|
||||
c = parseInt(_twoDigitStartDate.getFullYear() / 100) % 10,
|
||||
m = parseInt(_twoDigitStartDate.getFullYear() / 1000) % 10;
|
||||
d = parseInt(_twoDigitStartDate.getFullYear() / 10) % 10,
|
||||
c = parseInt(_twoDigitStartDate.getFullYear() / 100) % 10,
|
||||
m = parseInt(_twoDigitStartDate.getFullYear() / 1000) % 10;
|
||||
|
||||
if (length == 2 && dateComponent.length == 2)
|
||||
{
|
||||
@@ -1474,9 +1475,9 @@ var _separatorsCharacterSet = nil;
|
||||
|
||||
case @"Y":
|
||||
var u = _twoDigitStartDate.getFullYear() % 10,
|
||||
d = parseInt(_twoDigitStartDate.getFullYear() / 10) % 10,
|
||||
c = parseInt(_twoDigitStartDate.getFullYear() / 100) % 10,
|
||||
m = parseInt(_twoDigitStartDate.getFullYear() / 1000) % 10;
|
||||
d = parseInt(_twoDigitStartDate.getFullYear() / 10) % 10,
|
||||
c = parseInt(_twoDigitStartDate.getFullYear() / 100) % 10,
|
||||
m = parseInt(_twoDigitStartDate.getFullYear() / 1000) % 10;
|
||||
|
||||
if (length == 2 && dateComponent.length == 2)
|
||||
{
|
||||
@@ -1790,7 +1791,7 @@ var _separatorsCharacterSet = nil;
|
||||
return nil;
|
||||
|
||||
var millisecondsInDay = parseInt(dateComponent),
|
||||
tmpDate = new Date();
|
||||
tmpDate = new Date();
|
||||
|
||||
tmpDate.setHours(0);
|
||||
tmpDate.setMinutes(0);
|
||||
@@ -1816,8 +1817,6 @@ var _separatorsCharacterSet = nil;
|
||||
if (!timeZoneseconds)
|
||||
return nil;
|
||||
|
||||
timeZoneseconds = timeZoneseconds + 60 * 60;
|
||||
|
||||
break;
|
||||
|
||||
case @"Z":
|
||||
@@ -1826,8 +1825,6 @@ var _separatorsCharacterSet = nil;
|
||||
if (!timeZoneseconds)
|
||||
return nil;
|
||||
|
||||
timeZoneseconds = timeZoneseconds + 60 * 60;
|
||||
|
||||
break;
|
||||
|
||||
case @"v":
|
||||
@@ -1842,8 +1839,6 @@ var _separatorsCharacterSet = nil;
|
||||
if (!timeZoneseconds)
|
||||
return nil;
|
||||
|
||||
timeZoneseconds = timeZoneseconds + 60 * 60;
|
||||
|
||||
break;
|
||||
|
||||
case @"V":
|
||||
@@ -1858,8 +1853,6 @@ var _separatorsCharacterSet = nil;
|
||||
if (!timeZoneseconds)
|
||||
return nil;
|
||||
|
||||
timeZoneseconds = timeZoneseconds + 60 * 60;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
@@ -1912,11 +1905,15 @@ var _separatorsCharacterSet = nil;
|
||||
if (isPM)
|
||||
dateArray[3] += 12;
|
||||
|
||||
if (isNaN(parseInt(dateArray[0])) || isNaN(parseInt(dateArray[1])) || isNaN(parseInt(dateArray[2])) || isNaN(parseInt(dateArray[3])) || isNaN(parseInt(dateArray[4])) || isNaN(parseInt(dateArray[5])) || isNaN(parseInt(dateArray[6])))
|
||||
if (isNaN(parseInt(dateArray[0])) || isNaN(parseInt(dateArray[1])) || isNaN(parseInt(dateArray[2])) || isNaN(parseInt(dateArray[3])) || isNaN(parseInt(dateArray[4])) || isNaN(parseInt(dateArray[5])))
|
||||
return nil;
|
||||
|
||||
var dateResult = [[CPDate alloc] initWithString:[CPString stringWithFormat:@"%04d-%02d-%02d %02d:%02d:%02d %s", dateArray[0], dateArray[1], dateArray[2], dateArray[3], dateArray[4], dateArray[5], dateArray[6]]];
|
||||
dateResult.setSeconds(dateResult.getSeconds() - timeZoneseconds + 60 * 60);
|
||||
var utcTimestamp = Date.UTC(dateArray[0], dateArray[1] - 1, dateArray[2], dateArray[3], dateArray[4], dateArray[5]),
|
||||
kCFAbsoluteTimeIntervalSince1970 = 978307200.0,
|
||||
interval = (utcTimestamp / 1000.0) - kCFAbsoluteTimeIntervalSince1970,
|
||||
dateResult = [CPDate dateWithTimeIntervalSinceReferenceDate:interval];
|
||||
|
||||
dateResult.setSeconds(dateResult.getSeconds() - timeZoneseconds);
|
||||
|
||||
return dateResult;
|
||||
}
|
||||
@@ -1942,29 +1939,29 @@ var _separatorsCharacterSet = nil;
|
||||
}
|
||||
|
||||
/*! Check if we are in the american format or not. Depending on the locale
|
||||
*/
|
||||
*/
|
||||
- (BOOL)_isAmericanFormat
|
||||
{
|
||||
return [[_locale objectForKey:CPLocaleCountryCode] isEqualToString:@"US"];
|
||||
}
|
||||
|
||||
/*! Check if we are in the english format or not. Depending on the locale
|
||||
*/
|
||||
*/
|
||||
- (BOOL)_isEnglishFormat
|
||||
{
|
||||
return [[_locale objectForKey:CPLocaleLanguageCode] isEqualToString:@"en"];
|
||||
}
|
||||
|
||||
/*! Returns the number of second from a time zone (-8000 or HGP-8:35 or GMT-08:00)
|
||||
*/
|
||||
*/
|
||||
- (int)_secondsFromTimeZoneDefaultFormatString:(CPString)aTimeZoneFormatString
|
||||
{
|
||||
var format = new RegExp("\\w*([HPG-GMT])?([+-])(\\d{1,2})([:])?(\\d{2})\\w*"),
|
||||
result = aTimeZoneFormatString.match(new RegExp(format)),
|
||||
seconds = 0;
|
||||
result = aTimeZoneFormatString.match(new RegExp(format)),
|
||||
seconds = 0;
|
||||
|
||||
if (!result)
|
||||
return nil;
|
||||
return 0;
|
||||
|
||||
seconds = result[3] * 60 * 60 + result[5] * 60;
|
||||
|
||||
@@ -1975,30 +1972,30 @@ var _separatorsCharacterSet = nil;
|
||||
}
|
||||
|
||||
/*! Return the number of seconds from a timeZoneString
|
||||
*/
|
||||
*/
|
||||
- (int)_secondsFromTimeZoneString:(CPString)aTimeZoneString style:(NSTimeZoneNameStyle)aStyle
|
||||
{
|
||||
var timeZone = [CPTimeZone _timeZoneFromString:aTimeZoneString style:aStyle locale:_locale];
|
||||
|
||||
if (!timeZone)
|
||||
return nil;
|
||||
return 0;
|
||||
|
||||
return [timeZone secondsFromGMT];
|
||||
}
|
||||
|
||||
/*! This method is used to know if the given string match with the token.
|
||||
@param aString
|
||||
@param aToken
|
||||
@param anIndex the current index in the string
|
||||
@return an index who describes the position of the end of the word for the token
|
||||
*/
|
||||
@param aString
|
||||
@param aToken
|
||||
@param anIndex the current index in the string
|
||||
@return an index who describes the position of the end of the word for the token
|
||||
*/
|
||||
- (int)_lastIndexMatchedString:(CPString)aString token:(CPString)aToken index:anIndex
|
||||
{
|
||||
var character = [aToken characterAtIndex:0],
|
||||
length = [aToken length],
|
||||
targetedArray,
|
||||
format = new RegExp("\\w*([HPG-GMT])?([+-])(\\d{1,2})([:])?(\\d{2})\\w*"),
|
||||
result = aString.match(new RegExp(format));
|
||||
length = [aToken length],
|
||||
targetedArray,
|
||||
format = new RegExp("\\w*([HPG-GMT])?([+-])(\\d{1,2})([:])?(\\d{2})\\w*"),
|
||||
result = aString.match(new RegExp(format));
|
||||
|
||||
switch (character)
|
||||
{
|
||||
@@ -2129,7 +2126,7 @@ var _separatorsCharacterSet = nil;
|
||||
for (var i = 0; i < [targetedArray count]; i++)
|
||||
{
|
||||
var currentObject = [targetedArray objectAtIndex:i],
|
||||
range = [aString rangeOfString:currentObject];
|
||||
range = [aString rangeOfString:currentObject];
|
||||
|
||||
if (range.length == 0)
|
||||
continue;
|
||||
@@ -2146,12 +2143,12 @@ var _separatorsCharacterSet = nil;
|
||||
@end
|
||||
|
||||
var CPDateFormatterDateStyleKey = @"CPDateFormatterDateStyle",
|
||||
CPDateFormatterTimeStyleKey = @"CPDateFormatterTimeStyleKey",
|
||||
CPDateFormatterFormatterBehaviorKey = @"CPDateFormatterFormatterBehaviorKey",
|
||||
CPDateFormatterDoseRelativeDateFormattingKey = @"CPDateFormatterDoseRelativeDateFormattingKey",
|
||||
CPDateFormatterDateFormatKey = @"CPDateFormatterDateFormatKey",
|
||||
CPDateFormatterAllowNaturalLanguageKey = @"CPDateFormatterAllowNaturalLanguageKey",
|
||||
CPDateFormatterLocaleKey = @"CPDateFormatterLocaleKey";
|
||||
CPDateFormatterTimeStyleKey = @"CPDateFormatterTimeStyleKey",
|
||||
CPDateFormatterFormatterBehaviorKey = @"CPDateFormatterFormatterBehaviorKey",
|
||||
CPDateFormatterDoseRelativeDateFormattingKey = @"CPDateFormatterDoseRelativeDateFormattingKey",
|
||||
CPDateFormatterDateFormatKey = @"CPDateFormatterDateFormatKey",
|
||||
CPDateFormatterAllowNaturalLanguageKey = @"CPDateFormatterAllowNaturalLanguageKey",
|
||||
CPDateFormatterLocaleKey = @"CPDateFormatterLocaleKey";
|
||||
|
||||
@implementation CPDateFormatter (CPCoding)
|
||||
|
||||
@@ -2194,14 +2191,17 @@ var CPDateFormatterDateStyleKey = @"CPDateFormatterDateStyle",
|
||||
@implementation CPDate (CPTimeZone)
|
||||
|
||||
/*! Convert a date from a timeZone
|
||||
*/
|
||||
*/
|
||||
- (void)_dateWithTimeZone:(CPTimeZone)aTimeZone
|
||||
{
|
||||
if (!aTimeZone)
|
||||
return;
|
||||
|
||||
self.setSeconds(self.getSeconds() - [aTimeZone secondsFromGMTForDate:self]);
|
||||
self.setSeconds(self.getSeconds() + [aTimeZone secondsFromGMT]);
|
||||
var targetOffset = [aTimeZone secondsFromGMTForDate:self],
|
||||
localOffset = - (self.getTimezoneOffset() * 60),
|
||||
offsetDifference = targetOffset - localOffset;
|
||||
|
||||
self.setSeconds(self.getSeconds() + offsetDifference);
|
||||
}
|
||||
|
||||
@end
|
||||
+539
-441
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -1,23 +1,23 @@
|
||||
/* CPTimeZoneTest.j
|
||||
* Foundation
|
||||
*
|
||||
* Created by Alexandre Wilhelm
|
||||
* Copyright 2012 <alexandre.wilhelmfr@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
* Foundation
|
||||
*
|
||||
* Created by Alexandre Wilhelm
|
||||
* Copyright 2012 <alexandre.wilhelmfr@gmail.com>
|
||||
*
|
||||
* This library is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU Lesser General Public
|
||||
* License as published by the Free Software Foundation; either
|
||||
* version 2.1 of the License, or (at your option) any later version.
|
||||
*
|
||||
* This library is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* Lesser General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public
|
||||
* License along with this library; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
*/
|
||||
|
||||
@import <Foundation/Foundation.j>
|
||||
@import <OJUnit/OJTestCase.j>
|
||||
@@ -66,7 +66,7 @@
|
||||
{
|
||||
var timeZone = [CPTimeZone timeZoneWithName:@"America/Los_Angeles"];
|
||||
|
||||
// The current implementation can return daylight saving time or standard time depending on the current implmentation on CPDictionary
|
||||
// The current implementation can return daylight saving time or standard time depending on the current date
|
||||
if ([timeZone abbreviation] === @"PDT") {
|
||||
[self assert:[timeZone name] equals:@"America/Los_Angeles"];
|
||||
[self assert:[timeZone abbreviation] equals:@"PDT"];
|
||||
@@ -96,8 +96,8 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
[CPTimeZone timeZoneWithName:nil];
|
||||
[self fail:"Invalid value provided for tzName"];
|
||||
[CPTimeZone timeZoneWithName:nil];
|
||||
[self fail:"Invalid value provided for tzName"];
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
@@ -109,7 +109,6 @@
|
||||
{
|
||||
var timeZone = [CPTimeZone timeZoneWithName:@"America/Los_Angeles" data:_data];
|
||||
|
||||
// The current implementation can return daylight saving time or standard time depending on the current implmentation on CPDictionary
|
||||
if ([timeZone abbreviation] === @"PDT") {
|
||||
[self assert:[timeZone name] equals:@"America/Los_Angeles"];
|
||||
[self assert:[timeZone abbreviation] equals:@"PDT"];
|
||||
@@ -140,8 +139,8 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
[CPTimeZone timeZoneWithName:nil data:_data];
|
||||
[self fail:"Invalid value provided for tzName"];
|
||||
[CPTimeZone timeZoneWithName:nil data:_data];
|
||||
[self fail:"Invalid value provided for tzName"];
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
@@ -151,30 +150,37 @@
|
||||
|
||||
- (void)testTimeZoneWithSecondsFromGMT
|
||||
{
|
||||
// timeZoneForSecondsFromGMT returns a fixed-offset zone. It does not
|
||||
// back-resolve to geographical regions (like Pacific/Honolulu).
|
||||
var timeZone = [CPTimeZone timeZoneForSecondsFromGMT:(-600 * 60)];
|
||||
[self assert:[timeZone name] equals:@"Pacific/Honolulu"];
|
||||
[self assert:[timeZone abbreviation] equals:@"HST"];
|
||||
[self assert:[timeZone name] equals:@"GMT-10:00"];
|
||||
[self assert:[timeZone abbreviation] equals:@"GMT-10:00"];
|
||||
[self assert:[timeZone secondsFromGMT] equals:(-600 * 60)];
|
||||
[self assert:[timeZone description] equals:@"Pacific/Honolulu (HST) offset -36000"];
|
||||
[self assert:[timeZone localizedName:CPTimeZoneNameStyleStandard locale:_locale] equals:@"Hawaii-Aleutian Standard Time"];
|
||||
[self assert:[timeZone localizedName:CPTimeZoneNameStyleShortStandard locale:_locale] equals:@"HST"];
|
||||
[self assert:[timeZone localizedName:CPTimeZoneNameStyleDaylightSaving locale:_locale] equals:@"Hawaii-Aleutian Daylight Time"];
|
||||
[self assert:[timeZone localizedName:CPTimeZoneNameStyleShortDaylightSaving locale:_locale] equals:@"HDT"];
|
||||
[self assert:[timeZone localizedName:CPTimeZoneNameStyleGeneric locale:_locale] equals:@"Hawaii-Aleutian Standard Time"];
|
||||
[self assert:[timeZone localizedName:CPTimeZoneNameStyleShortGeneric locale:_locale] equals:@"HST"];
|
||||
[self assert:[timeZone description] equals:@"GMT-10:00 (GMT-10:00) offset -36000"];
|
||||
[self assert:[timeZone localizedName:CPTimeZoneNameStyleStandard locale:_locale] equals:@"GMT-10:00"];
|
||||
[self assert:[timeZone localizedName:CPTimeZoneNameStyleShortStandard locale:_locale] equals:@"GMT-10:00"];
|
||||
[self assert:[timeZone localizedName:CPTimeZoneNameStyleDaylightSaving locale:_locale] equals:@"GMT-10:00"];
|
||||
[self assert:[timeZone localizedName:CPTimeZoneNameStyleShortDaylightSaving locale:_locale] equals:@"GMT-10:00"];
|
||||
[self assert:[timeZone localizedName:CPTimeZoneNameStyleGeneric locale:_locale] equals:@"GMT-10:00"];
|
||||
[self assert:[timeZone localizedName:CPTimeZoneNameStyleShortGeneric locale:_locale] equals:@"GMT-10:00"];
|
||||
}
|
||||
|
||||
- (void)testTimeZoneWithWrongSecondsFromGMT
|
||||
{
|
||||
// +/- 18 hours is the limit. -421 * 60 is valid and creates a fixed zone.
|
||||
var timeZone = [CPTimeZone timeZoneForSecondsFromGMT:(-421 * 60)];
|
||||
[self assert:timeZone equals:nil];
|
||||
[self assert:[timeZone name] equals:@"GMT-07:01"];
|
||||
[self assert:[timeZone secondsFromGMT] equals:(-421 * 60)];
|
||||
|
||||
// An offset strictly outside the +/- 18 hour range should return nil.
|
||||
var invalidTimeZone = [CPTimeZone timeZoneForSecondsFromGMT:(19 * 3600)];
|
||||
[self assert:invalidTimeZone equals:nil];
|
||||
}
|
||||
|
||||
- (void)testInitTimeZoneWithName
|
||||
{
|
||||
var timeZone = [[CPTimeZone alloc] initWithName:@"America/Los_Angeles"];
|
||||
|
||||
// The current implementation can return daylight saving time or standard time depending on the current implmentation on CPDictionary
|
||||
if ([timeZone abbreviation] === @"PDT") {
|
||||
[self assert:[timeZone name] equals:@"America/Los_Angeles"];
|
||||
[self assert:[timeZone abbreviation] equals:@"PDT"];
|
||||
@@ -204,8 +210,8 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
[[CPTimeZone alloc] initWithName:nil];
|
||||
[self fail:"Invalid value provided for tzName"];
|
||||
[[CPTimeZone alloc] initWithName:nil];
|
||||
[self fail:"Invalid value provided for tzName"];
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
@@ -217,7 +223,6 @@
|
||||
{
|
||||
var timeZone = [[CPTimeZone alloc] initWithName:@"America/Los_Angeles" data:_data];
|
||||
|
||||
// The current implementation can return daylight saving time or standard time depending on the current implmentation on CPDictionary
|
||||
if ([timeZone abbreviation] === @"PDT") {
|
||||
[self assert:[timeZone name] equals:@"America/Los_Angeles"];
|
||||
[self assert:[timeZone abbreviation] equals:@"PDT"];
|
||||
@@ -248,8 +253,8 @@
|
||||
{
|
||||
try
|
||||
{
|
||||
[[CPTimeZone alloc] initWithName:nil data:_data];
|
||||
[self fail:"Invalid value provided for tzName"];
|
||||
[[CPTimeZone alloc] initWithName:nil data:_data];
|
||||
[self fail:"Invalid value provided for tzName"];
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
@@ -260,12 +265,8 @@
|
||||
- (void)testAbbreviationWithDate
|
||||
{
|
||||
var timeZone = [CPTimeZone localTimeZone],
|
||||
abbreviation = [timeZone abbreviationForDate:_date];
|
||||
abbreviation = [timeZone abbreviationForDate:_date];
|
||||
|
||||
// With the new robust implementation, we can't easily predict the exact
|
||||
// abbreviation string without re-implementing the parsing logic.
|
||||
// Instead, we verify that the returned abbreviation is valid and exists
|
||||
// in the known dictionary, which is sufficient.
|
||||
[self assert:(abbreviation !== nil) equals:YES];
|
||||
var knownAbbreviations = [CPTimeZone abbreviationDictionary];
|
||||
[self assert:[knownAbbreviations containsKey:abbreviation] equals:YES];
|
||||
@@ -274,7 +275,7 @@
|
||||
- (void)testAbbreviationWithNilDate
|
||||
{
|
||||
var timeZone = [CPTimeZone localTimeZone],
|
||||
abbreviation = [timeZone abbreviationForDate:nil];
|
||||
abbreviation = [timeZone abbreviationForDate:nil];
|
||||
|
||||
[self assert:abbreviation equals:nil];
|
||||
}
|
||||
@@ -283,7 +284,7 @@
|
||||
- (void)testSecondsFromGMTForDate
|
||||
{
|
||||
var timeZone = [CPTimeZone localTimeZone],
|
||||
seconds = [timeZone secondsFromGMTForDate:_date];
|
||||
seconds = [timeZone secondsFromGMTForDate:_date];
|
||||
|
||||
[self assert:seconds equals:(_date.getTimezoneOffset() * -60)];
|
||||
}
|
||||
@@ -291,7 +292,7 @@
|
||||
- (void)testSecondsFromGMTForDateWithNilDate
|
||||
{
|
||||
var timeZone = [CPTimeZone localTimeZone],
|
||||
seconds = [timeZone secondsFromGMTForDate:nil];
|
||||
seconds = [timeZone secondsFromGMTForDate:nil];
|
||||
|
||||
[self assert:seconds equals:nil];
|
||||
}
|
||||
@@ -300,7 +301,6 @@
|
||||
{
|
||||
var timeZone = [[CPTimeZone alloc] initWithName:@"America/Los_Angeles"];
|
||||
|
||||
// The current implementation can return daylight saving time or standard time depending on the current implmentation on CPDictionary
|
||||
if ([timeZone abbreviation] === @"PDT") {
|
||||
[self assert:[timeZone secondsFromGMT] equals:(-420 * 60)];
|
||||
} else {
|
||||
@@ -312,7 +312,6 @@
|
||||
{
|
||||
var timeZone = [[CPTimeZone alloc] initWithName:@"America/Los_Angeles"];
|
||||
|
||||
// The current implementation can return daylight saving time or standard time depending on the current implmentation on CPDictionary
|
||||
if ([timeZone abbreviation] === @"PDT") {
|
||||
[self assert:[timeZone description] equals:@"America/Los_Angeles (PDT) offset -25200"];
|
||||
} else {
|
||||
@@ -334,7 +333,7 @@
|
||||
- (void)testEqualTrueToTimeZone
|
||||
{
|
||||
var timeZone1 = [[CPTimeZone alloc] initWithName:@"America/Los_Angeles"],
|
||||
timeZone2 = [[CPTimeZone alloc] initWithName:@"America/Los_Angeles"];
|
||||
timeZone2 = [[CPTimeZone alloc] initWithName:@"America/Los_Angeles"];
|
||||
|
||||
[self assert:[timeZone1 isEqualToTimeZone:timeZone2] equals:YES];
|
||||
}
|
||||
@@ -342,25 +341,17 @@
|
||||
- (void)testEqualFalseToTimeZone
|
||||
{
|
||||
var timeZone1 = [[CPTimeZone alloc] initWithName:@"America/Los_Angeles"],
|
||||
timeZone2 = [[CPTimeZone alloc] initWithName:@"Pacific/Honolulu"];
|
||||
timeZone2 = [[CPTimeZone alloc] initWithName:@"Pacific/Honolulu"];
|
||||
|
||||
[self assert:[timeZone1 isEqualToTimeZone:timeZone2] equals:NO];
|
||||
}
|
||||
|
||||
- (void)testInitWithNameRespectsDaylightSaving
|
||||
{
|
||||
// This test verifies that initWithName: correctly selects the abbreviation
|
||||
// (e.g., PST vs. PDT) based on the current date's daylight saving status.
|
||||
|
||||
// 1. Test a time zone that observes DST, like America/Los_Angeles.
|
||||
var laTimeZoneName = @"America/Los_Angeles";
|
||||
var expectedAbbreviationLA;
|
||||
|
||||
try {
|
||||
// This logic mirrors the _abbreviationForNameAndDate helper in
|
||||
// CPTimeZone.j: read the short time zone name directly from Intl,
|
||||
// as an independent check that CPTimeZone's own use of the same
|
||||
// API returns the same thing, not a duplicate of an algorithm.
|
||||
var options = { timeZone: laTimeZoneName, timeZoneName: 'short' };
|
||||
var parts = new Intl.DateTimeFormat('en-US', options).formatToParts(new Date());
|
||||
var tzPart = parts.filter(function (p) { return p.type === 'timeZoneName'; })[0];
|
||||
@@ -377,44 +368,46 @@
|
||||
|
||||
[self assert:[timeZoneLA abbreviation] equals:expectedAbbreviationLA];
|
||||
|
||||
// 2. Test a time zone that does not observe DST, like Pacific/Honolulu.
|
||||
var hnlTimeZoneName = @"Pacific/Honolulu";
|
||||
var timeZoneHNL = [[CPTimeZone alloc] initWithName:hnlTimeZoneName];
|
||||
|
||||
if (timeZoneHNL == nil)
|
||||
[self fail:"Time zone for Pacific/Honolulu should be created successfully."];
|
||||
|
||||
// For a non-DST zone, the abbreviation is constant.
|
||||
[self assert:[timeZoneHNL abbreviation] equals:@"HST"];
|
||||
}
|
||||
|
||||
// Pins the six timeDifferenceFromUTC entries corrected on CPTimeZoneTest-fix
|
||||
// (MDT, MSK, NZDT, NZST, WAT, WIT) through the public API, so a regression
|
||||
// back to any of the old wrong values is caught directly.
|
||||
- (void)testCorrectedOffsets
|
||||
{
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"MDT"] secondsFromGMT] equals:(-360 * 60)];
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"MSK"] secondsFromGMT] equals:(180 * 60)];
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"NZDT"] secondsFromGMT] equals:(780 * 60)];
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"NZST"] secondsFromGMT] equals:(720 * 60)];
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"WAT"] secondsFromGMT] equals:(60 * 60)];
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"WIT"] secondsFromGMT] equals:(420 * 60)];
|
||||
// Validate IANA name resolution for legacy abbreviations.
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"MDT"] name] equals:@"America/Denver"];
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"MSK"] name] equals:@"Europe/Moscow"];
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"NZDT"] name] equals:@"Pacific/Auckland"];
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"NZST"] name] equals:@"Pacific/Auckland"];
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"WAT"] name] equals:@"Africa/Lagos"];
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"WIT"] name] equals:@"Asia/Jakarta"];
|
||||
|
||||
// Evaluate against fixed dates to prevent seasonal failures during CI runs.
|
||||
var janDate = [[CPDate alloc] initWithString:@"2026-01-15 12:00:00 +0000"];
|
||||
var julDate = [[CPDate alloc] initWithString:@"2026-07-15 12:00:00 +0000"];
|
||||
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"MDT"] secondsFromGMTForDate:julDate] equals:(-360 * 60)];
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"MSK"] secondsFromGMTForDate:janDate] equals:(180 * 60)];
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"NZDT"] secondsFromGMTForDate:janDate] equals:(780 * 60)];
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"NZST"] secondsFromGMTForDate:julDate] equals:(720 * 60)];
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"WAT"] secondsFromGMTForDate:janDate] equals:(60 * 60)];
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"WIT"] secondsFromGMTForDate:janDate] equals:(420 * 60)];
|
||||
}
|
||||
|
||||
// MSD ("Moscow Summer Time") has no correct current value: Russia abolished
|
||||
// DST in 2014, so there is no live distinct summer offset for Moscow to
|
||||
// assign. This pins the current, intentionally-unfixed value, so any future
|
||||
// edit to it happens deliberately alongside CPTimeZone.j's comment and the
|
||||
// tracked Intl redesign, not as a silent, unrelated drift.
|
||||
- (void)testMSDKnownStaleValue
|
||||
- (void)testMSKCorrectCurrentValue
|
||||
{
|
||||
[self assert:[[CPTimeZone timeZoneWithAbbreviation:@"MSD"] secondsFromGMT] equals:(240 * 60)];
|
||||
// MSD/MSK resolve to Europe/Moscow.
|
||||
// Russia abolished DST in 2014, so there is no distinct summer offset.
|
||||
// The current permanent offset is +03:00 (10800 seconds).
|
||||
var timeZone = [CPTimeZone timeZoneWithAbbreviation:@"MSD"];
|
||||
[self assert:[timeZone secondsFromGMT] equals:(180 * 60)];
|
||||
}
|
||||
|
||||
// knownTimeZoneNames should prefer the runtime's own IANA database over the
|
||||
// old 48-city hardcoded list, on any engine that exposes
|
||||
// Intl.supportedValuesOf. Skips itself where that API is unavailable, rather
|
||||
// than asserting a specific engine capability.
|
||||
- (void)testKnownTimeZoneNamesUsesIntlWhenAvailable
|
||||
{
|
||||
if (typeof Intl === "undefined" || typeof Intl.supportedValuesOf !== "function")
|
||||
@@ -423,38 +416,22 @@
|
||||
var names = [CPTimeZone knownTimeZoneNames];
|
||||
|
||||
[self assertTrue:([names count] > 48)
|
||||
message:"knownTimeZoneNames should use Intl.supportedValuesOf when available, not the small hardcoded fallback list"];
|
||||
message:"knownTimeZoneNames should use Intl.supportedValuesOf when available, not the small hardcoded fallback list"];
|
||||
[self assertTrue:[names containsObject:@"Europe/Berlin"]
|
||||
message:"a zone absent from the old hardcoded list should be present via Intl"];
|
||||
message:"a zone absent from the old hardcoded list should be present via Intl"];
|
||||
}
|
||||
|
||||
// Disabled: the "fr" entry in localizedName is an empty dictionary, so any
|
||||
// lookup for a French locale currently returns nil regardless of style. This
|
||||
// is the same static, English-only table design as before the Intl
|
||||
// migration; folding it in was deferred because CPTimeZoneNameStyleStandard/
|
||||
// DaylightSaving need to force a specific state independent of the current
|
||||
// date, which Intl.formatToParts(date) alone can't do for an arbitrary date.
|
||||
// Tracked for the larger IANA-identity redesign, not fixed here.
|
||||
- (void)disabled_testLocalizedNameFrenchLocale
|
||||
{
|
||||
var frenchLocale = [[CPLocale alloc] initWithLocaleIdentifier:@"fr_FR"],
|
||||
timeZone = [CPTimeZone timeZoneWithAbbreviation:@"PST"];
|
||||
timeZone = [CPTimeZone timeZoneWithAbbreviation:@"PST"];
|
||||
|
||||
[self assert:[timeZone localizedName:CPTimeZoneNameStyleStandard locale:frenchLocale] equals:@"Heure normale du Pacifique"];
|
||||
}
|
||||
|
||||
// Disabled: timeZoneForSecondsFromGMT: does a linear scan of
|
||||
// timeDifferenceFromUTC and returns the first matching key, with no defined
|
||||
// tie-break when more than one abbreviation shares an offset. MDT and CST
|
||||
// both now correctly resolve to -360; asking for that offset silently
|
||||
// returns whichever CPDictionary happens to enumerate first, not a
|
||||
// documented choice. The idealized contract is that an inherently ambiguous
|
||||
// query should not silently guess one answer. No fix exists for this within
|
||||
// the current flat abbreviation-to-offset table design.
|
||||
- (void)disabled_testTimeZoneForSecondsFromGMTOffsetCollisionIsAmbiguous
|
||||
{
|
||||
var timeZone = [CPTimeZone timeZoneForSecondsFromGMT:(-360 * 60)];
|
||||
|
||||
[self assert:timeZone equals:nil];
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user