| OLD | NEW |
| 1 /* | 1 /* |
| 2 ******************************************************************************* | 2 ******************************************************************************* |
| 3 * Copyright (C) 1997-2014, International Business Machines Corporation and * | 3 * Copyright (C) 1997-2015, International Business Machines Corporation and * |
| 4 * others. All Rights Reserved. * | 4 * others. All Rights Reserved. * |
| 5 ******************************************************************************* | 5 ******************************************************************************* |
| 6 * | 6 * |
| 7 * File CALENDAR.CPP | 7 * File CALENDAR.CPP |
| 8 * | 8 * |
| 9 * Modification History: | 9 * Modification History: |
| 10 * | 10 * |
| 11 * Date Name Description | 11 * Date Name Description |
| 12 * 02/03/97 clhuang Creation. | 12 * 02/03/97 clhuang Creation. |
| 13 * 04/22/97 aliu Cleaned up, fixed memory leak, made | 13 * 04/22/97 aliu Cleaned up, fixed memory leak, made |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 50 #include "unicode/calendar.h" | 50 #include "unicode/calendar.h" |
| 51 #include "cpputils.h" | 51 #include "cpputils.h" |
| 52 #include "servloc.h" | 52 #include "servloc.h" |
| 53 #include "ucln_in.h" | 53 #include "ucln_in.h" |
| 54 #include "cstring.h" | 54 #include "cstring.h" |
| 55 #include "locbased.h" | 55 #include "locbased.h" |
| 56 #include "uresimp.h" | 56 #include "uresimp.h" |
| 57 #include "ustrenum.h" | 57 #include "ustrenum.h" |
| 58 #include "uassert.h" | 58 #include "uassert.h" |
| 59 #include "olsontz.h" | 59 #include "olsontz.h" |
| 60 #include "sharedcalendar.h" |
| 61 #include "unifiedcache.h" |
| 60 | 62 |
| 61 #if !UCONFIG_NO_SERVICE | 63 #if !UCONFIG_NO_SERVICE |
| 62 static icu::ICULocaleService* gService = NULL; | 64 static icu::ICULocaleService* gService = NULL; |
| 63 static icu::UInitOnce gServiceInitOnce = U_INITONCE_INITIALIZER; | 65 static icu::UInitOnce gServiceInitOnce = U_INITONCE_INITIALIZER; |
| 64 #endif | 66 #endif |
| 65 | 67 |
| 66 // INTERNAL - for cleanup | 68 // INTERNAL - for cleanup |
| 67 | 69 |
| 68 U_CDECL_BEGIN | 70 U_CDECL_BEGIN |
| 69 static UBool calendar_cleanup(void) { | 71 static UBool calendar_cleanup(void) { |
| (...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 192 CALTYPE_ETHIOPIC_AMETE_ALEM, | 194 CALTYPE_ETHIOPIC_AMETE_ALEM, |
| 193 CALTYPE_ISO8601, | 195 CALTYPE_ISO8601, |
| 194 CALTYPE_DANGI, | 196 CALTYPE_DANGI, |
| 195 CALTYPE_ISLAMIC_UMALQURA, | 197 CALTYPE_ISLAMIC_UMALQURA, |
| 196 CALTYPE_ISLAMIC_TBLA, | 198 CALTYPE_ISLAMIC_TBLA, |
| 197 CALTYPE_ISLAMIC_RGSA | 199 CALTYPE_ISLAMIC_RGSA |
| 198 } ECalType; | 200 } ECalType; |
| 199 | 201 |
| 200 U_NAMESPACE_BEGIN | 202 U_NAMESPACE_BEGIN |
| 201 | 203 |
| 204 SharedCalendar::~SharedCalendar() { |
| 205 delete ptr; |
| 206 } |
| 207 |
| 208 template<> U_I18N_API |
| 209 const SharedCalendar *LocaleCacheKey<SharedCalendar>::createObject( |
| 210 const void * /*unusedCreationContext*/, UErrorCode &status) const { |
| 211 Calendar *calendar = Calendar::makeInstance(fLoc, status); |
| 212 if (U_FAILURE(status)) { |
| 213 return NULL; |
| 214 } |
| 215 SharedCalendar *shared = new SharedCalendar(calendar); |
| 216 if (shared == NULL) { |
| 217 delete calendar; |
| 218 status = U_MEMORY_ALLOCATION_ERROR; |
| 219 return NULL; |
| 220 } |
| 221 shared->addRef(); |
| 222 return shared; |
| 223 } |
| 224 |
| 202 static ECalType getCalendarType(const char *s) { | 225 static ECalType getCalendarType(const char *s) { |
| 203 for (int i = 0; gCalTypes[i] != NULL; i++) { | 226 for (int i = 0; gCalTypes[i] != NULL; i++) { |
| 204 if (uprv_stricmp(s, gCalTypes[i]) == 0) { | 227 if (uprv_stricmp(s, gCalTypes[i]) == 0) { |
| 205 return (ECalType)i; | 228 return (ECalType)i; |
| 206 } | 229 } |
| 207 } | 230 } |
| 208 return CALTYPE_UNKNOWN; | 231 return CALTYPE_UNKNOWN; |
| 209 } | 232 } |
| 210 | 233 |
| 211 static UBool isStandardSupportedKeyword(const char *keyword, UErrorCode& status)
{ | 234 static UBool isStandardSupportedKeyword(const char *keyword, UErrorCode& status)
{ |
| (...skipping 393 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 605 { 0, 0, 23, 23 }, // HOUR_OF_DAY | 628 { 0, 0, 23, 23 }, // HOUR_OF_DAY |
| 606 { 0, 0, 59, 59 }, // MINUTE | 629 { 0, 0, 59, 59 }, // MINUTE |
| 607 { 0, 0, 59, 59 }, // SECOND | 630 { 0, 0, 59, 59 }, // SECOND |
| 608 { 0, 0, 999, 999 }, // MILLISECOND | 631 { 0, 0, 999, 999 }, // MILLISECOND |
| 609 {-12*kOneHour, -12*kOneHour, 12*kOneHour, 15*kOneHour }, // ZONE_OFFSET | 632 {-12*kOneHour, -12*kOneHour, 12*kOneHour, 15*kOneHour }, // ZONE_OFFSET |
| 610 { 0, 0, 1*kOneHour, 1*kOneHour }, // DST_OFFSET | 633 { 0, 0, 1*kOneHour, 1*kOneHour }, // DST_OFFSET |
| 611 {/*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1}, // YEAR_WOY | 634 {/*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1}, // YEAR_WOY |
| 612 { 1, 1, 7, 7 }, // DOW_LOCAL | 635 { 1, 1, 7, 7 }, // DOW_LOCAL |
| 613 {/*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1}, // EXTENDED_YE
AR | 636 {/*N/A*/-1, /*N/A*/-1, /*N/A*/-1, /*N/A*/-1}, // EXTENDED_YE
AR |
| 614 { -0x7F000000, -0x7F000000, 0x7F000000, 0x7F000000 }, // JULIAN_DAY | 637 { -0x7F000000, -0x7F000000, 0x7F000000, 0x7F000000 }, // JULIAN_DAY |
| 615 { 0, 0, 24*kOneHour-1, 24*kOneHour-1 }, // MILLISECON
DS_IN_DAY | 638 { 0, 0, 24*kOneHour-1, 24*kOneHour-1 }, // MILLISECOND
S_IN_DAY |
| 616 { 0, 0, 1, 1 }, // IS_LEAP_MO
NTH | 639 { 0, 0, 1, 1 }, // IS_LEAP_MON
TH |
| 617 }; | 640 }; |
| 618 | 641 |
| 619 // Resource bundle tags read by this class | 642 // Resource bundle tags read by this class |
| 620 static const char gMonthNames[] = "monthNames"; | 643 static const char gMonthNames[] = "monthNames"; |
| 621 | 644 |
| 622 // Data flow in Calendar | 645 // Data flow in Calendar |
| 623 // --------------------- | 646 // --------------------- |
| 624 | 647 |
| 625 // The current time is represented in two ways by Calendar: as UTC | 648 // The current time is represented in two ways by Calendar: as UTC |
| 626 // milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local | 649 // milliseconds from the epoch start (1 January 1970 0:00 UTC), and as local |
| (...skipping 199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 826 Calendar* U_EXPORT2 | 849 Calendar* U_EXPORT2 |
| 827 Calendar::createInstance(const Locale& aLocale, UErrorCode& success) | 850 Calendar::createInstance(const Locale& aLocale, UErrorCode& success) |
| 828 { | 851 { |
| 829 return createInstance(TimeZone::createDefault(), aLocale, success); | 852 return createInstance(TimeZone::createDefault(), aLocale, success); |
| 830 } | 853 } |
| 831 | 854 |
| 832 // ------------------------------------- Adopting | 855 // ------------------------------------- Adopting |
| 833 | 856 |
| 834 // Note: this is the bottleneck that actually calls the service routines. | 857 // Note: this is the bottleneck that actually calls the service routines. |
| 835 | 858 |
| 836 Calendar* U_EXPORT2 | 859 Calendar * U_EXPORT2 |
| 837 Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& succ
ess) | 860 Calendar::makeInstance(const Locale& aLocale, UErrorCode& success) { |
| 838 { | |
| 839 if (U_FAILURE(success)) { | 861 if (U_FAILURE(success)) { |
| 840 return NULL; | 862 return NULL; |
| 841 } | 863 } |
| 842 | 864 |
| 843 Locale actualLoc; | 865 Locale actualLoc; |
| 844 UObject* u = NULL; | 866 UObject* u = NULL; |
| 845 | 867 |
| 846 #if !UCONFIG_NO_SERVICE | 868 #if !UCONFIG_NO_SERVICE |
| 847 if (isCalendarServiceUsed()) { | 869 if (isCalendarServiceUsed()) { |
| 848 u = getCalendarService(success)->get(aLocale, LocaleKey::KIND_ANY, &actu
alLoc, success); | 870 u = getCalendarService(success)->get(aLocale, LocaleKey::KIND_ANY, &actu
alLoc, success); |
| 849 } | 871 } |
| 850 else | 872 else |
| 851 #endif | 873 #endif |
| 852 { | 874 { |
| 853 u = createStandardCalendar(getCalendarTypeForLocale(aLocale.getName()),
aLocale, success); | 875 u = createStandardCalendar(getCalendarTypeForLocale(aLocale.getName()),
aLocale, success); |
| 854 } | 876 } |
| 855 Calendar* c = NULL; | 877 Calendar* c = NULL; |
| 856 | 878 |
| 857 if(U_FAILURE(success) || !u) { | 879 if(U_FAILURE(success) || !u) { |
| 858 delete zone; | |
| 859 if(U_SUCCESS(success)) { // Propagate some kind of err | 880 if(U_SUCCESS(success)) { // Propagate some kind of err |
| 860 success = U_INTERNAL_PROGRAM_ERROR; | 881 success = U_INTERNAL_PROGRAM_ERROR; |
| 861 } | 882 } |
| 862 return NULL; | 883 return NULL; |
| 863 } | 884 } |
| 864 | 885 |
| 865 #if !UCONFIG_NO_SERVICE | 886 #if !UCONFIG_NO_SERVICE |
| 866 const UnicodeString* str = dynamic_cast<const UnicodeString*>(u); | 887 const UnicodeString* str = dynamic_cast<const UnicodeString*>(u); |
| 867 if(str != NULL) { | 888 if(str != NULL) { |
| 868 // It's a unicode string telling us what type of calendar to load ("greg
orian", etc) | 889 // It's a unicode string telling us what type of calendar to load ("greg
orian", etc) |
| 869 // Create a Locale over this string | 890 // Create a Locale over this string |
| 870 Locale l(""); | 891 Locale l(""); |
| 871 LocaleUtility::initLocaleFromName(*str, l); | 892 LocaleUtility::initLocaleFromName(*str, l); |
| 872 | 893 |
| 873 #ifdef U_DEBUG_CALSVC | 894 #ifdef U_DEBUG_CALSVC |
| 874 fprintf(stderr, "Calendar::createInstance(%s), looking up [%s]\n", aLoca
le.getName(), l.getName()); | 895 fprintf(stderr, "Calendar::createInstance(%s), looking up [%s]\n", aLoca
le.getName(), l.getName()); |
| 875 #endif | 896 #endif |
| 876 | 897 |
| 877 Locale actualLoc2; | 898 Locale actualLoc2; |
| 878 delete u; | 899 delete u; |
| 879 u = NULL; | 900 u = NULL; |
| 880 | 901 |
| 881 // Don't overwrite actualLoc, since the actual loc from this call | 902 // Don't overwrite actualLoc, since the actual loc from this call |
| 882 // may be something like "@calendar=gregorian" -- TODO investigate | 903 // may be something like "@calendar=gregorian" -- TODO investigate |
| 883 // further... | 904 // further... |
| 884 c = (Calendar*)getCalendarService(success)->get(l, LocaleKey::KIND_ANY,
&actualLoc2, success); | 905 c = (Calendar*)getCalendarService(success)->get(l, LocaleKey::KIND_ANY,
&actualLoc2, success); |
| 885 | 906 |
| 886 if(U_FAILURE(success) || !c) { | 907 if(U_FAILURE(success) || !c) { |
| 887 delete zone; | |
| 888 if(U_SUCCESS(success)) { | 908 if(U_SUCCESS(success)) { |
| 889 success = U_INTERNAL_PROGRAM_ERROR; // Propagate some err | 909 success = U_INTERNAL_PROGRAM_ERROR; // Propagate some err |
| 890 } | 910 } |
| 891 return NULL; | 911 return NULL; |
| 892 } | 912 } |
| 893 | 913 |
| 894 str = dynamic_cast<const UnicodeString*>(c); | 914 str = dynamic_cast<const UnicodeString*>(c); |
| 895 if(str != NULL) { | 915 if(str != NULL) { |
| 896 // recursed! Second lookup returned a UnicodeString. | 916 // recursed! Second lookup returned a UnicodeString. |
| 897 // Perhaps DefaultCalendar{} was set to another locale. | 917 // Perhaps DefaultCalendar{} was set to another locale. |
| 898 #ifdef U_DEBUG_CALSVC | 918 #ifdef U_DEBUG_CALSVC |
| 899 char tmp[200]; | 919 char tmp[200]; |
| 900 // Extract a char* out of it.. | 920 // Extract a char* out of it.. |
| 901 int32_t len = str->length(); | 921 int32_t len = str->length(); |
| 902 int32_t actLen = sizeof(tmp)-1; | 922 int32_t actLen = sizeof(tmp)-1; |
| 903 if(len > actLen) { | 923 if(len > actLen) { |
| 904 len = actLen; | 924 len = actLen; |
| 905 } | 925 } |
| 906 str->extract(0,len,tmp); | 926 str->extract(0,len,tmp); |
| 907 tmp[len]=0; | 927 tmp[len]=0; |
| 908 | 928 |
| 909 fprintf(stderr, "err - recursed, 2nd lookup was unistring %s\n", tmp
); | 929 fprintf(stderr, "err - recursed, 2nd lookup was unistring %s\n", tmp
); |
| 910 #endif | 930 #endif |
| 911 success = U_MISSING_RESOURCE_ERROR; // requested a calendar type wh
ich could NOT be found. | 931 success = U_MISSING_RESOURCE_ERROR; // requested a calendar type wh
ich could NOT be found. |
| 912 delete c; | 932 delete c; |
| 913 delete zone; | |
| 914 return NULL; | 933 return NULL; |
| 915 } | 934 } |
| 916 #ifdef U_DEBUG_CALSVC | 935 #ifdef U_DEBUG_CALSVC |
| 917 fprintf(stderr, "%p: setting week count data to locale %s, actual locale
%s\n", c, (const char*)aLocale.getName(), (const char *)actualLoc.getName()); | 936 fprintf(stderr, "%p: setting week count data to locale %s, actual locale
%s\n", c, (const char*)aLocale.getName(), (const char *)actualLoc.getName()); |
| 918 #endif | 937 #endif |
| 919 c->setWeekData(aLocale, c->getType(), success); // set the correct loca
le (this was an indirected calendar) | 938 c->setWeekData(aLocale, c->getType(), success); // set the correct loca
le (this was an indirected calendar) |
| 920 | 939 |
| 921 char keyword[ULOC_FULLNAME_CAPACITY]; | 940 char keyword[ULOC_FULLNAME_CAPACITY]; |
| 922 UErrorCode tmpStatus = U_ZERO_ERROR; | 941 UErrorCode tmpStatus = U_ZERO_ERROR; |
| 923 l.getKeywordValue("calendar", keyword, ULOC_FULLNAME_CAPACITY, tmpStatus
); | 942 l.getKeywordValue("calendar", keyword, ULOC_FULLNAME_CAPACITY, tmpStatus
); |
| 924 if (U_SUCCESS(tmpStatus) && uprv_strcmp(keyword, "iso8601") == 0) { | 943 if (U_SUCCESS(tmpStatus) && uprv_strcmp(keyword, "iso8601") == 0) { |
| 925 c->setFirstDayOfWeek(UCAL_MONDAY); | 944 c->setFirstDayOfWeek(UCAL_MONDAY); |
| 926 c->setMinimalDaysInFirstWeek(4); | 945 c->setMinimalDaysInFirstWeek(4); |
| 927 } | 946 } |
| 928 } | 947 } |
| 929 else | 948 else |
| 930 #endif /* UCONFIG_NO_SERVICE */ | 949 #endif /* UCONFIG_NO_SERVICE */ |
| 931 { | 950 { |
| 932 // a calendar was returned - we assume the factory did the right thing. | 951 // a calendar was returned - we assume the factory did the right thing. |
| 933 c = (Calendar*)u; | 952 c = (Calendar*)u; |
| 934 } | 953 } |
| 935 | 954 |
| 955 return c; |
| 956 } |
| 957 |
| 958 Calendar* U_EXPORT2 |
| 959 Calendar::createInstance(TimeZone* zone, const Locale& aLocale, UErrorCode& succ
ess) |
| 960 { |
| 961 LocalPointer<TimeZone> zonePtr(zone); |
| 962 const SharedCalendar *shared = NULL; |
| 963 UnifiedCache::getByLocale(aLocale, shared, success); |
| 964 if (U_FAILURE(success)) { |
| 965 return NULL; |
| 966 } |
| 967 Calendar *c = (*shared)->clone(); |
| 968 shared->removeRef(); |
| 969 if (c == NULL) { |
| 970 success = U_MEMORY_ALLOCATION_ERROR; |
| 971 return NULL; |
| 972 } |
| 973 |
| 936 // Now, reset calendar to default state: | 974 // Now, reset calendar to default state: |
| 937 c->adoptTimeZone(zone); // Set the correct time zone | 975 c->adoptTimeZone(zonePtr.orphan()); // Set the correct time zone |
| 938 c->setTimeInMillis(getNow(), success); // let the new calendar have the curr
ent time. | 976 c->setTimeInMillis(getNow(), success); // let the new calendar have the curr
ent time. |
| 939 | 977 |
| 940 return c; | 978 return c; |
| 941 } | 979 } |
| 942 | 980 |
| 943 // ------------------------------------- | 981 // ------------------------------------- |
| 944 | 982 |
| 945 Calendar* U_EXPORT2 | 983 Calendar* U_EXPORT2 |
| 946 Calendar::createInstance(const TimeZone& zone, const Locale& aLocale, UErrorCode
& success) | 984 Calendar::createInstance(const TimeZone& zone, const Locale& aLocale, UErrorCode
& success) |
| 947 { | 985 { |
| 948 Calendar* c = createInstance(aLocale, success); | 986 Calendar* c = createInstance(aLocale, success); |
| 949 if(U_SUCCESS(success) && c) { | 987 if(U_SUCCESS(success) && c) { |
| 950 c->setTimeZone(zone); | 988 c->setTimeZone(zone); |
| 951 } | 989 } |
| 952 return c; | 990 return c; |
| 953 } | 991 } |
| 954 | 992 |
| 955 // ------------------------------------- | 993 // ------------------------------------- |
| 956 | 994 |
| 995 void U_EXPORT2 |
| 996 Calendar::getCalendarTypeFromLocale( |
| 997 const Locale &aLocale, |
| 998 char *typeBuffer, |
| 999 int32_t typeBufferSize, |
| 1000 UErrorCode &success) { |
| 1001 const SharedCalendar *shared = NULL; |
| 1002 UnifiedCache::getByLocale(aLocale, shared, success); |
| 1003 if (U_FAILURE(success)) { |
| 1004 return; |
| 1005 } |
| 1006 uprv_strncpy(typeBuffer, (*shared)->getType(), typeBufferSize); |
| 1007 shared->removeRef(); |
| 1008 if (typeBuffer[typeBufferSize - 1]) { |
| 1009 success = U_BUFFER_OVERFLOW_ERROR; |
| 1010 } |
| 1011 } |
| 1012 |
| 957 UBool | 1013 UBool |
| 958 Calendar::operator==(const Calendar& that) const | 1014 Calendar::operator==(const Calendar& that) const |
| 959 { | 1015 { |
| 960 UErrorCode status = U_ZERO_ERROR; | 1016 UErrorCode status = U_ZERO_ERROR; |
| 961 return isEquivalentTo(that) && | 1017 return isEquivalentTo(that) && |
| 962 getTimeInMillis(status) == that.getTimeInMillis(status) && | 1018 getTimeInMillis(status) == that.getTimeInMillis(status) && |
| 963 U_SUCCESS(status); | 1019 U_SUCCESS(status); |
| 964 } | 1020 } |
| 965 | 1021 |
| 966 UBool | 1022 UBool |
| (...skipping 2899 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3866 return NULL; | 3922 return NULL; |
| 3867 } | 3923 } |
| 3868 | 3924 |
| 3869 U_NAMESPACE_END | 3925 U_NAMESPACE_END |
| 3870 | 3926 |
| 3871 #endif /* #if !UCONFIG_NO_FORMATTING */ | 3927 #endif /* #if !UCONFIG_NO_FORMATTING */ |
| 3872 | 3928 |
| 3873 | 3929 |
| 3874 //eof | 3930 //eof |
| 3875 | 3931 |
| OLD | NEW |