138ac8defSOliver Tappe /* 2*e3857211SAdrien Destugues * Copyright 2010-2014, Haiku, Inc. All Rights Reserved. 338ac8defSOliver Tappe * Distributed under the terms of the MIT License. 438ac8defSOliver Tappe * 538ac8defSOliver Tappe * Authors: 638ac8defSOliver Tappe * Oliver Tappe <zooey@hirschkaefer.de> 738ac8defSOliver Tappe */ 838ac8defSOliver Tappe 938ac8defSOliver Tappe #include <DateTimeFormat.h> 1038ac8defSOliver Tappe 11*e3857211SAdrien Destugues #include <AutoDeleter.h> 12*e3857211SAdrien Destugues #include <Autolock.h> 13*e3857211SAdrien Destugues #include <FormattingConventionsPrivate.h> 14*e3857211SAdrien Destugues #include <LanguagePrivate.h> 15*e3857211SAdrien Destugues #include <TimeZone.h> 1638ac8defSOliver Tappe 17*e3857211SAdrien Destugues #include <ICUWrapper.h> 18*e3857211SAdrien Destugues 19*e3857211SAdrien Destugues #include <unicode/datefmt.h> 20*e3857211SAdrien Destugues #include <unicode/smpdtfmt.h> 21*e3857211SAdrien Destugues 22*e3857211SAdrien Destugues 2338ac8defSOliver Tappe BDateTimeFormat::BDateTimeFormat() 2438ac8defSOliver Tappe : BFormat() 2538ac8defSOliver Tappe { 2638ac8defSOliver Tappe } 2738ac8defSOliver Tappe 28f3dd81abSOliver Tappe 2938ac8defSOliver Tappe BDateTimeFormat::BDateTimeFormat(const BDateTimeFormat &other) 3038ac8defSOliver Tappe : BFormat(other) 3138ac8defSOliver Tappe { 3238ac8defSOliver Tappe } 3338ac8defSOliver Tappe 34f3dd81abSOliver Tappe 3538ac8defSOliver Tappe BDateTimeFormat::~BDateTimeFormat() 3638ac8defSOliver Tappe { 3738ac8defSOliver Tappe } 3838ac8defSOliver Tappe 39f3dd81abSOliver Tappe 40*e3857211SAdrien Destugues // #pragma mark - Formatting 41*e3857211SAdrien Destugues 42*e3857211SAdrien Destugues 43*e3857211SAdrien Destugues ssize_t 44*e3857211SAdrien Destugues BDateTimeFormat::Format(char* target, size_t maxSize, time_t time, 45*e3857211SAdrien Destugues BDateFormatStyle dateStyle, BTimeFormatStyle timeStyle) const 4638ac8defSOliver Tappe { 47*e3857211SAdrien Destugues BAutolock lock(fLock); 48*e3857211SAdrien Destugues if (!lock.IsLocked()) 4938ac8defSOliver Tappe return B_ERROR; 50*e3857211SAdrien Destugues 51*e3857211SAdrien Destugues BString format; 52*e3857211SAdrien Destugues fConventions.GetDateFormat(dateStyle, format); 53*e3857211SAdrien Destugues ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format)); 54*e3857211SAdrien Destugues if (dateFormatter.Get() == NULL) 55*e3857211SAdrien Destugues return B_NO_MEMORY; 56*e3857211SAdrien Destugues 57*e3857211SAdrien Destugues fConventions.GetTimeFormat(timeStyle, format); 58*e3857211SAdrien Destugues ObjectDeleter<DateFormat> timeFormatter(_CreateTimeFormatter(format)); 59*e3857211SAdrien Destugues if (timeFormatter.Get() == NULL) 60*e3857211SAdrien Destugues return B_NO_MEMORY; 61*e3857211SAdrien Destugues 62*e3857211SAdrien Destugues UnicodeString icuString; 63*e3857211SAdrien Destugues dateFormatter->format((UDate)time * 1000, icuString); 64*e3857211SAdrien Destugues 65*e3857211SAdrien Destugues icuString.append(UnicodeString::fromUTF8(", ")); 66*e3857211SAdrien Destugues 67*e3857211SAdrien Destugues timeFormatter->format((UDate)time * 1000, icuString); 68*e3857211SAdrien Destugues 69*e3857211SAdrien Destugues CheckedArrayByteSink stringConverter(target, maxSize); 70*e3857211SAdrien Destugues icuString.toUTF8(stringConverter); 71*e3857211SAdrien Destugues 72*e3857211SAdrien Destugues if (stringConverter.Overflowed()) 73*e3857211SAdrien Destugues return B_BAD_VALUE; 74*e3857211SAdrien Destugues 75*e3857211SAdrien Destugues return stringConverter.NumberOfBytesWritten(); 76*e3857211SAdrien Destugues } 77*e3857211SAdrien Destugues 78*e3857211SAdrien Destugues 79*e3857211SAdrien Destugues status_t 80*e3857211SAdrien Destugues BDateTimeFormat::Format(BString& target, const time_t time, 81*e3857211SAdrien Destugues BDateFormatStyle dateStyle, BTimeFormatStyle timeStyle, 82*e3857211SAdrien Destugues const BTimeZone* timeZone) const 83*e3857211SAdrien Destugues { 84*e3857211SAdrien Destugues BAutolock lock(fLock); 85*e3857211SAdrien Destugues if (!lock.IsLocked()) 86*e3857211SAdrien Destugues return B_ERROR; 87*e3857211SAdrien Destugues 88*e3857211SAdrien Destugues BString format; 89*e3857211SAdrien Destugues fConventions.GetDateFormat(dateStyle, format); 90*e3857211SAdrien Destugues ObjectDeleter<DateFormat> dateFormatter(_CreateDateFormatter(format)); 91*e3857211SAdrien Destugues if (dateFormatter.Get() == NULL) 92*e3857211SAdrien Destugues return B_NO_MEMORY; 93*e3857211SAdrien Destugues 94*e3857211SAdrien Destugues fConventions.GetTimeFormat(timeStyle, format); 95*e3857211SAdrien Destugues ObjectDeleter<DateFormat> timeFormatter(_CreateTimeFormatter(format)); 96*e3857211SAdrien Destugues if (timeFormatter.Get() == NULL) 97*e3857211SAdrien Destugues return B_NO_MEMORY; 98*e3857211SAdrien Destugues 99*e3857211SAdrien Destugues if (timeZone != NULL) { 100*e3857211SAdrien Destugues ObjectDeleter<TimeZone> icuTimeZone( 101*e3857211SAdrien Destugues TimeZone::createTimeZone(timeZone->ID().String())); 102*e3857211SAdrien Destugues if (icuTimeZone.Get() == NULL) 103*e3857211SAdrien Destugues return B_NO_MEMORY; 104*e3857211SAdrien Destugues timeFormatter->setTimeZone(*icuTimeZone.Get()); 105*e3857211SAdrien Destugues } 106*e3857211SAdrien Destugues 107*e3857211SAdrien Destugues UnicodeString icuString; 108*e3857211SAdrien Destugues dateFormatter->format((UDate)time * 1000, icuString); 109*e3857211SAdrien Destugues icuString.append(UnicodeString::fromUTF8(", ")); 110*e3857211SAdrien Destugues timeFormatter->format((UDate)time * 1000, icuString); 111*e3857211SAdrien Destugues 112*e3857211SAdrien Destugues target.Truncate(0); 113*e3857211SAdrien Destugues BStringByteSink stringConverter(&target); 114*e3857211SAdrien Destugues icuString.toUTF8(stringConverter); 115*e3857211SAdrien Destugues 116*e3857211SAdrien Destugues return B_OK; 117*e3857211SAdrien Destugues } 118*e3857211SAdrien Destugues 119*e3857211SAdrien Destugues 120*e3857211SAdrien Destugues DateFormat* 121*e3857211SAdrien Destugues BDateTimeFormat::_CreateDateFormatter(const BString& format) const 122*e3857211SAdrien Destugues { 123*e3857211SAdrien Destugues Locale* icuLocale 124*e3857211SAdrien Destugues = fConventions.UseStringsFromPreferredLanguage() 125*e3857211SAdrien Destugues ? BLanguage::Private(&fLanguage).ICULocale() 126*e3857211SAdrien Destugues : BFormattingConventions::Private(&fConventions).ICULocale(); 127*e3857211SAdrien Destugues 128*e3857211SAdrien Destugues icu::DateFormat* dateFormatter 129*e3857211SAdrien Destugues = icu::DateFormat::createDateInstance(DateFormat::kShort, *icuLocale); 130*e3857211SAdrien Destugues if (dateFormatter == NULL) 131*e3857211SAdrien Destugues return NULL; 132*e3857211SAdrien Destugues 133*e3857211SAdrien Destugues SimpleDateFormat* dateFormatterImpl 134*e3857211SAdrien Destugues = static_cast<SimpleDateFormat*>(dateFormatter); 135*e3857211SAdrien Destugues 136*e3857211SAdrien Destugues UnicodeString pattern(format.String()); 137*e3857211SAdrien Destugues dateFormatterImpl->applyPattern(pattern); 138*e3857211SAdrien Destugues 139*e3857211SAdrien Destugues return dateFormatter; 140*e3857211SAdrien Destugues } 141*e3857211SAdrien Destugues 142*e3857211SAdrien Destugues 143*e3857211SAdrien Destugues DateFormat* 144*e3857211SAdrien Destugues BDateTimeFormat::_CreateTimeFormatter(const BString& format) const 145*e3857211SAdrien Destugues { 146*e3857211SAdrien Destugues Locale* icuLocale 147*e3857211SAdrien Destugues = fConventions.UseStringsFromPreferredLanguage() 148*e3857211SAdrien Destugues ? BLanguage::Private(&fLanguage).ICULocale() 149*e3857211SAdrien Destugues : BFormattingConventions::Private(&fConventions).ICULocale(); 150*e3857211SAdrien Destugues 151*e3857211SAdrien Destugues icu::DateFormat* timeFormatter 152*e3857211SAdrien Destugues = icu::DateFormat::createTimeInstance(DateFormat::kShort, *icuLocale); 153*e3857211SAdrien Destugues if (timeFormatter == NULL) 154*e3857211SAdrien Destugues return NULL; 155*e3857211SAdrien Destugues 156*e3857211SAdrien Destugues SimpleDateFormat* timeFormatterImpl 157*e3857211SAdrien Destugues = static_cast<SimpleDateFormat*>(timeFormatter); 158*e3857211SAdrien Destugues 159*e3857211SAdrien Destugues UnicodeString pattern(format.String()); 160*e3857211SAdrien Destugues timeFormatterImpl->applyPattern(pattern); 161*e3857211SAdrien Destugues 162*e3857211SAdrien Destugues return timeFormatter; 16338ac8defSOliver Tappe } 164