[haiku-commits] haiku: hrev51374 - src/kits/locale headers/os/locale

  • From: pulkomandy@xxxxxxxxxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 25 Aug 2017 21:37:17 +0200 (CEST)

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;
+}


Other related posts:

  • » [haiku-commits] haiku: hrev51374 - src/kits/locale headers/os/locale - pulkomandy