1 /* 2 * Copyright 2019, Andrew Lindesay <apl@lindesay.co.nz>. 3 * All rights reserved. Distributed under the terms of the MIT License. 4 */ 5 #include "LocaleUtils.h" 6 7 #include <stdlib.h> 8 #include <unicode/datefmt.h> 9 #include <unicode/dtptngen.h> 10 #include <unicode/smpdtfmt.h> 11 12 #include <Catalog.h> 13 #include <Collator.h> 14 #include <ICUWrapper.h> 15 #include <Locale.h> 16 #include <LocaleRoster.h> 17 #include <StringFormat.h> 18 19 20 #undef B_TRANSLATION_CONTEXT 21 #define B_TRANSLATION_CONTEXT "LocaleUtils" 22 23 24 BCollator* LocaleUtils::sSharedCollator = NULL; 25 26 27 /*static*/ BCollator* 28 LocaleUtils::GetSharedCollator() 29 { 30 if (sSharedCollator == NULL) { 31 sSharedCollator = new BCollator(); 32 GetCollator(sSharedCollator); 33 } 34 35 return sSharedCollator; 36 } 37 38 39 /*static*/ void 40 LocaleUtils::GetCollator(BCollator* collator) 41 { 42 const BLocale* locale = BLocaleRoster::Default()->GetDefaultLocale(); 43 44 if (B_OK != locale->GetCollator(collator)) { 45 debugger("unable to get the locale's collator"); 46 exit(EXIT_FAILURE); 47 } 48 } 49 50 51 /*! There was some difficulty in getting BDateTime and friends to 52 work for the purposes of this application. Data comes in as millis since 53 the epoc relative to GMT0. These need to be displayed in the local time 54 zone, but the timezone aspect never seems to be quite right with BDateTime! 55 For now, to avoid this work over-spilling into a debug of the date-time 56 classes in Haiku, I am adding this method that uses ICU directly in order 57 to get something basic working for now. Later this should be migrated to 58 use the BDateTime etc... classes from Haiku once these problems have been 59 ironed out. 60 */ 61 62 /*static*/ BString 63 LocaleUtils::TimestampToDateTimeString(uint64 millis) 64 { 65 if (millis == 0) 66 return "?"; 67 68 UnicodeString pattern("yyyy-MM-dd HH:mm:ss"); 69 // later use variants of DateFormat::createInstance() 70 UErrorCode success = U_ZERO_ERROR; 71 SimpleDateFormat sdf(pattern, success); 72 73 if (U_FAILURE(success)) 74 return "!"; 75 76 UnicodeString icuResult; 77 sdf.format((UDate) millis, icuResult); 78 BString result; 79 BStringByteSink converter(&result); 80 icuResult.toUTF8(converter); 81 return result; 82 } 83 84 85 /*! This is used in situations where the user is required to confirm that they 86 are as old or older than some minimal age. This is associated with agreeing 87 to the user usage conditions. 88 */ 89 90 /*static*/ BString 91 LocaleUtils::CreateTranslatedIAmMinimumAgeSlug(int minimumAge) 92 { 93 BString slug; 94 static BStringFormat format(B_TRANSLATE("{0, plural," 95 "one{I am at least one year old}" 96 "other{I am # years of age or older}}")); 97 format.Format(slug, minimumAge); 98 return slug; 99 } 100