hrev51374 adds 1 changeset to branch 'master'
old head: 31e6a56fb383e5bfe95debe4fbdecf700c70b5eb
new head: 1e4ab34cd7fa368bfb8cb7f9a25c984e004e1344
overview:
http://cgit.haiku-os.org/haiku/log/?qt=range&q=1e4ab34cd7fa+%5E31e6a56fb383
----------------------------------------------------------------------------
1e4ab34cd7fa: Implement a formatter for relative dates.
Signed-off-by: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
It can give results such as "in 2 hours", "2 days ago", etc.
This is different from BDurationFormat which will just say "1 hour, 2
minute and 36 seconds"
[ Akshay Agarwal <agarwal.akshay.akshay8@xxxxxxxxx> ]
----------------------------------------------------------------------------
Revision: hrev51374
Commit: 1e4ab34cd7fa368bfb8cb7f9a25c984e004e1344
URL: http://cgit.haiku-os.org/haiku/commit/?id=1e4ab34cd7fa
Author: Akshay Agarwal <agarwal.akshay.akshay8@xxxxxxxxx>
Date: Thu Aug 24 07:17:00 2017 UTC
Committer: Adrien Destugues <pulkomandy@xxxxxxxxxxxxx>
Commit-Date: Fri Aug 25 19:14:27 2017 UTC
----------------------------------------------------------------------------
3 files changed, 208 insertions(+)
headers/os/locale/RelativeDateTimeFormat.h | 44 +++++++
src/kits/locale/Jamfile | 1 +
src/kits/locale/RelativeDateTimeFormat.cpp | 163 +++++++++++++++++++++++++
----------------------------------------------------------------------------
diff --git a/headers/os/locale/RelativeDateTimeFormat.h
b/headers/os/locale/RelativeDateTimeFormat.h
new file mode 100644
index 0000000..dce4866
--- /dev/null
+++ b/headers/os/locale/RelativeDateTimeFormat.h
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2017, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ * Akshay Agarwal <agarwal.akshay.akshay8@xxxxxxxxx>
+ */
+#ifndef _B_RELATIVE_DATE_TIME_FORMAT_H_
+#define _B_RELATIVE_DATE_TIME_FORMAT_H_
+
+
+#include <Format.h>
+#include <SupportDefs.h>
+
+
+class BString;
+
+#ifndef U_ICU_NAMESPACE
+ #define U_ICU_NAMESPACE icu
+#endif
+namespace U_ICU_NAMESPACE {
+ class GregorianCalendar;
+ class RelativeDateTimeFormatter;
+}
+
+
+class BRelativeDateTimeFormat: public BFormat {
+ typedef BFormat Inherited;
+public:
+
BRelativeDateTimeFormat();
+
BRelativeDateTimeFormat(const BLanguage& language,
+ const
BFormattingConventions& conventions);
+
BRelativeDateTimeFormat(const BRelativeDateTimeFormat& other);
+ virtual
~BRelativeDateTimeFormat();
+
+ status_t Format(BString& string,
const time_t timeValue) const;
+
+private:
+ U_ICU_NAMESPACE::RelativeDateTimeFormatter*
fFormatter;
+ U_ICU_NAMESPACE::GregorianCalendar* fCalendar;
+};
+
+
+#endif // _B_RELATIVE_DATE_TIME_FORMAT_H_
diff --git a/src/kits/locale/Jamfile b/src/kits/locale/Jamfile
index 73b7646..057687f 100644
--- a/src/kits/locale/Jamfile
+++ b/src/kits/locale/Jamfile
@@ -34,6 +34,7 @@ local sources =
TimeUnitFormat.cpp
Format.cpp # Used by some of the above.
UnicodeChar.cpp # Already used in FirstBootPrompt.
+ RelativeDateTimeFormat.cpp
;
local architectureObject ;
diff --git a/src/kits/locale/RelativeDateTimeFormat.cpp
b/src/kits/locale/RelativeDateTimeFormat.cpp
new file mode 100644
index 0000000..6b43885
--- /dev/null
+++ b/src/kits/locale/RelativeDateTimeFormat.cpp
@@ -0,0 +1,163 @@
+/*
+ * Copyright 2017, Haiku, Inc. All Rights Reserved.
+ * Distributed under the terms of the MIT License.
+ *
+ * Authors:
+ * Akshay Agarwal <agarwal.akshay.akshay8@xxxxxxxxx>
+ */
+
+
+#include <unicode/uversion.h>
+#include <RelativeDateTimeFormat.h>
+
+#include <stdlib.h>
+#include <time.h>
+
+#include <unicode/gregocal.h>
+#include <unicode/reldatefmt.h>
+#include <unicode/utypes.h>
+
+#include <ICUWrapper.h>
+
+#include <Language.h>
+#include <Locale.h>
+#include <LocaleRoster.h>
+#include <TimeUnitFormat.h>
+
+
+static const URelativeDateTimeUnit kTimeUnitToRelativeDateTime[] = {
+ UDAT_REL_UNIT_YEAR,
+ UDAT_REL_UNIT_MONTH,
+ UDAT_REL_UNIT_WEEK,
+ UDAT_REL_UNIT_DAY,
+ UDAT_REL_UNIT_HOUR,
+ UDAT_REL_UNIT_MINUTE,
+ UDAT_REL_UNIT_SECOND,
+};
+
+
+static const UCalendarDateFields kTimeUnitToICUDateField[] = {
+ UCAL_YEAR,
+ UCAL_MONTH,
+ UCAL_WEEK_OF_MONTH,
+ UCAL_DAY_OF_WEEK,
+ UCAL_HOUR_OF_DAY,
+ UCAL_MINUTE,
+ UCAL_SECOND,
+};
+
+
+BRelativeDateTimeFormat::BRelativeDateTimeFormat()
+ : Inherited()
+{
+ Locale icuLocale(fLanguage.Code());
+ UErrorCode icuStatus = U_ZERO_ERROR;
+
+ fFormatter = new RelativeDateTimeFormatter(icuLocale, icuStatus);
+ if (fFormatter == NULL) {
+ fInitStatus = B_NO_MEMORY;
+ return;
+ }
+
+ fCalendar = new GregorianCalendar(icuStatus);
+ if (fCalendar == NULL) {
+ fInitStatus = B_NO_MEMORY;
+ return;
+ }
+
+ if (!U_SUCCESS(icuStatus))
+ fInitStatus = B_ERROR;
+}
+
+
+BRelativeDateTimeFormat::BRelativeDateTimeFormat(const BLanguage& language,
+ const BFormattingConventions& conventions)
+ : Inherited(language, conventions)
+{
+ Locale icuLocale(fLanguage.Code());
+ UErrorCode icuStatus = U_ZERO_ERROR;
+
+ fFormatter = new RelativeDateTimeFormatter(icuLocale, icuStatus);
+ if (fFormatter == NULL) {
+ fInitStatus = B_NO_MEMORY;
+ return;
+ }
+
+ fCalendar = new GregorianCalendar(icuStatus);
+ if (fCalendar == NULL) {
+ fInitStatus = B_NO_MEMORY;
+ return;
+ }
+
+ if (!U_SUCCESS(icuStatus))
+ fInitStatus = B_ERROR;
+}
+
+
+BRelativeDateTimeFormat::BRelativeDateTimeFormat(const
BRelativeDateTimeFormat& other)
+ : Inherited(other),
+ fFormatter(other.fFormatter != NULL
+ ? new RelativeDateTimeFormatter(*other.fFormatter) : NULL),
+ fCalendar(other.fCalendar != NULL
+ ? new GregorianCalendar(*other.fCalendar) : NULL)
+{
+ if ((fFormatter == NULL && other.fFormatter != NULL)
+ || (fCalendar == NULL && other.fCalendar != NULL))
+ fInitStatus = B_NO_MEMORY;
+}
+
+
+BRelativeDateTimeFormat::~BRelativeDateTimeFormat()
+{
+ delete fFormatter;
+ delete fCalendar;
+}
+
+
+status_t
+BRelativeDateTimeFormat::Format(BString& string,
+ const time_t timeValue) const
+{
+ if (fFormatter == NULL)
+ return B_NO_INIT;
+
+ time_t currentTime = time(NULL);
+
+ UErrorCode icuStatus = U_ZERO_ERROR;
+ fCalendar->setTime((UDate)currentTime * 1000, icuStatus);
+ if (!U_SUCCESS(icuStatus))
+ return B_ERROR;
+
+ UDate UTimeValue = (UDate)timeValue * 1000;
+
+ int delta = 0;
+ int offset = 1;
+ URelativeDateTimeUnit unit = UDAT_REL_UNIT_SECOND;
+
+ for (int timeUnit = 0; timeUnit <= B_TIME_UNIT_LAST; ++timeUnit) {
+ delta = fCalendar->fieldDifference(UTimeValue,
+ kTimeUnitToICUDateField[timeUnit], icuStatus);
+
+ if (!U_SUCCESS(icuStatus))
+ return B_ERROR;
+
+ if (abs(delta) >= offset) {
+ unit = kTimeUnitToRelativeDateTime[timeUnit];
+ break;
+ }
+ }
+
+ UnicodeString unicodeResult;
+
+ // Note: icu::RelativeDateTimeFormatter::formatNumeric() is a part of
ICU Draft API
+ // and may be changed in the future versions and was introduced in ICU
57.
+ fFormatter->formatNumeric(delta, unit, unicodeResult, icuStatus);
+
+ if (!U_SUCCESS(icuStatus))
+ return B_ERROR;
+
+ BStringByteSink byteSink(&string);
+ unicodeResult.toUTF8(byteSink);
+
+ return B_OK;
+}