138ac8defSOliver Tappe /* 2e3857211SAdrien 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 11e3857211SAdrien Destugues #include <AutoDeleter.h> 12e3857211SAdrien Destugues #include <Autolock.h> 13e3857211SAdrien Destugues #include <FormattingConventionsPrivate.h> 14e3857211SAdrien Destugues #include <LanguagePrivate.h> 15e3857211SAdrien Destugues #include <TimeZone.h> 1638ac8defSOliver Tappe 17e3857211SAdrien Destugues #include <ICUWrapper.h> 18e3857211SAdrien Destugues 19e3857211SAdrien Destugues #include <unicode/datefmt.h> 20*4a3a4742SAdrien Destugues #include <unicode/dtptngen.h> 21e3857211SAdrien Destugues #include <unicode/smpdtfmt.h> 22e3857211SAdrien Destugues 23e3857211SAdrien Destugues 24*4a3a4742SAdrien Destugues BDateTimeFormat::BDateTimeFormat(const BLanguage* const language, 25*4a3a4742SAdrien Destugues const BFormattingConventions* const conventions) 2638ac8defSOliver Tappe { 27*4a3a4742SAdrien Destugues if (conventions != NULL) 28*4a3a4742SAdrien Destugues fConventions = *conventions; 29*4a3a4742SAdrien Destugues 30*4a3a4742SAdrien Destugues if (language != NULL) 31*4a3a4742SAdrien Destugues fLanguage = *language; 3238ac8defSOliver Tappe } 3338ac8defSOliver Tappe 34f3dd81abSOliver Tappe 3538ac8defSOliver Tappe BDateTimeFormat::BDateTimeFormat(const BDateTimeFormat &other) 3638ac8defSOliver Tappe : BFormat(other) 3738ac8defSOliver Tappe { 3838ac8defSOliver Tappe } 3938ac8defSOliver Tappe 40f3dd81abSOliver Tappe 4138ac8defSOliver Tappe BDateTimeFormat::~BDateTimeFormat() 4238ac8defSOliver Tappe { 4338ac8defSOliver Tappe } 4438ac8defSOliver Tappe 45f3dd81abSOliver Tappe 46*4a3a4742SAdrien Destugues void 47*4a3a4742SAdrien Destugues BDateTimeFormat::SetDateTimeFormat(BDateFormatStyle dateStyle, 48*4a3a4742SAdrien Destugues BTimeFormatStyle timeStyle, int32 elements) { 49*4a3a4742SAdrien Destugues UErrorCode error = U_ZERO_ERROR; 50*4a3a4742SAdrien Destugues DateTimePatternGenerator* generator 51*4a3a4742SAdrien Destugues = DateTimePatternGenerator::createInstance(error); 52*4a3a4742SAdrien Destugues 53*4a3a4742SAdrien Destugues BString skeleton; 54*4a3a4742SAdrien Destugues if (elements & B_DATE_ELEMENT_YEAR) 55*4a3a4742SAdrien Destugues skeleton << "yyyy"; 56*4a3a4742SAdrien Destugues if (elements & B_DATE_ELEMENT_MONTH) 57*4a3a4742SAdrien Destugues skeleton << "MM"; 58*4a3a4742SAdrien Destugues if (elements & B_DATE_ELEMENT_WEEKDAY) 59*4a3a4742SAdrien Destugues skeleton << "eee"; 60*4a3a4742SAdrien Destugues if (elements & B_DATE_ELEMENT_DAY) 61*4a3a4742SAdrien Destugues skeleton << "dd"; 62*4a3a4742SAdrien Destugues if (elements & B_DATE_ELEMENT_AM_PM) 63*4a3a4742SAdrien Destugues skeleton << "a"; 64*4a3a4742SAdrien Destugues if (elements & B_DATE_ELEMENT_HOUR) 65*4a3a4742SAdrien Destugues skeleton << "jj"; 66*4a3a4742SAdrien Destugues if (elements & B_DATE_ELEMENT_MINUTE) 67*4a3a4742SAdrien Destugues skeleton << "mm"; 68*4a3a4742SAdrien Destugues if (elements & B_DATE_ELEMENT_SECOND) 69*4a3a4742SAdrien Destugues skeleton << "ss"; 70*4a3a4742SAdrien Destugues if (elements & B_DATE_ELEMENT_TIMEZONE) 71*4a3a4742SAdrien Destugues skeleton << "V"; 72*4a3a4742SAdrien Destugues 73*4a3a4742SAdrien Destugues UnicodeString pattern = generator->getBestPattern( 74*4a3a4742SAdrien Destugues UnicodeString::fromUTF8(skeleton.String()), error); 75*4a3a4742SAdrien Destugues 76*4a3a4742SAdrien Destugues BString buffer; 77*4a3a4742SAdrien Destugues BStringByteSink stringConverter(&buffer); 78*4a3a4742SAdrien Destugues pattern.toUTF8(stringConverter); 79*4a3a4742SAdrien Destugues fConventions.SetExplicitDateTimeFormat(dateStyle, timeStyle, buffer); 80*4a3a4742SAdrien Destugues 81*4a3a4742SAdrien Destugues delete generator; 82*4a3a4742SAdrien Destugues } 83*4a3a4742SAdrien Destugues 84*4a3a4742SAdrien Destugues 85e3857211SAdrien Destugues // #pragma mark - Formatting 86e3857211SAdrien Destugues 87e3857211SAdrien Destugues 88e3857211SAdrien Destugues ssize_t 89e3857211SAdrien Destugues BDateTimeFormat::Format(char* target, size_t maxSize, time_t time, 90e3857211SAdrien Destugues BDateFormatStyle dateStyle, BTimeFormatStyle timeStyle) const 9138ac8defSOliver Tappe { 92e3857211SAdrien Destugues BAutolock lock(fLock); 93e3857211SAdrien Destugues if (!lock.IsLocked()) 9438ac8defSOliver Tappe return B_ERROR; 95e3857211SAdrien Destugues 96e3857211SAdrien Destugues BString format; 97*4a3a4742SAdrien Destugues fConventions.GetDateTimeFormat(dateStyle, timeStyle, format); 98*4a3a4742SAdrien Destugues ObjectDeleter<DateFormat> dateFormatter(_CreateDateTimeFormatter(format)); 99e3857211SAdrien Destugues if (dateFormatter.Get() == NULL) 100e3857211SAdrien Destugues return B_NO_MEMORY; 101e3857211SAdrien Destugues 102e3857211SAdrien Destugues UnicodeString icuString; 103e3857211SAdrien Destugues dateFormatter->format((UDate)time * 1000, icuString); 104e3857211SAdrien Destugues 105e3857211SAdrien Destugues CheckedArrayByteSink stringConverter(target, maxSize); 106e3857211SAdrien Destugues icuString.toUTF8(stringConverter); 107e3857211SAdrien Destugues 108e3857211SAdrien Destugues if (stringConverter.Overflowed()) 109e3857211SAdrien Destugues return B_BAD_VALUE; 110e3857211SAdrien Destugues 111e3857211SAdrien Destugues return stringConverter.NumberOfBytesWritten(); 112e3857211SAdrien Destugues } 113e3857211SAdrien Destugues 114e3857211SAdrien Destugues 115e3857211SAdrien Destugues status_t 116e3857211SAdrien Destugues BDateTimeFormat::Format(BString& target, const time_t time, 117e3857211SAdrien Destugues BDateFormatStyle dateStyle, BTimeFormatStyle timeStyle, 118e3857211SAdrien Destugues const BTimeZone* timeZone) const 119e3857211SAdrien Destugues { 120e3857211SAdrien Destugues BAutolock lock(fLock); 121e3857211SAdrien Destugues if (!lock.IsLocked()) 122e3857211SAdrien Destugues return B_ERROR; 123e3857211SAdrien Destugues 124e3857211SAdrien Destugues BString format; 125*4a3a4742SAdrien Destugues fConventions.GetDateTimeFormat(dateStyle, timeStyle, format); 126*4a3a4742SAdrien Destugues ObjectDeleter<DateFormat> dateFormatter(_CreateDateTimeFormatter(format)); 127e3857211SAdrien Destugues if (dateFormatter.Get() == NULL) 128e3857211SAdrien Destugues return B_NO_MEMORY; 129e3857211SAdrien Destugues 130e3857211SAdrien Destugues if (timeZone != NULL) { 131e3857211SAdrien Destugues ObjectDeleter<TimeZone> icuTimeZone( 132e3857211SAdrien Destugues TimeZone::createTimeZone(timeZone->ID().String())); 133e3857211SAdrien Destugues if (icuTimeZone.Get() == NULL) 134e3857211SAdrien Destugues return B_NO_MEMORY; 135*4a3a4742SAdrien Destugues dateFormatter->setTimeZone(*icuTimeZone.Get()); 136e3857211SAdrien Destugues } 137e3857211SAdrien Destugues 138e3857211SAdrien Destugues UnicodeString icuString; 139e3857211SAdrien Destugues dateFormatter->format((UDate)time * 1000, icuString); 140e3857211SAdrien Destugues 141e3857211SAdrien Destugues target.Truncate(0); 142e3857211SAdrien Destugues BStringByteSink stringConverter(&target); 143e3857211SAdrien Destugues icuString.toUTF8(stringConverter); 144e3857211SAdrien Destugues 145e3857211SAdrien Destugues return B_OK; 146e3857211SAdrien Destugues } 147e3857211SAdrien Destugues 148e3857211SAdrien Destugues 149e3857211SAdrien Destugues DateFormat* 150*4a3a4742SAdrien Destugues BDateTimeFormat::_CreateDateTimeFormatter(const BString& format) const 151e3857211SAdrien Destugues { 152e3857211SAdrien Destugues Locale* icuLocale 153e3857211SAdrien Destugues = fConventions.UseStringsFromPreferredLanguage() 154e3857211SAdrien Destugues ? BLanguage::Private(&fLanguage).ICULocale() 155e3857211SAdrien Destugues : BFormattingConventions::Private(&fConventions).ICULocale(); 156e3857211SAdrien Destugues 157*4a3a4742SAdrien Destugues icu::DateFormat* dateFormatter = icu::DateFormat::createDateTimeInstance( 158*4a3a4742SAdrien Destugues DateFormat::kDefault, DateFormat::kDefault, *icuLocale); 159e3857211SAdrien Destugues if (dateFormatter == NULL) 160e3857211SAdrien Destugues return NULL; 161e3857211SAdrien Destugues 162e3857211SAdrien Destugues SimpleDateFormat* dateFormatterImpl 163e3857211SAdrien Destugues = static_cast<SimpleDateFormat*>(dateFormatter); 164e3857211SAdrien Destugues 165e3857211SAdrien Destugues UnicodeString pattern(format.String()); 166e3857211SAdrien Destugues dateFormatterImpl->applyPattern(pattern); 167e3857211SAdrien Destugues 168e3857211SAdrien Destugues return dateFormatter; 169e3857211SAdrien Destugues } 170