xref: /haiku/src/apps/haikudepot/util/LocaleUtils.cpp (revision 04d1d2da0b27294f0f1e623071df310a0820d4b6)
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