From 4da0eab610b65766b72c55e4369dc79c002af4e0 Mon Sep 17 00:00:00 2001
From: Erdoan Hadzhiyusein <3rdoan@gmail.com>
Date: Wed, 13 Sep 2017 15:48:22 +0300
Subject: [PATCH] added time zone in the Paper UI and LocationProvider service
Signed-off-by: Erdoan Hadzhiyusein <3rdoan@gmail.com>
---
.../i18n/I18nConfigOptionsProvider.java | 56 ++++++++++++++++---
.../ESH-INF/config/i18n.xml | 8 +++
.../smarthome/core/i18n/TimeZoneProvider.java | 25 +++++++++
.../core/internal/i18n/I18nProviderImpl.java | 47 ++++++++++++----
.../discovery/AstroDiscoveryService.java | 1 -
5 files changed, 119 insertions(+), 18 deletions(-)
create mode 100644 bundles/core/org.eclipse.smarthome.core/src/main/java/org/eclipse/smarthome/core/i18n/TimeZoneProvider.java
diff --git a/bundles/config/org.eclipse.smarthome.config.core/src/main/java/org/eclipse/smarthome/config/core/internal/i18n/I18nConfigOptionsProvider.java b/bundles/config/org.eclipse.smarthome.config.core/src/main/java/org/eclipse/smarthome/config/core/internal/i18n/I18nConfigOptionsProvider.java
index 9a063c35df7..7e293ef3c89 100644
--- a/bundles/config/org.eclipse.smarthome.config.core/src/main/java/org/eclipse/smarthome/config/core/internal/i18n/I18nConfigOptionsProvider.java
+++ b/bundles/config/org.eclipse.smarthome.config.core/src/main/java/org/eclipse/smarthome/config/core/internal/i18n/I18nConfigOptionsProvider.java
@@ -8,10 +8,16 @@
package org.eclipse.smarthome.config.core.internal.i18n;
import java.net.URI;
+import java.time.ZoneId;
import java.util.Arrays;
import java.util.Collection;
+import java.util.Collections;
import java.util.Comparator;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Locale;
+import java.util.TimeZone;
+import java.util.concurrent.TimeUnit;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -23,29 +29,65 @@
* {@link ConfigOptionProvider} that provides a list of
*
* @author Simon Kaufmann - initial contribution and API
+ * @author Erdoan Hadzhiyusein - Added time zone
*
*/
@Component(immediate = true)
public class I18nConfigOptionsProvider implements ConfigOptionProvider {
+ private static final String NO_OFFSET_FORMAT = "(GMT) %s";
+ private static final String NEGATIVE_OFFSET_FORMAT = "%s (GMT%d:%02d)";
+ private static final String POSITIVE_OFFSET_FORMAT = "%s (GMT+%d:%02d)";
+
@Override
public Collection getParameterOptions(URI uri, String param, Locale locale) {
if (uri.toString().equals("system:i18n")) {
Locale translation = locale != null ? locale : Locale.getDefault();
- if (param.equals("language")) {
- return getAvailable(locale, l -> new ParameterOption(l.getLanguage(), l.getDisplayLanguage(translation)));
- } else if (param.equals("region")) {
- return getAvailable(locale, l -> new ParameterOption(l.getCountry(), l.getDisplayCountry(translation)));
- } else if (param.equals("variant")) {
- return getAvailable(locale, l -> new ParameterOption(l.getVariant(), l.getDisplayVariant(translation)));
+ switch (param) {
+ case "language":
+ return getAvailable(locale,
+ l -> new ParameterOption(l.getLanguage(), l.getDisplayLanguage(translation)));
+ case "region":
+ return getAvailable(locale,
+ l -> new ParameterOption(l.getCountry(), l.getDisplayCountry(translation)));
+ case "variant":
+ return getAvailable(locale,
+ l -> new ParameterOption(l.getVariant(), l.getDisplayVariant(translation)));
+ case "timezone":
+ Collection collection = new LinkedList();
+ Collection ids = ZoneId.getAvailableZoneIds();
+ List timeZones = ids.stream().map(TimeZone::getTimeZone)
+ .collect(Collectors.toList());
+ Collections.sort(timeZones, (s1, s2) -> s2.getRawOffset() - s1.getRawOffset());
+ // sorting the time zones by offset
+ for (TimeZone instance : timeZones) {
+ collection.add(new ParameterOption(instance.getID(), getTimeZoneRepresentation(instance)));
+ }
+ return collection;
+ default:
+ return null;
}
}
return null;
}
+ private static String getTimeZoneRepresentation(TimeZone tz) {
+ long hours = TimeUnit.MILLISECONDS.toHours(tz.getRawOffset());
+ long minutes = TimeUnit.MILLISECONDS.toMinutes(tz.getRawOffset()) - TimeUnit.HOURS.toMinutes(hours);
+ minutes = Math.abs(minutes);
+ final String result;
+ if (hours > 0) {
+ result = String.format(POSITIVE_OFFSET_FORMAT, tz.getID(), hours, minutes);
+ } else if (hours < 0) {
+ result = String.format(NEGATIVE_OFFSET_FORMAT, tz.getID(), hours, minutes);
+ } else {
+ result = String.format(NO_OFFSET_FORMAT, tz.getDisplayName(Locale.getDefault()));
+ }
+ return result;
+ }
+
private Collection getAvailable(Locale locale, Function mapFunction) {
return Arrays.stream(Locale.getAvailableLocales()).map(l -> mapFunction.apply(l)).distinct()
.sorted(Comparator.comparing(a -> a.getLabel())).collect(Collectors.toList());
}
-
}
diff --git a/bundles/core/org.eclipse.smarthome.core/ESH-INF/config/i18n.xml b/bundles/core/org.eclipse.smarthome.core/ESH-INF/config/i18n.xml
index ec510a49a30..bb092ebae7e 100644
--- a/bundles/core/org.eclipse.smarthome.core/ESH-INF/config/i18n.xml
+++ b/bundles/core/org.eclipse.smarthome.core/ESH-INF/config/i18n.xml
@@ -43,6 +43,14 @@
true
+
+
+ A time zone can be set from the dropdown menu.
+
The underlying system's time zone is the default.
+ ]]>
+
+
location
diff --git a/bundles/core/org.eclipse.smarthome.core/src/main/java/org/eclipse/smarthome/core/i18n/TimeZoneProvider.java b/bundles/core/org.eclipse.smarthome.core/src/main/java/org/eclipse/smarthome/core/i18n/TimeZoneProvider.java
new file mode 100644
index 00000000000..df26b9e90b0
--- /dev/null
+++ b/bundles/core/org.eclipse.smarthome.core/src/main/java/org/eclipse/smarthome/core/i18n/TimeZoneProvider.java
@@ -0,0 +1,25 @@
+/**
+ * Copyright (c) 2014-2017 by the respective copyright holders.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ */
+package org.eclipse.smarthome.core.i18n;
+
+import java.util.TimeZone;
+
+/**
+ * This interface describes a provider for a location and time zone.
+ *
+ * @author Erdoan Hadzhiyusein - Initial contribution and API
+ */
+public interface TimeZoneProvider {
+
+ /**
+ * Provides access to the time zone property.
+ *
+ * @return the time zone set in the Paper UI and if there isn't one, the default time zone of the underlying system
+ */
+ TimeZone getTimeZone();
+}
diff --git a/bundles/core/org.eclipse.smarthome.core/src/main/java/org/eclipse/smarthome/core/internal/i18n/I18nProviderImpl.java b/bundles/core/org.eclipse.smarthome.core/src/main/java/org/eclipse/smarthome/core/internal/i18n/I18nProviderImpl.java
index 37553b69ea5..9159b0e471c 100644
--- a/bundles/core/org.eclipse.smarthome.core/src/main/java/org/eclipse/smarthome/core/internal/i18n/I18nProviderImpl.java
+++ b/bundles/core/org.eclipse.smarthome.core/src/main/java/org/eclipse/smarthome/core/internal/i18n/I18nProviderImpl.java
@@ -11,10 +11,12 @@
import java.util.Locale;
import java.util.Map;
import java.util.ResourceBundle;
+import java.util.TimeZone;
import org.apache.commons.lang.StringUtils;
import org.eclipse.smarthome.core.i18n.LocaleProvider;
import org.eclipse.smarthome.core.i18n.LocationProvider;
+import org.eclipse.smarthome.core.i18n.TimeZoneProvider;
import org.eclipse.smarthome.core.i18n.TranslationProvider;
import org.eclipse.smarthome.core.library.types.PointType;
import org.osgi.framework.Bundle;
@@ -39,9 +41,10 @@
* @author Thomas Höfer - Added getText operation with arguments
* @author Markus Rathgeb - Initial contribution and API of LocaleProvider
* @author Stefan Triller - Initial contribution and API of LocationProvider
+ * @author Erdoan Hadzhiyusein - Added time zone
*
*/
-public class I18nProviderImpl implements TranslationProvider, LocaleProvider, LocationProvider {
+public class I18nProviderImpl implements TranslationProvider, LocaleProvider, LocationProvider, TimeZoneProvider {
private final Logger logger = LoggerFactory.getLogger(getClass());
@@ -50,6 +53,7 @@ public class I18nProviderImpl implements TranslationProvider, LocaleProvider, Lo
private static final String SCRIPT = "script";
private static final String REGION = "region";
private static final String VARIANT = "variant";
+ private static final String TIMEZONE = "timezone";
private Locale locale;
// TranslationProvider
@@ -58,6 +62,7 @@ public class I18nProviderImpl implements TranslationProvider, LocaleProvider, Lo
// LocationProvider
private static final String LOCATION = "location";
private PointType location;
+ private TimeZone timeZone;
@SuppressWarnings("unchecked")
protected void activate(ComponentContext componentContext) {
@@ -77,15 +82,10 @@ protected synchronized void modified(Map config) {
final String region = (String) config.get(REGION);
final String variant = (String) config.get(VARIANT);
final String location = (String) config.get(LOCATION);
+ final String timeZone = (String) config.get(TIMEZONE);
- if (location != null) {
- try {
- this.location = PointType.valueOf(location);
- } catch (IllegalArgumentException e) {
- // preserve old location or null if none was set before
- logger.warn("Could not set new location, keeping old one: ", e.getMessage());
- }
- }
+ setTimeZone(timeZone);
+ setLocation(location);
if (StringUtils.isEmpty(language)) {
// at least the language must be defined otherwise the system default locale is used
@@ -125,7 +125,29 @@ protected synchronized void modified(Map config) {
locale = builder.build();
- logger.info("Locale set to {}, Location set to {}", locale, this.location);
+ logger.info("Locale set to {}, Location set to {}, Time zone set to {}", locale, this.location, this.timeZone);
+ }
+
+ private void setLocation(final String location) {
+ if (location != null) {
+ try {
+ this.location = PointType.valueOf(location);
+ } catch (IllegalArgumentException e) {
+ // preserve old location or null if none was set before
+ logger.warn("Could not set new location, keeping old one: ", e);
+ }
+ }
+ }
+
+ private void setTimeZone(final String timeZone) {
+ if (timeZone != null) {
+ try {
+ this.timeZone = TimeZone.getTimeZone(timeZone);
+ } catch (IllegalArgumentException e) {
+ this.timeZone = TimeZone.getDefault();
+ logger.warn("Could not set a new timezone, the system's default time zone will be used ", e);
+ }
+ }
}
@Override
@@ -133,6 +155,11 @@ public PointType getLocation() {
return location;
}
+ @Override
+ public TimeZone getTimeZone() {
+ return this.timeZone;
+ }
+
@Override
public Locale getLocale() {
if (locale == null) {
diff --git a/extensions/binding/org.eclipse.smarthome.binding.astro/src/main/java/org/eclipse/smarthome/binding/astro/discovery/AstroDiscoveryService.java b/extensions/binding/org.eclipse.smarthome.binding.astro/src/main/java/org/eclipse/smarthome/binding/astro/discovery/AstroDiscoveryService.java
index 672fffe46c9..5a290b6590a 100644
--- a/extensions/binding/org.eclipse.smarthome.binding.astro/src/main/java/org/eclipse/smarthome/binding/astro/discovery/AstroDiscoveryService.java
+++ b/extensions/binding/org.eclipse.smarthome.binding.astro/src/main/java/org/eclipse/smarthome/binding/astro/discovery/AstroDiscoveryService.java
@@ -118,5 +118,4 @@ protected void setLocationProvider(LocationProvider locationProvider) {
protected void unsetLocationProvider(LocationProvider locationProvider) {
this.locationProvider = null;
}
-
}