[gnome-maps/wip/mlundblad/redesign-opening-hours: 1/3] time: Add utility functions to format time strings




commit 99b790429e3687eb1e62c4a9a5814142e2134e10
Author: Marcus Lundblad <ml update uu se>
Date:   Mon Dec 14 23:18:24 2020 +0100

    time: Add utility functions to format time strings
    
    Add functions to format a time given a time relative
    to Epoch with a time zone offset and a function
    formatting time given hours and minutes.
    Also add unit tests for these.

 src/time.js       | 52 ++++++++++++++++++++++++++++++++++++++++++++
 tests/meson.build |  3 ++-
 tests/timeTest.js | 65 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 119 insertions(+), 1 deletion(-)
---
diff --git a/src/time.js b/src/time.js
index 4916a628..0c19400b 100644
--- a/src/time.js
+++ b/src/time.js
@@ -19,6 +19,8 @@
  * Author: Marcus Lundblad <ml update uu se>
  */
 
+const Gio = imports.gi.Gio;
+
 // allow using :, ., and the ratio symbol to separate hours:mins
 const _DELIMITERS = [':', '.', '\u2236'];
 
@@ -76,6 +78,21 @@ const _DIGIT_RANGE_BASES = [
     0x1c40
 ];
 
+// in org.gnome.desktop.interface
+const CLOCK_FORMAT_KEY = 'clock-format';
+
+let _desktopSettings = new Gio.Settings({ schema_id: 'org.gnome.desktop.interface' });
+let _clockFormat = _desktopSettings.get_string(CLOCK_FORMAT_KEY);
+
+const _timeFormat24 = new Intl.DateTimeFormat([], { hour:     '2-digit',
+                                                    minute:   '2-digit',
+                                                    hour12:   false,
+                                                    timeZone: 'UTC'});
+const _timeFormat12 = new Intl.DateTimeFormat([], { hour:     '2-digit',
+                                                    minute:   '2-digit',
+                                                    hour12:   true,
+                                                    timeZone: 'UTC'});
+
 /* parse a time from a fixed set of free-formats into a string representation:
  * hour:min
  *
@@ -158,3 +175,38 @@ function parseTimeString(timeString) {
         return null;
     }
 }
+
+function _is12Hour() {
+    return _clockFormat === '12h';
+}
+
+/**
+ * Format a time as HH:mm in either 12 or 24 h
+ * format depending on system settings
+ * given time in ms since Epoch with an offset in
+ * ms relative UTC.
+ */
+function formatTimeWithTZOffset(time, offset) {
+    let utcTimeWithOffset = time + offset;
+    let date = new Date();
+    let timeFormat = _is12Hour() ? _timeFormat12 : _timeFormat24;
+
+    date.setTime(utcTimeWithOffset);
+
+    return timeFormat.format(date);
+}
+
+/**
+ * Format a time as HH:mm in either 12 or 24 h
+ * format depending on system settings
+ * given hours and minutes values.
+ */
+function formatTimeFromHoursAndMins(hours, mins) {
+    let date = new Date();
+    let timeFormat = _is12Hour() ? _timeFormat12 : _timeFormat24;
+
+    date.setUTCHours(hours);
+    date.setUTCMinutes(mins);
+
+    return timeFormat.format(date);
+}
diff --git a/tests/meson.build b/tests/meson.build
index 551ade73..8731e906 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -1,4 +1,5 @@
-tests = ['addressTest', 'colorTest', 'osmNamesTest', 'utilsTest', 'urlsTest']
+tests = ['addressTest', 'colorTest', 'osmNamesTest', 'timeTest', 'utilsTest',
+         'urlsTest']
 
 foreach test : tests
   script_conf = configuration_data()
diff --git a/tests/timeTest.js b/tests/timeTest.js
new file mode 100644
index 00000000..50f3ab03
--- /dev/null
+++ b/tests/timeTest.js
@@ -0,0 +1,65 @@
+/* -*- Mode: JS2; indent-tabs-mode: nil; js2-basic-offset: 4 -*- */
+/* vim: set et ts=4 sw=4: */
+/*
+ * Copyright (c) 2020 Marcus Lundblad
+ *
+ * GNOME Maps is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by the
+ * Free Software Foundation; either version 2 of the License, or (at your
+ * option) any later version.
+ *
+ * GNOME Maps is distributed in the hope that it will be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
+ * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * for more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with GNOME Maps; if not, see <http://www.gnu.org/licenses/>.
+ *
+ * Author: Marcus Lundblad <ml update uu se>
+ */
+
+const JsUnit = imports.jsUnit;
+
+const Time = imports.time;
+
+function main() {
+  formatTimeWithTZOffsetTest();
+  formatTimeFromHoursAndMinsTest();
+}
+
+function formatTimeWithTZOffsetTest() {
+    // mock to always use 24 hour format
+    Time._is12Hour = function () { return false; };
+
+    JsUnit.assertEquals('22:54',
+                        Time.formatTimeWithTZOffset(1607982864000, 3600000));
+    JsUnit.assertEquals('21:54',
+                        Time.formatTimeWithTZOffset(1607982864000, 0));
+
+    // mock to always use 12 hour format
+    Time._is12Hour = function () { return true; };
+
+    JsUnit.assertEquals('10:54 PM',
+                        Time.formatTimeWithTZOffset(1607982864000, 3600000));
+    JsUnit.assertEquals('9:54 PM',
+                        Time.formatTimeWithTZOffset(1607982864000, 0));
+}
+
+function formatTimeFromHoursAndMinsTest() {
+    // mock to always use 24 hour format
+    Time._is12Hour = function () { return false; };
+
+    JsUnit.assertEquals('12:34', Time.formatTimeFromHoursAndMins(12, 34));
+    JsUnit.assertEquals('09:42', Time.formatTimeFromHoursAndMins(9, 42));
+    JsUnit.assertEquals('00:00', Time.formatTimeFromHoursAndMins(24, 0));
+    JsUnit.assertEquals('12:01', Time.formatTimeFromHoursAndMins(12, 1));
+
+    // mock to always use 12 hour format
+    Time._is12Hour = function () { return true; };
+
+    JsUnit.assertEquals('12:34 PM', Time.formatTimeFromHoursAndMins(12, 34));
+    JsUnit.assertEquals('9:42 AM', Time.formatTimeFromHoursAndMins(9, 42));
+    JsUnit.assertEquals('12:00 AM', Time.formatTimeFromHoursAndMins(24, 0));
+    JsUnit.assertEquals('12:01 PM', Time.formatTimeFromHoursAndMins(12, 1));
+}


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]