/*
 * Copyright (c) 2008-2009 Brent Fulgham <bfulgham@gmail.org>.  All rights reserved.
 *
 * This source code is a modified version of the CoreFoundation sources released by Apple Inc. under
 * the terms of the APSL version 2.0 (see below).
 *
 * For information about changes from the original Apple source release can be found by reviewing the
 * source control system for the project at https://sourceforge.net/svn/?group_id=246198.
 *
 * The original license information is as follows:
 * 
 * Copyright (c) 2008 Apple Inc. All rights reserved.
 *
 * @APPLE_LICENSE_HEADER_START@
 * 
 * This file contains Original Code and/or Modifications of Original Code
 * as defined in and that are subject to the Apple Public Source License
 * Version 2.0 (the 'License'). You may not use this file except in
 * compliance with the License. Please obtain a copy of the License at
 * http://www.opensource.apple.com/apsl/ and read it before using this
 * file.
 * 
 * The Original Code and all software distributed under the License are
 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 * Please see the License for the specific language governing rights and
 * limitations under the License.
 * 
 * @APPLE_LICENSE_HEADER_END@
 */
/*	CFDateFormatter.c
	Copyright 2002-2003, Apple, Inc. All rights reserved.
	Responsibility: Christopher Kane
*/

#include <CoreFoundation/CFDateFormatter.h>
#include <CoreFoundation/CFDate.h>
#include <CoreFoundation/CFTimeZone.h>
#include <CoreFoundation/CFCalendar.h>
#include <CoreFoundation/CFNumber.h>
#include "CFInternal.h"
#include <unicode/udat.h>
#include <math.h>
#include <float.h>

extern UCalendar *__CFCalendarCreateUCalendar(CFStringRef calendarID, CFStringRef localeID, CFTimeZoneRef tz);
#ifdef DEPLOYMENT_TARGET_WINDOWS
extern CFAbsoluteTime __CFDateWindowsSystemTimeToAbsoluteTime(SYSTEMTIME *time);
#endif
static void __CFDateFormatterCustomize(CFDateFormatterRef formatter);

CF_EXPORT const CFStringRef kCFDateFormatterCalendarIdentifier;

#define BUFFER_SIZE 768

struct __CFDateFormatter {
    CFRuntimeBase _base;
    UDateFormat *_df;
    CFLocaleRef _locale;
    CFDateFormatterStyle _timeStyle;
    CFDateFormatterStyle _dateStyle;
    CFStringRef _format;
    CFStringRef _defformat;
    CFStringRef _calendarName;
    CFTimeZoneRef _tz;
    CFDateRef _defaultDate;
};

static CFStringRef __CFDateFormatterCopyDescription(CFTypeRef cf) {
    CFDateFormatterRef formatter = (CFDateFormatterRef)cf;
    return CFStringCreateWithFormat(CFGetAllocator(formatter), NULL, CFSTR("<CFDateFormatter %p [%p]>"), cf, CFGetAllocator(formatter));
}

static void __CFDateFormatterDeallocate(CFTypeRef cf) {
    CFDateFormatterRef formatter = (CFDateFormatterRef)cf;
    if (formatter->_df) udat_close(formatter->_df);
    if (formatter->_locale) CFRelease(formatter->_locale);
    if (formatter->_format) CFRelease(formatter->_format);
    if (formatter->_defformat) CFRelease(formatter->_defformat);
    if (formatter->_calendarName) CFRelease(formatter->_calendarName);
    if (formatter->_tz) CFRelease(formatter->_tz);
    if (formatter->_defaultDate) CFRelease(formatter->_defaultDate);
}

static CFTypeID __kCFDateFormatterTypeID = _kCFRuntimeNotATypeID;

static const CFRuntimeClass __CFDateFormatterClass = {
    0,
    "CFDateFormatter",
    NULL,	// init
    NULL,	// copy
    __CFDateFormatterDeallocate,
    NULL,
    NULL,
    NULL,	// 
    __CFDateFormatterCopyDescription
};

static void __CFDateFormatterInitialize(void) {
    __kCFDateFormatterTypeID = _CFRuntimeRegisterClass(&__CFDateFormatterClass);
}

CFTypeID CFDateFormatterGetTypeID(void) {
    if (_kCFRuntimeNotATypeID == __kCFDateFormatterTypeID) __CFDateFormatterInitialize();
    return __kCFDateFormatterTypeID;
}

CFDateFormatterRef CFDateFormatterCreate(CFAllocatorRef allocator, CFLocaleRef locale, CFDateFormatterStyle dateStyle, CFDateFormatterStyle timeStyle) {
    struct __CFDateFormatter *memory;
    uint32_t size = sizeof(struct __CFDateFormatter) - sizeof(CFRuntimeBase);
    if (allocator == NULL) allocator = __CFGetDefaultAllocator();
    __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
    if (locale) __CFGenericValidateType(locale, CFLocaleGetTypeID());
    memory = (struct __CFDateFormatter *)_CFRuntimeCreateInstance(allocator, CFDateFormatterGetTypeID(), size, NULL);
    if (NULL == memory) {
	return NULL;
    }
    memory->_df = NULL;
    memory->_locale = NULL;
    memory->_format = NULL;
    memory->_defformat = NULL;
    memory->_calendarName = NULL;
    memory->_tz = NULL;
    memory->_defaultDate = NULL;
    if (NULL == locale) locale = CFLocaleGetSystem();
    memory->_dateStyle = dateStyle;
    memory->_timeStyle = timeStyle;
    int32_t udstyle, utstyle;
    switch (dateStyle) {
    case kCFDateFormatterNoStyle: udstyle = UDAT_NONE; break;
    case kCFDateFormatterShortStyle: udstyle = UDAT_SHORT; break;
    case kCFDateFormatterMediumStyle: udstyle = UDAT_MEDIUM; break;
    case kCFDateFormatterLongStyle: udstyle = UDAT_LONG; break;
    case kCFDateFormatterFullStyle: udstyle = UDAT_FULL; break;
    default:
	CFAssert2(0, __kCFLogAssertion, "%s(): unknown date style %d", __PRETTY_FUNCTION__, dateStyle);
	udstyle = UDAT_MEDIUM;
	memory->_dateStyle = kCFDateFormatterMediumStyle;
	break;
    }
    switch (timeStyle) {
    case kCFDateFormatterNoStyle: utstyle = UDAT_NONE; break;
    case kCFDateFormatterShortStyle: utstyle = UDAT_SHORT; break;
    case kCFDateFormatterMediumStyle: utstyle = UDAT_MEDIUM; break;
    case kCFDateFormatterLongStyle: utstyle = UDAT_LONG; break;
    case kCFDateFormatterFullStyle: utstyle = UDAT_FULL; break;
    default:
	CFAssert2(0, __kCFLogAssertion, "%s(): unknown time style %d", __PRETTY_FUNCTION__, timeStyle);
	utstyle = UDAT_MEDIUM;
	memory->_timeStyle = kCFDateFormatterMediumStyle;
	break;
    }
    CFStringRef localeName = locale ? CFLocaleGetIdentifier(locale) : CFSTR("");
    char buffer[BUFFER_SIZE];
    const char *cstr = CFStringGetCStringPtr(localeName, kCFStringEncodingASCII);
    if (NULL == cstr) {
        if (CFStringGetCString(localeName, buffer, BUFFER_SIZE, kCFStringEncodingASCII)) cstr = buffer;
    }
    if (NULL == cstr) {
        CFRelease(memory);
        return NULL;
    }
    UChar ubuffer[BUFFER_SIZE];
    memset(ubuffer, 0x00, sizeof(UChar) * BUFFER_SIZE);
    memory->_tz = CFTimeZoneCopyDefault();
#ifdef DEPLOYMENT_TARGET_WINDOWS
    // ICU doesn't know about Windows Time Zone names.  It'll understand the abbreviation for the non-daylight saving time, though
    TIME_ZONE_INFORMATION *tzi = (TIME_ZONE_INFORMATION *)CFDataGetBytePtr(CFTimeZoneGetData(memory->_tz));
    CFAbsoluteTime at = __CFDateWindowsSystemTimeToAbsoluteTime(&tzi->DaylightDate);
    // subtract a day to get us off the time change boundary
    at -= (60 * 60 * 24);
    CFStringRef tznam = CFTimeZoneCopyAbbreviation(memory->_tz, at);
#else
    CFStringRef tznam = CFTimeZoneGetName(memory->_tz);
#endif
    CFIndex cnt = CFStringGetLength(tznam);
    if (BUFFER_SIZE < cnt) cnt = BUFFER_SIZE;
    CFStringGetCharacters(tznam, CFRangeMake(0, cnt), (UniChar *)ubuffer);
    UErrorCode status = U_ZERO_ERROR;
    memory->_df = udat_open((UDateFormatStyle)utstyle, (UDateFormatStyle)udstyle, cstr, ubuffer, cnt, NULL, 0, &status);
    CFAssert2(memory->_df, __kCFLogAssertion, "%s(): error (%d) creating date formatter", __PRETTY_FUNCTION__, status);
    if (NULL == memory->_df) {
	CFRelease(memory->_tz);
	CFRelease(memory);
	return NULL;
    }
    udat_setLenient(memory->_df, 0);
    if (kCFDateFormatterNoStyle == dateStyle && kCFDateFormatterNoStyle == timeStyle) {
	udat_applyPattern(memory->_df, false, NULL, 0);
    }
    CFTypeRef calident = CFLocaleGetValue(locale, kCFLocaleCalendarIdentifier);
    if (calident && CFEqual(calident, kCFGregorianCalendar)) {
	status = U_ZERO_ERROR;
	udat_set2DigitYearStart(memory->_df, -631152000000.0, &status); // 1950-01-01 00:00:00 GMT
    }
    memory->_locale = locale ? CFLocaleCreateCopy(allocator, locale) : CFLocaleGetSystem();
    __CFDateFormatterCustomize(memory);
    status = U_ZERO_ERROR;
    int32_t ret = udat_toPattern(memory->_df, false, ubuffer, BUFFER_SIZE, &status);
    if (U_SUCCESS(status) && ret <= BUFFER_SIZE) {
	memory->_format = CFStringCreateWithCharacters(allocator, (const UniChar *)ubuffer, ret);
    }
    memory->_defformat = memory->_format ? (CFStringRef)CFRetain(memory->_format) : NULL;
    return (CFDateFormatterRef)memory;
}

extern CFDictionaryRef __CFLocaleGetPrefs(CFLocaleRef locale);

static void __substituteFormatStringFromPrefsDF(CFDateFormatterRef formatter, bool doTime) {
    CFIndex formatStyle = doTime ? formatter->_timeStyle : formatter->_dateStyle;
    CFStringRef prefName = doTime ? CFSTR("AppleICUTimeFormatStrings") : CFSTR("AppleICUDateFormatStrings");
    if (kCFDateFormatterNoStyle != formatStyle) {
        CFStringRef pref = NULL;
        CFDictionaryRef prefs = __CFLocaleGetPrefs(formatter->_locale);
        CFPropertyListRef metapref = prefs ? CFDictionaryGetValue(prefs, prefName) : NULL;
        if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) {
            CFStringRef key;
            switch (formatStyle) {
                case kCFDateFormatterShortStyle: key = CFSTR("1"); break;
                case kCFDateFormatterMediumStyle: key = CFSTR("2"); break;
                case kCFDateFormatterLongStyle: key = CFSTR("3"); break;
                case kCFDateFormatterFullStyle: key = CFSTR("4"); break;
                default: key = CFSTR("0"); break;
            }
            pref = (CFStringRef)CFDictionaryGetValue((CFDictionaryRef)metapref, key);
        }
        if (NULL != pref && CFGetTypeID(pref) == CFStringGetTypeID()) {
            int32_t icustyle = UDAT_NONE;
            switch (formatStyle) {
                case kCFDateFormatterShortStyle: icustyle = UDAT_SHORT; break;
                case kCFDateFormatterMediumStyle: icustyle = UDAT_MEDIUM; break;
                case kCFDateFormatterLongStyle: icustyle = UDAT_LONG; break;
                case kCFDateFormatterFullStyle: icustyle = UDAT_FULL; break;
            }
            CFStringRef localeName = CFLocaleGetIdentifier(formatter->_locale);
            char buffer[BUFFER_SIZE];
            const char *cstr = CFStringGetCStringPtr(localeName, kCFStringEncodingASCII);
            if (NULL == cstr) {
                if (CFStringGetCString(localeName, buffer, BUFFER_SIZE, kCFStringEncodingASCII)) cstr = buffer;
            }
            UErrorCode status = U_ZERO_ERROR;
            UDateFormat *df = udat_open((UDateFormatStyle)(doTime ? icustyle : UDAT_NONE), (UDateFormatStyle)(doTime ? UDAT_NONE : icustyle), cstr, NULL, 0, NULL, 0, &status);
            if (NULL != df) {
                UChar ubuffer[BUFFER_SIZE];
                status = U_ZERO_ERROR;
                int32_t date_len = udat_toPattern(df, false, ubuffer, BUFFER_SIZE, &status);
                if (U_SUCCESS(status) && date_len <= BUFFER_SIZE) {
                    CFStringRef dateString = CFStringCreateWithCharacters(kCFAllocatorSystemDefault, (UniChar *)ubuffer, date_len);
                    status = U_ZERO_ERROR;
                    int32_t formatter_len = udat_toPattern(formatter->_df, false, ubuffer, BUFFER_SIZE, &status);
                    if (U_SUCCESS(status) && formatter_len <= BUFFER_SIZE) {
                        CFMutableStringRef formatString = CFStringCreateMutable(kCFAllocatorSystemDefault, 0);
                        CFStringAppendCharacters(formatString, (UniChar *)ubuffer, formatter_len);
                        // find dateString inside formatString, substitute the pref in that range
                        CFRange result;
                        if (CFStringFindWithOptions(formatString, dateString, CFRangeMake(0, formatter_len), 0, &result)) {
                            CFStringReplace(formatString, result, pref);
                            int32_t new_len = CFStringGetLength(formatString);
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
                            STACK_BUFFER_DECL(UChar, new_buffer, new_len);
#else
                            UChar new_buffer[BUFFER_SIZE]; // Dynamic stack allocation is GNU specific
#endif
                            const UChar *new_ustr = (UChar *)CFStringGetCharactersPtr(formatString);
                            if (NULL == new_ustr) {
                                CFStringGetCharacters(formatString, CFRangeMake(0, new_len), (UniChar *)new_buffer);
                                new_ustr = new_buffer;
                            }
                            status = U_ZERO_ERROR;
//	                         udat_applyPattern(formatter->_df, false, new_ustr, new_len, &status);
                            udat_applyPattern(formatter->_df, false, new_ustr, new_len);
                        }
                        CFRelease(formatString);
                    }
                    CFRelease(dateString);
                }
                udat_close(df);
            }
        }
    }
}

static void __CFDateFormatterApplySymbolPrefs(const void *key, const void *value, void *context) {
    if (CFGetTypeID(key) == CFStringGetTypeID() && CFGetTypeID(value) == CFArrayGetTypeID()) {
        CFDateFormatterRef formatter = (CFDateFormatterRef)context;
        UDateFormatSymbolType sym = (UDateFormatSymbolType)CFStringGetIntValue((CFStringRef)key);
        CFArrayRef array = (CFArrayRef)value;
        CFIndex idx, cnt = CFArrayGetCount(array);
        for (idx = 0; idx < cnt; idx++) {
            CFStringRef item = (CFStringRef)CFArrayGetValueAtIndex(array, idx);
            if (CFGetTypeID(item) != CFStringGetTypeID()) continue;
            CFIndex item_cnt = CFStringGetLength(item);
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
	         STACK_BUFFER_DECL(UChar, item_buffer, __CFMin(BUFFER_SIZE, item_cnt));
#else
            UChar item_buffer[BUFFER_SIZE]; // Dynamic stack allocation is GNU specific
#endif
            UChar *item_ustr = (UChar *)CFStringGetCharactersPtr(item);
            if (NULL == item_ustr) {
                item_cnt = __CFMin(BUFFER_SIZE, item_cnt);
                CFStringGetCharacters(item, CFRangeMake(0, item_cnt), (UniChar *)item_buffer);
                item_ustr = item_buffer;
            }
            UErrorCode status = U_ZERO_ERROR;
            udat_setSymbols(formatter->_df, sym, idx, item_ustr, item_cnt, &status);
        }
    }
}

static void __CFDateFormatterCustomize(CFDateFormatterRef formatter) {
    __substituteFormatStringFromPrefsDF(formatter, false);
    __substituteFormatStringFromPrefsDF(formatter, true);
    CFDictionaryRef prefs = __CFLocaleGetPrefs(formatter->_locale);
    CFPropertyListRef metapref = prefs ? CFDictionaryGetValue(prefs, CFSTR("AppleICUDateTimeSymbols")) : NULL;
    if (NULL != metapref && CFGetTypeID(metapref) == CFDictionaryGetTypeID()) {
	CFDictionaryApplyFunction((CFDictionaryRef)metapref, __CFDateFormatterApplySymbolPrefs, formatter);
    }
}

CFLocaleRef CFDateFormatterGetLocale(CFDateFormatterRef formatter) {
    __CFGenericValidateType(formatter, CFDateFormatterGetTypeID());
    return formatter->_locale;
}

CFDateFormatterStyle CFDateFormatterGetDateStyle(CFDateFormatterRef formatter) {
    __CFGenericValidateType(formatter, CFDateFormatterGetTypeID());
    return formatter->_dateStyle;
}

CFDateFormatterStyle CFDateFormatterGetTimeStyle(CFDateFormatterRef formatter) {
    __CFGenericValidateType(formatter, CFDateFormatterGetTypeID());
    return formatter->_timeStyle;
}

CFStringRef CFDateFormatterGetFormat(CFDateFormatterRef formatter) {
    __CFGenericValidateType(formatter, CFDateFormatterGetTypeID());
    return formatter->_format;
}

void CFDateFormatterSetFormat(CFDateFormatterRef formatter, CFStringRef formatString) {
    __CFGenericValidateType(formatter, CFDateFormatterGetTypeID());
    __CFGenericValidateType(formatString, CFStringGetTypeID());
    CFIndex cnt = CFStringGetLength(formatString);
    CFAssert1(cnt <= 1024, __kCFLogAssertion, "%s(): format string too long", __PRETTY_FUNCTION__);
    if (formatter->_format != formatString && cnt <= 1024) {
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
        STACK_BUFFER_DECL(UChar, ubuffer, cnt);
#else
        UChar ubuffer[BUFFER_SIZE]; // Dynamic stack allocation is GNU specific
#endif
        const UChar *ustr = (UChar *)CFStringGetCharactersPtr((CFStringRef)formatString);
        if (NULL == ustr) {
            CFStringGetCharacters(formatString, CFRangeMake(0, cnt), (UniChar *)ubuffer);
            ustr = ubuffer;
        }
        UErrorCode status = U_ZERO_ERROR;
//	     udat_applyPattern(formatter->_df, false, ustr, cnt, &status);
        udat_applyPattern(formatter->_df, false, ustr, cnt);
        if (U_SUCCESS(status)) {
            if (formatter->_format) CFRelease(formatter->_format);
            formatter->_format = (CFStringRef)CFStringCreateCopy(CFGetAllocator(formatter), formatString);
        }
    }
}

CFStringRef CFDateFormatterCreateStringWithDate(CFAllocatorRef allocator, CFDateFormatterRef formatter, CFDateRef date) {
    if (allocator == NULL) allocator = __CFGetDefaultAllocator();
    __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
    __CFGenericValidateType(formatter, CFDateFormatterGetTypeID());
    __CFGenericValidateType(date, CFDateGetTypeID());
    return CFDateFormatterCreateStringWithAbsoluteTime(allocator, formatter, CFDateGetAbsoluteTime(date));
}

CFStringRef CFDateFormatterCreateStringWithAbsoluteTime(CFAllocatorRef allocator, CFDateFormatterRef formatter, CFAbsoluteTime at) {
    if (allocator == NULL) allocator = __CFGetDefaultAllocator();
    __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
    __CFGenericValidateType(formatter, CFDateFormatterGetTypeID());
    UChar *ustr = NULL, ubuffer[BUFFER_SIZE];
    UErrorCode status = U_ZERO_ERROR;
    CFIndex used, cnt = BUFFER_SIZE;
    UDate ud = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0 + 0.5;
    used = udat_format(formatter->_df, ud, ubuffer, cnt, NULL, &status);
    if (status == U_BUFFER_OVERFLOW_ERROR || cnt < used) {
	cnt = used + 1;
	ustr = (UChar *)CFAllocatorAllocate(kCFAllocatorSystemDefault, sizeof(UChar) * cnt, 0);
	status = U_ZERO_ERROR;
	used = udat_format(formatter->_df, ud, ustr, cnt, NULL, &status);
    }
    CFStringRef string = NULL;
    if (U_SUCCESS(status)) {
	string = CFStringCreateWithCharacters(allocator, (const UniChar *)(ustr ? ustr : ubuffer), used);
    }
    if (ustr) CFAllocatorDeallocate(kCFAllocatorSystemDefault, ustr);
    return string;
}

CFDateRef CFDateFormatterCreateDateFromString(CFAllocatorRef allocator, CFDateFormatterRef formatter, CFStringRef string, CFRange *rangep) {
    if (allocator == NULL) allocator = __CFGetDefaultAllocator();
    __CFGenericValidateType(allocator, CFAllocatorGetTypeID());
    __CFGenericValidateType(formatter, CFDateFormatterGetTypeID());
    __CFGenericValidateType(string, CFStringGetTypeID());
    CFAbsoluteTime at;
    if (CFDateFormatterGetAbsoluteTimeFromString(formatter, string, rangep, &at)) {
	return CFDateCreate(allocator, at);
    }
    return NULL;
}

Boolean CFDateFormatterGetAbsoluteTimeFromString(CFDateFormatterRef formatter, CFStringRef string, CFRange *rangep, CFAbsoluteTime *atp) {
    __CFGenericValidateType(formatter, CFDateFormatterGetTypeID());
    __CFGenericValidateType(string, CFStringGetTypeID());
    CFRange range = {0, 0};
    if (rangep) {
       range = *rangep;
    } else {
        range.length = CFStringGetLength(string);
    }
    if (1024 < range.length) range.length = 1024;
    const UChar *ustr = (UChar *)CFStringGetCharactersPtr(string);
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
    STACK_BUFFER_DECL(UChar, ubuffer, (NULL == ustr) ? range.length : 1);
#else
    UChar ubuffer[BUFFER_SIZE]; // Dynamic stack allocation is GNU specific
#endif
    if (NULL == ustr) {
        CFStringGetCharacters(string, range, (UniChar *)ubuffer);
        ustr = ubuffer;
    } else {
        ustr += range.location;
    }
    UDate udate;
    int32_t dpos = 0;
    UErrorCode status = U_ZERO_ERROR;
    if (formatter->_defaultDate) {
        CFAbsoluteTime at = CFDateGetAbsoluteTime(formatter->_defaultDate);
        udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
        UDateFormat *df2 = udat_clone(formatter->_df, &status);
        UCalendar *cal2 = (UCalendar *)udat_getCalendar(df2);
        ucal_setMillis(cal2, udate, &status);
        udat_parseCalendar(formatter->_df, cal2, ustr, range.length, &dpos, &status);
        udate = ucal_getMillis(cal2, &status);
        udat_close(df2);
    } else {
        udate = udat_parse(formatter->_df, ustr, range.length, &dpos, &status);
    }
    if (rangep) rangep->length = dpos;
    if (U_FAILURE(status)) {
        return false;
    }
    if (atp) {
        *atp = (double)udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970;
    }
    return true;
}

#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
#define SET_SYMBOLS_ARRAY(ICU_CODE, INDEX_BASE) \
        __CFGenericValidateType(value, CFArrayGetTypeID()); \
	CFArrayRef array = (CFArrayRef)value; \
	CFIndex idx, cnt = CFArrayGetCount(array); \
	for (idx = 0; idx < cnt; idx++) { \
	    CFStringRef item = (CFStringRef)CFArrayGetValueAtIndex(array, idx); \
	    __CFGenericValidateType(item, CFStringGetTypeID()); \
	    CFIndex item_cnt = CFStringGetLength(item); \
	    STACK_BUFFER_DECL(UChar, item_buffer, __CFMin(BUFFER_SIZE, item_cnt)); \
	    UChar *item_ustr = (UChar *)CFStringGetCharactersPtr(item); \
	    if (NULL == item_ustr) { \
		item_cnt = __CFMin(BUFFER_SIZE, item_cnt); \
	        CFStringGetCharacters(item, CFRangeMake(0, item_cnt), (UniChar *)item_buffer); \
		item_ustr = item_buffer; \
	    } \
	    status = U_ZERO_ERROR; \
	    udat_setSymbols(formatter->_df, ICU_CODE, idx + INDEX_BASE, item_ustr, item_cnt, &status); \
	}
#else
#define SET_SYMBOLS_ARRAY(ICU_CODE, INDEX_BASE) \
        __CFGenericValidateType(value, CFArrayGetTypeID()); \
	CFArrayRef array = (CFArrayRef)value; \
	CFIndex idx, cnt = CFArrayGetCount(array); \
	for (idx = 0; idx < cnt; idx++) { \
	    CFStringRef item = (CFStringRef)CFArrayGetValueAtIndex(array, idx); \
	    __CFGenericValidateType(item, CFStringGetTypeID()); \
	    CFIndex item_cnt = CFStringGetLength(item); \
       UChar item_buffer[BUFFER_SIZE]; \
	    UChar *item_ustr = (UChar *)CFStringGetCharactersPtr(item); \
	    if (NULL == item_ustr) { \
		item_cnt = __CFMin(BUFFER_SIZE, item_cnt); \
	        CFStringGetCharacters(item, CFRangeMake(0, item_cnt), (UniChar *)item_buffer); \
		item_ustr = item_buffer; \
	    } \
	    status = U_ZERO_ERROR; \
	    udat_setSymbols(formatter->_df, ICU_CODE, idx + INDEX_BASE, item_ustr, item_cnt, &status); \
	}
#endif


void CFDateFormatterSetProperty(CFDateFormatterRef formatter, CFStringRef key, CFTypeRef value) {
    __CFGenericValidateType(formatter, CFDateFormatterGetTypeID());
    __CFGenericValidateType(key, CFStringGetTypeID());
    UErrorCode status = U_ZERO_ERROR;
    UChar ubuffer[BUFFER_SIZE];

    if (kCFDateFormatterIsLenient == key) {
	__CFGenericValidateType(value, CFBooleanGetTypeID());
	udat_setLenient(formatter->_df, (kCFBooleanTrue == value));
    } else if (kCFDateFormatterCalendar == key) {
	__CFGenericValidateType(value, CFCalendarGetTypeID());
	CFStringRef localeName = CFLocaleGetIdentifier(formatter->_locale);
	CFDictionaryRef components = CFLocaleCreateComponentsFromLocaleIdentifier(kCFAllocatorSystemDefault, localeName);
	CFMutableDictionaryRef mcomponents = CFDictionaryCreateMutableCopy(kCFAllocatorSystemDefault, 0, components);
	CFDictionarySetValue(mcomponents, kCFLocaleCalendarIdentifier, CFCalendarGetIdentifier((CFCalendarRef)value));
	localeName = CFLocaleCreateLocaleIdentifierFromComponents(kCFAllocatorSystemDefault, mcomponents);
	CFRelease(mcomponents);
	CFRelease(components);
	CFLocaleRef newLocale = CFLocaleCreate(CFGetAllocator(formatter->_locale), localeName);
	CFRelease(localeName);
	CFRelease(formatter->_locale);
	formatter->_locale = newLocale;
	UCalendar *cal = __CFCalendarCreateUCalendar(NULL, CFLocaleGetIdentifier(formatter->_locale), formatter->_tz);
	if (cal) udat_setCalendar(formatter->_df, cal);
	if (cal) ucal_close(cal);
    } else if (kCFDateFormatterCalendarIdentifier == key || kCFDateFormatterCalendarName == key) {
	__CFGenericValidateType(value, CFStringGetTypeID());
	CFStringRef localeName = CFLocaleGetIdentifier(formatter->_locale);
	CFDictionaryRef components = CFLocaleCreateComponentsFromLocaleIdentifier(kCFAllocatorSystemDefault, localeName);
	CFMutableDictionaryRef mcomponents = CFDictionaryCreateMutableCopy(kCFAllocatorSystemDefault, 0, components);
	CFDictionarySetValue(mcomponents, kCFLocaleCalendarIdentifier, value);
	localeName = CFLocaleCreateLocaleIdentifierFromComponents(kCFAllocatorSystemDefault, mcomponents);
	CFRelease(mcomponents);
	CFRelease(components);
	CFLocaleRef newLocale = CFLocaleCreate(CFGetAllocator(formatter->_locale), localeName);
	CFRelease(localeName);
	CFRelease(formatter->_locale);
	formatter->_locale = newLocale;
	UCalendar *cal = __CFCalendarCreateUCalendar(NULL, CFLocaleGetIdentifier(formatter->_locale), formatter->_tz);
	if (cal) udat_setCalendar(formatter->_df, cal);
	if (cal) ucal_close(cal);
    } else if (kCFDateFormatterTimeZone == key) {
	__CFGenericValidateType(value, CFTimeZoneGetTypeID());
	CFTimeZoneRef old = formatter->_tz;
	formatter->_tz = value ? (CFTimeZoneRef)CFRetain(value) : CFTimeZoneCopyDefault();
	if (old) CFRelease(old);
	CFStringRef tznam = CFTimeZoneGetName(formatter->_tz);
	UCalendar *cal = (UCalendar *)udat_getCalendar(formatter->_df);
	CFIndex ucnt = CFStringGetLength(tznam);
	if (BUFFER_SIZE < ucnt) ucnt = BUFFER_SIZE;
	CFStringGetCharacters(tznam, CFRangeMake(0, ucnt), (UniChar *)ubuffer);
	ucal_setTimeZone(cal, ubuffer, ucnt, &status);
    } else if (kCFDateFormatterDefaultFormat == key) {
	// read-only attribute
    } else if (kCFDateFormatterTwoDigitStartDate == key) {
        __CFGenericValidateType(value, CFDateGetTypeID());
	CFAbsoluteTime at = CFDateGetAbsoluteTime((CFDateRef)value);
	UDate udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
	udat_set2DigitYearStart(formatter->_df, udate, &status);
    } else if (kCFDateFormatterDefaultDate == key) {
        __CFGenericValidateType(value, CFDateGetTypeID());
	CFDateRef old = formatter->_defaultDate;
	formatter->_defaultDate = value ? (CFDateRef)CFRetain(value) : NULL;
	if (old) CFRelease(old);
    } else if (kCFDateFormatterEraSymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_ERAS, 0)
    } else if (kCFDateFormatterMonthSymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_MONTHS, 0)
    } else if (kCFDateFormatterShortMonthSymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_SHORT_MONTHS, 0)
    } else if (kCFDateFormatterWeekdaySymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_WEEKDAYS, 1)
    } else if (kCFDateFormatterShortWeekdaySymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_SHORT_WEEKDAYS, 1)
    } else if (kCFDateFormatterAMSymbol == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
	CFIndex item_cnt = CFStringGetLength((CFStringRef)value);
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
	STACK_BUFFER_DECL(UChar, item_buffer, __CFMin(BUFFER_SIZE, item_cnt));
#else
   UChar item_buffer[BUFFER_SIZE];
#endif
	UChar *item_ustr = (UChar *)CFStringGetCharactersPtr((CFStringRef)value);
	if (NULL == item_ustr) {
	    item_cnt = __CFMin(BUFFER_SIZE, item_cnt);
	    CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, item_cnt), (UniChar *)item_buffer);
	    item_ustr = item_buffer;
	}
	udat_setSymbols(formatter->_df, UDAT_AM_PMS, 0, item_ustr, item_cnt, &status);
    } else if (kCFDateFormatterPMSymbol == key) {
        __CFGenericValidateType(value, CFStringGetTypeID());
	CFIndex item_cnt = CFStringGetLength((CFStringRef)value);
#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
	STACK_BUFFER_DECL(UChar, item_buffer, __CFMin(BUFFER_SIZE, item_cnt));
#else
   UChar item_buffer[BUFFER_SIZE];
#endif
	UChar *item_ustr = (UChar *)CFStringGetCharactersPtr((CFStringRef)value);
	if (NULL == item_ustr) {
	    item_cnt = __CFMin(BUFFER_SIZE, item_cnt);
	    CFStringGetCharacters((CFStringRef)value, CFRangeMake(0, item_cnt), (UniChar *)item_buffer);
	    item_ustr = item_buffer;
	}
	udat_setSymbols(formatter->_df, UDAT_AM_PMS, 1, item_ustr, item_cnt, &status);
    } else if (kCFDateFormatterGregorianStartDate == key) {
	__CFGenericValidateType(value, CFDateGetTypeID());
	CFAbsoluteTime at = CFDateGetAbsoluteTime((CFDateRef)value);
	UDate udate = (at + kCFAbsoluteTimeIntervalSince1970) * 1000.0;
	UCalendar *cal = (UCalendar *)udat_getCalendar(formatter->_df);
	ucal_setGregorianChange(cal, udate, &status);
    } else if (kCFDateFormatterLongEraSymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_ERA_NAMES, 0)
    } else if (kCFDateFormatterVeryShortMonthSymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_NARROW_MONTHS, 0)
    } else if (kCFDateFormatterStandaloneMonthSymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_STANDALONE_MONTHS, 0)
    } else if (kCFDateFormatterShortStandaloneMonthSymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_STANDALONE_SHORT_MONTHS, 0)
    } else if (kCFDateFormatterVeryShortStandaloneMonthSymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_STANDALONE_NARROW_MONTHS, 0)
    } else if (kCFDateFormatterVeryShortWeekdaySymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_NARROW_WEEKDAYS, 1)
    } else if (kCFDateFormatterStandaloneWeekdaySymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_STANDALONE_WEEKDAYS, 1)
    } else if (kCFDateFormatterShortStandaloneWeekdaySymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_STANDALONE_SHORT_WEEKDAYS, 1)
    } else if (kCFDateFormatterVeryShortStandaloneWeekdaySymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_STANDALONE_NARROW_WEEKDAYS, 1)
    } else if (kCFDateFormatterQuarterSymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_QUARTERS, 1)
    } else if (kCFDateFormatterShortQuarterSymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_SHORT_QUARTERS, 1)
    } else if (kCFDateFormatterStandaloneQuarterSymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_STANDALONE_QUARTERS, 1)
    } else if (kCFDateFormatterShortStandaloneQuarterSymbols == key) {
	SET_SYMBOLS_ARRAY(UDAT_STANDALONE_SHORT_QUARTERS, 1)
    } else {
	CFAssert3(0, __kCFLogAssertion, "%s(): unknown key %p (%@)", __PRETTY_FUNCTION__, key, key);
    }
}

#if DEPLOYMENT_TARGET_MACOSX || DEPLOYMENT_TARGET_WINDOWS || DEPLOYMENT_TARGET_LINUX
#define GET_SYMBOLS_ARRAY(ICU_CODE, INDEX_BASE) \
	CFIndex idx, cnt = udat_countSymbols(formatter->_df, ICU_CODE) - INDEX_BASE; \
	STACK_BUFFER_DECL(CFStringRef, strings, cnt); \
	for (idx = 0; idx < cnt; idx++) { \
	    CFStringRef str = NULL; \
	    status = U_ZERO_ERROR; \
	    CFIndex ucnt = udat_getSymbols(formatter->_df, ICU_CODE, idx + INDEX_BASE, ubuffer, BUFFER_SIZE, &status); \
	    if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) { \
		str = CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, ucnt); \
	    } \
	    strings[idx] = !str ? (CFStringRef)CFRetain(CFSTR("<error>")) : str; \
	} \
	CFArrayRef array = CFArrayCreate(CFGetAllocator(formatter), (const void **)strings, cnt, &kCFTypeArrayCallBacks); \
	while (cnt--) { \
	    CFRelease(strings[cnt]); \
	} \
	return array;
#else
#define GET_SYMBOLS_ARRAY(ICU_CODE, INDEX_BASE) \
	CFIndex idx, cnt = udat_countSymbols(formatter->_df, ICU_CODE) - INDEX_BASE; \
	CFStringRef strings[BUFFER_SIZE]; \
	for (idx = 0; idx < cnt; idx++) { \
	    CFStringRef str = NULL; \
	    status = U_ZERO_ERROR; \
	    CFIndex ucnt = udat_getSymbols(formatter->_df, ICU_CODE, idx + INDEX_BASE, ubuffer, BUFFER_SIZE, &status); \
	    if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) { \
		str = CFStringCreateWithCharacters(CFGetAllocator(formatter), (const UniChar *)ubuffer, ucnt); \
	    } \
	    strings[idx] = !str ? (CFStringRef)CFRetain(CFSTR("<error>")) : str; \
	} \
	CFArrayRef array = CFArrayCreate(CFGetAllocator(formatter), (const void **)strings, cnt, &kCFTypeArrayCallBacks); \
	while (cnt--) { \
	    CFRelease(strings[cnt]); \
	} \
	return array;
#endif

CFTypeRef CFDateFormatterCopyProperty(CFDateFormatterRef formatter, CFStringRef key) {
    __CFGenericValidateType(formatter, CFDateFormatterGetTypeID());
    __CFGenericValidateType(key, CFStringGetTypeID());
    UErrorCode status = U_ZERO_ERROR;
    UChar ubuffer[BUFFER_SIZE];

    if (kCFDateFormatterIsLenient == key) {
	return CFRetain(udat_isLenient(formatter->_df) ? kCFBooleanTrue : kCFBooleanFalse);
    } else if (kCFDateFormatterCalendar == key) {
	CFCalendarRef calendar = (CFCalendarRef)CFLocaleGetValue(formatter->_locale, kCFLocaleCalendar);
	return calendar ? CFRetain(calendar) : NULL;
    } else if (kCFDateFormatterCalendarIdentifier == key || kCFDateFormatterCalendarName == key) {
	CFStringRef ident = (CFStringRef)CFLocaleGetValue(formatter->_locale, kCFLocaleCalendarIdentifier);
	return ident ? CFRetain(ident) : NULL;
    } else if (kCFDateFormatterTimeZone == key) {
	return CFRetain(formatter->_tz);
    } else if (kCFDateFormatterDefaultFormat == key) {
	return formatter->_defformat ? CFRetain(formatter->_defformat) : NULL;
    } else if (kCFDateFormatterTwoDigitStartDate == key) {
	UDate udate = udat_get2DigitYearStart(formatter->_df, &status);
        if (U_SUCCESS(status)) {
	    CFAbsoluteTime at = (double)udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970;
            return CFDateCreate(CFGetAllocator(formatter), at);
        }
    } else if (kCFDateFormatterDefaultDate == key) {
	return formatter->_defaultDate ? CFRetain(formatter->_defaultDate) : NULL;
    } else if (kCFDateFormatterEraSymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_ERAS, 0)
    } else if (kCFDateFormatterMonthSymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_MONTHS, 0)
    } else if (kCFDateFormatterShortMonthSymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_SHORT_MONTHS, 0)
    } else if (kCFDateFormatterWeekdaySymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_WEEKDAYS, 1)
    } else if (kCFDateFormatterShortWeekdaySymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_SHORT_WEEKDAYS, 1)
    } else if (kCFDateFormatterAMSymbol == key) {
	CFIndex cnt = udat_countSymbols(formatter->_df, UDAT_AM_PMS);
	if (2 <= cnt) {
	    CFIndex ucnt = udat_getSymbols(formatter->_df, UDAT_AM_PMS, 0, ubuffer, BUFFER_SIZE, &status);
	    if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
		return CFStringCreateWithCharacters(CFGetAllocator(formatter), (UniChar *)ubuffer, ucnt);
	    }
	}	
    } else if (kCFDateFormatterPMSymbol == key) {
	CFIndex cnt = udat_countSymbols(formatter->_df, UDAT_AM_PMS);
	if (2 <= cnt) {
	    CFIndex ucnt = udat_getSymbols(formatter->_df, UDAT_AM_PMS, 1, ubuffer, BUFFER_SIZE, &status);
	    if (U_SUCCESS(status) && cnt <= BUFFER_SIZE) {
		return CFStringCreateWithCharacters(CFGetAllocator(formatter), (UniChar *)ubuffer, ucnt);
	    }
	}	
    } else if (kCFDateFormatterGregorianStartDate == key) {
	UCalendar *cal = (UCalendar *)udat_getCalendar(formatter->_df);
	UDate udate = ucal_getGregorianChange(cal, &status);
        if (U_SUCCESS(status)) {
	    CFAbsoluteTime at = (double)udate / 1000.0 - kCFAbsoluteTimeIntervalSince1970;
            return CFDateCreate(CFGetAllocator(formatter), at);
        }
    } else if (kCFDateFormatterLongEraSymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_ERA_NAMES, 0)
    } else if (kCFDateFormatterVeryShortMonthSymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_NARROW_MONTHS, 0)
    } else if (kCFDateFormatterStandaloneMonthSymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_STANDALONE_MONTHS, 0)
    } else if (kCFDateFormatterShortStandaloneMonthSymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_STANDALONE_SHORT_MONTHS, 0)
    } else if (kCFDateFormatterVeryShortStandaloneMonthSymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_STANDALONE_NARROW_MONTHS, 0)
    } else if (kCFDateFormatterVeryShortWeekdaySymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_NARROW_WEEKDAYS, 1)
    } else if (kCFDateFormatterStandaloneWeekdaySymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_STANDALONE_WEEKDAYS, 1)
    } else if (kCFDateFormatterShortStandaloneWeekdaySymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_STANDALONE_SHORT_WEEKDAYS, 1)
    } else if (kCFDateFormatterVeryShortStandaloneWeekdaySymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_STANDALONE_NARROW_WEEKDAYS, 1)
    } else if (kCFDateFormatterQuarterSymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_QUARTERS, 1)
    } else if (kCFDateFormatterShortQuarterSymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_SHORT_QUARTERS, 1)
    } else if (kCFDateFormatterStandaloneQuarterSymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_STANDALONE_QUARTERS, 1)
    } else if (kCFDateFormatterShortStandaloneQuarterSymbols == key) {
	GET_SYMBOLS_ARRAY(UDAT_STANDALONE_SHORT_QUARTERS, 1)
    } else {
	CFAssert3(0, __kCFLogAssertion, "%s(): unknown key %p (%@)", __PRETTY_FUNCTION__, key, key);
    }
    return NULL;
}

CONST_STRING_DECL(kCFDateFormatterIsLenient, "kCFDateFormatterIsLenient")
CONST_STRING_DECL(kCFDateFormatterTimeZone, "kCFDateFormatterTimeZone")
CONST_STRING_DECL(kCFDateFormatterCalendarName, "kCFDateFormatterCalendarName")
CONST_STRING_DECL(kCFDateFormatterCalendarIdentifier, "kCFDateFormatterCalendarIdentifier")
CONST_STRING_DECL(kCFDateFormatterCalendar, "kCFDateFormatterCalendar")
CONST_STRING_DECL(kCFDateFormatterDefaultFormat, "kCFDateFormatterDefaultFormat")

CONST_STRING_DECL(kCFDateFormatterTwoDigitStartDate, "kCFDateFormatterTwoDigitStartDate")
CONST_STRING_DECL(kCFDateFormatterDefaultDate, "kCFDateFormatterDefaultDate")
CONST_STRING_DECL(kCFDateFormatterEraSymbols, "kCFDateFormatterEraSymbols")
CONST_STRING_DECL(kCFDateFormatterMonthSymbols, "kCFDateFormatterMonthSymbols")
CONST_STRING_DECL(kCFDateFormatterShortMonthSymbols, "kCFDateFormatterShortMonthSymbols")
CONST_STRING_DECL(kCFDateFormatterWeekdaySymbols, "kCFDateFormatterWeekdaySymbols")
CONST_STRING_DECL(kCFDateFormatterShortWeekdaySymbols, "kCFDateFormatterShortWeekdaySymbols")
CONST_STRING_DECL(kCFDateFormatterAMSymbol, "kCFDateFormatterAMSymbol")
CONST_STRING_DECL(kCFDateFormatterPMSymbol, "kCFDateFormatterPMSymbol")

CONST_STRING_DECL(kCFDateFormatterLongEraSymbols, "kCFDateFormatterLongEraSymbols")
CONST_STRING_DECL(kCFDateFormatterVeryShortMonthSymbols, "kCFDateFormatterVeryShortMonthSymbols")
CONST_STRING_DECL(kCFDateFormatterStandaloneMonthSymbols, "kCFDateFormatterStandaloneMonthSymbols")
CONST_STRING_DECL(kCFDateFormatterShortStandaloneMonthSymbols, "kCFDateFormatterShortStandaloneMonthSymbols")
CONST_STRING_DECL(kCFDateFormatterVeryShortStandaloneMonthSymbols, "kCFDateFormatterVeryShortStandaloneMonthSymbols")
CONST_STRING_DECL(kCFDateFormatterVeryShortWeekdaySymbols, "kCFDateFormatterVeryShortWeekdaySymbols")
CONST_STRING_DECL(kCFDateFormatterStandaloneWeekdaySymbols, "kCFDateFormatterStandaloneWeekdaySymbols")
CONST_STRING_DECL(kCFDateFormatterShortStandaloneWeekdaySymbols, "kCFDateFormatterShortStandaloneWeekdaySymbols")
CONST_STRING_DECL(kCFDateFormatterVeryShortStandaloneWeekdaySymbols, "kCFDateFormatterVeryShortStandaloneWeekdaySymbols")
CONST_STRING_DECL(kCFDateFormatterQuarterSymbols, "kCFDateFormatterQuarterSymbols")
CONST_STRING_DECL(kCFDateFormatterShortQuarterSymbols, "kCFDateFormatterShortQuarterSymbols")
CONST_STRING_DECL(kCFDateFormatterStandaloneQuarterSymbols, "kCFDateFormatterStandaloneQuarterSymbols")
CONST_STRING_DECL(kCFDateFormatterShortStandaloneQuarterSymbols, "kCFDateFormatterShortStandaloneQuarterSymbols")
CONST_STRING_DECL(kCFDateFormatterGregorianStartDate, "kCFDateFormatterGregorianStartDate")

#undef BUFFER_SIZE

