[Astro] Removing org.apache.commons.* (#11327)

* Removing org.apache.commons.*
Some code cleansing

Signed-off-by: Gaël L'hopital <gael@lhopital.org>

* Some more code cleansing.

Signed-off-by: Gaël L'hopital <gael@lhopital.org>

* Satisfy integration tests

Signed-off-by: Gaël L'hopital <gael@lhopital.org>

* Taking in account @lolodomo feed-back

Signed-off-by: Gaël L'hopital <gael@lhopital.org>
This commit is contained in:
Gaël L'hopital 2021-10-02 14:16:23 +02:00 committed by GitHub
parent 1b80f1d492
commit b1f412377f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 97 additions and 83 deletions

View File

@ -32,8 +32,8 @@ public final class AstroBindingConstants {
public static final String BINDING_ID = "astro"; public static final String BINDING_ID = "astro";
public static final String SUN = "sun"; private static final String SUN = "sun";
public static final String MOON = "moon"; private static final String MOON = "moon";
public static final String LOCAL = "local"; public static final String LOCAL = "local";
// things // things

View File

@ -17,8 +17,6 @@ import static org.openhab.binding.astro.internal.AstroBindingConstants.*;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
@ -45,9 +43,7 @@ import org.osgi.service.component.annotations.Reference;
@Component(configurationPid = "binding.astro", service = ThingHandlerFactory.class) @Component(configurationPid = "binding.astro", service = ThingHandlerFactory.class)
public class AstroHandlerFactory extends BaseThingHandlerFactory { public class AstroHandlerFactory extends BaseThingHandlerFactory {
private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Stream private static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = Set.of(THING_TYPE_SUN, THING_TYPE_MOON);
.concat(SunHandler.SUPPORTED_THING_TYPES.stream(), MoonHandler.SUPPORTED_THING_TYPES.stream())
.collect(Collectors.toSet());
private static final Map<String, AstroThingHandler> ASTRO_THING_HANDLERS = new HashMap<>(); private static final Map<String, AstroThingHandler> ASTRO_THING_HANDLERS = new HashMap<>();
private final CronScheduler scheduler; private final CronScheduler scheduler;
private final TimeZoneProvider timeZoneProvider; private final TimeZoneProvider timeZoneProvider;

View File

@ -42,7 +42,7 @@ import org.slf4j.LoggerFactory;
public class AstroActions implements ThingActions { public class AstroActions implements ThingActions {
private final Logger logger = LoggerFactory.getLogger(AstroActions.class); private final Logger logger = LoggerFactory.getLogger(AstroActions.class);
protected @Nullable AstroThingHandler handler; private @Nullable AstroThingHandler handler;
public AstroActions() { public AstroActions() {
logger.debug("Astro actions service instanciated"); logger.debug("Astro actions service instanciated");

View File

@ -391,7 +391,7 @@ public class MoonCalc {
/** /**
* Calculates the previous moon phase. * Calculates the previous moon phase.
*/ */
public double getPreviousPhase(Calendar cal, double jd, double mode) { private double getPreviousPhase(Calendar cal, double jd, double mode) {
double tz = 0; double tz = 0;
double phaseJd = 0; double phaseJd = 0;
do { do {
@ -494,7 +494,7 @@ public class MoonCalc {
return sr; return sr;
} }
public double[] calcMoon(double t) { private double[] calcMoon(double t) {
double p2 = 6.283185307; double p2 = 6.283185307;
double arc = 206264.8062; double arc = 206264.8062;
double coseps = .91748; double coseps = .91748;

View File

@ -90,7 +90,7 @@ public class SunCalc {
/** /**
* Calculates sun radiation data. * Calculates sun radiation data.
*/ */
public void setRadiationInfo(Calendar calendar, double elevation, Double altitude, Sun sun) { private void setRadiationInfo(Calendar calendar, double elevation, Double altitude, Sun sun) {
double sinAlpha = Math.sin(DEG2RAD * elevation); double sinAlpha = Math.sin(DEG2RAD * elevation);
int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR); int dayOfYear = calendar.get(Calendar.DAY_OF_YEAR);

View File

@ -22,6 +22,8 @@ import org.eclipse.jdt.annotation.Nullable;
*/ */
@NonNullByDefault @NonNullByDefault
public class AstroThingConfig { public class AstroThingConfig {
public static final String GEOLOCATION = "geolocation";
public static final String USE_METEOROLOGICAL_SEASON = "useMeteorologicalSeason";
public @Nullable String geolocation; public @Nullable String geolocation;
public @Nullable Double altitude; public @Nullable Double altitude;
public @Nullable Double latitude; public @Nullable Double latitude;
@ -35,12 +37,11 @@ public class AstroThingConfig {
public void parseGeoLocation() { public void parseGeoLocation() {
if (geolocation != null) { if (geolocation != null) {
String[] geoParts = geolocation.split(","); String[] geoParts = geolocation.split(",");
if (geoParts.length == 2) { if (geoParts.length >= 2) {
latitude = toDouble(geoParts[0]);
longitude = toDouble(geoParts[1]);
} else if (geoParts.length == 3) {
latitude = toDouble(geoParts[0]); latitude = toDouble(geoParts[0]);
longitude = toDouble(geoParts[1]); longitude = toDouble(geoParts[1]);
}
if (geoParts.length == 3) {
altitude = toDouble(geoParts[2]); altitude = toDouble(geoParts[2]);
} }
} }

View File

@ -13,6 +13,7 @@
package org.openhab.binding.astro.internal.discovery; package org.openhab.binding.astro.internal.discovery;
import static org.openhab.binding.astro.internal.AstroBindingConstants.*; import static org.openhab.binding.astro.internal.AstroBindingConstants.*;
import static org.openhab.binding.astro.internal.config.AstroThingConfig.*;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet; import java.util.HashSet;
@ -50,7 +51,7 @@ import org.slf4j.LoggerFactory;
public class AstroDiscoveryService extends AbstractDiscoveryService { public class AstroDiscoveryService extends AbstractDiscoveryService {
private static final int DISCOVER_TIMEOUT_SECONDS = 2; private static final int DISCOVER_TIMEOUT_SECONDS = 2;
private static final int LOCATION_CHANGED_CHECK_INTERVAL = 60; private static final int LOCATION_CHANGED_CHECK_INTERVAL = 60;
private static final Set<String> METEO_BASED_COUNTRIES = new HashSet<>(Arrays.asList("NZ", "AU")); private static final Set<String> METEO_BASED_COUNTRIES = Set.of("NZ", "AU");
private static final ThingUID SUN_THING = new ThingUID(THING_TYPE_SUN, LOCAL); private static final ThingUID SUN_THING = new ThingUID(THING_TYPE_SUN, LOCAL);
private static final ThingUID MOON_THING = new ThingUID(THING_TYPE_MOON, LOCAL); private static final ThingUID MOON_THING = new ThingUID(THING_TYPE_MOON, LOCAL);
@ -110,15 +111,15 @@ public class AstroDiscoveryService extends AbstractDiscoveryService {
} }
public void createResults(PointType location) { public void createResults(PointType location) {
String propGeolocation; String propGeolocation = location.toString();
String country = localeProvider.getLocale().getCountry(); String country = localeProvider.getLocale().getCountry();
propGeolocation = String.format("%s,%s,%s", location.getLatitude(), location.getLongitude(),
location.getAltitude());
thingDiscovered(DiscoveryResultBuilder.create(SUN_THING).withLabel("Local Sun") thingDiscovered(DiscoveryResultBuilder.create(SUN_THING).withLabel("Local Sun")
.withProperty("geolocation", propGeolocation) .withProperty(GEOLOCATION, propGeolocation)
.withProperty("useMeteorologicalSeason", METEO_BASED_COUNTRIES.contains(country)) .withProperty(USE_METEOROLOGICAL_SEASON, METEO_BASED_COUNTRIES.contains(country))
.withRepresentationProperty("geolocation").build()); .withRepresentationProperty(GEOLOCATION).build());
thingDiscovered(DiscoveryResultBuilder.create(MOON_THING).withLabel("Local Moon") thingDiscovered(DiscoveryResultBuilder.create(MOON_THING).withLabel("Local Moon")
.withProperty("geolocation", propGeolocation).withRepresentationProperty("geolocation").build()); .withProperty(GEOLOCATION, propGeolocation).withRepresentationProperty(GEOLOCATION).build());
} }
} }

View File

@ -17,6 +17,7 @@ import static org.openhab.core.thing.type.ChannelKind.TRIGGER;
import static org.openhab.core.types.RefreshType.REFRESH; import static org.openhab.core.types.RefreshType.REFRESH;
import java.lang.invoke.MethodHandles; import java.lang.invoke.MethodHandles;
import java.text.SimpleDateFormat;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.Arrays; import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
@ -34,7 +35,6 @@ import java.util.concurrent.locks.ReentrantLock;
import javax.measure.quantity.Angle; import javax.measure.quantity.Angle;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
import org.openhab.binding.astro.internal.action.AstroActions; import org.openhab.binding.astro.internal.action.AstroActions;
@ -67,11 +67,11 @@ import org.slf4j.LoggerFactory;
*/ */
@NonNullByDefault @NonNullByDefault
public abstract class AstroThingHandler extends BaseThingHandler { public abstract class AstroThingHandler extends BaseThingHandler {
private static final String DAILY_MIDNIGHT = "30 0 0 * * ? *"; private static final String DAILY_MIDNIGHT = "30 0 0 * * ? *";
/** Logger Instance */ /** Logger Instance */
protected final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass()); private final Logger logger = LoggerFactory.getLogger(MethodHandles.lookup().lookupClass());
private final SimpleDateFormat isoFormatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
/** Scheduler to schedule jobs */ /** Scheduler to schedule jobs */
private final CronScheduler cronScheduler; private final CronScheduler cronScheduler;
@ -310,7 +310,7 @@ public abstract class AstroThingHandler extends BaseThingHandler {
monitor.unlock(); monitor.unlock();
} }
if (logger.isDebugEnabled()) { if (logger.isDebugEnabled()) {
String formattedDate = DateFormatUtils.ISO_DATETIME_FORMAT.format(eventAt); String formattedDate = this.isoFormatter.format(eventAt);
logger.debug("Scheduled {} in {}ms (at {})", job, sleepTime, formattedDate); logger.debug("Scheduled {} in {}ms (at {})", job, sleepTime, formattedDate);
} }
} }

View File

@ -12,14 +12,9 @@
*/ */
package org.openhab.binding.astro.internal.handler; package org.openhab.binding.astro.internal.handler;
import static org.openhab.binding.astro.internal.AstroBindingConstants.THING_TYPE_MOON;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
@ -32,7 +27,6 @@ import org.openhab.binding.astro.internal.model.Position;
import org.openhab.core.i18n.TimeZoneProvider; import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.scheduler.CronScheduler; import org.openhab.core.scheduler.CronScheduler;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
/** /**
* The MoonHandler is responsible for updating calculated moon data. * The MoonHandler is responsible for updating calculated moon data.
@ -43,8 +37,6 @@ import org.openhab.core.thing.ThingTypeUID;
@NonNullByDefault @NonNullByDefault
public class MoonHandler extends AstroThingHandler { public class MoonHandler extends AstroThingHandler {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(Arrays.asList(THING_TYPE_MOON));
private final String[] positionalChannelIds = new String[] { "phase#name", "phase#age", "phase#agePercent", private final String[] positionalChannelIds = new String[] { "phase#name", "phase#age", "phase#agePercent",
"phase#ageDegree", "phase#illumination", "position#azimuth", "position#elevation", "zodiac#sign" }; "phase#ageDegree", "phase#illumination", "position#azimuth", "position#elevation", "zodiac#sign" };
private final MoonCalc moonCalc = new MoonCalc(); private final MoonCalc moonCalc = new MoonCalc();

View File

@ -12,14 +12,9 @@
*/ */
package org.openhab.binding.astro.internal.handler; package org.openhab.binding.astro.internal.handler;
import static org.openhab.binding.astro.internal.AstroBindingConstants.THING_TYPE_SUN;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Calendar; import java.util.Calendar;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNullByDefault; import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable; import org.eclipse.jdt.annotation.Nullable;
@ -34,7 +29,6 @@ import org.openhab.binding.astro.internal.model.SunPhaseName;
import org.openhab.core.i18n.TimeZoneProvider; import org.openhab.core.i18n.TimeZoneProvider;
import org.openhab.core.scheduler.CronScheduler; import org.openhab.core.scheduler.CronScheduler;
import org.openhab.core.thing.Thing; import org.openhab.core.thing.Thing;
import org.openhab.core.thing.ThingTypeUID;
/** /**
* The SunHandler is responsible for updating calculated sun data. * The SunHandler is responsible for updating calculated sun data.
@ -45,8 +39,6 @@ import org.openhab.core.thing.ThingTypeUID;
@NonNullByDefault @NonNullByDefault
public class SunHandler extends AstroThingHandler { public class SunHandler extends AstroThingHandler {
public static final Set<ThingTypeUID> SUPPORTED_THING_TYPES = new HashSet<>(Arrays.asList(THING_TYPE_SUN));
private final String[] positionalChannelIds = new String[] { "position#azimuth", "position#elevation", private final String[] positionalChannelIds = new String[] { "position#azimuth", "position#elevation",
"radiation#direct", "radiation#diffuse", "radiation#total" }; "radiation#direct", "radiation#diffuse", "radiation#total" };
private final SunCalc sunCalc = new SunCalc(); private final SunCalc sunCalc = new SunCalc();

View File

@ -12,11 +12,8 @@
*/ */
package org.openhab.binding.astro.internal.job; package org.openhab.binding.astro.internal.job;
import static java.util.Arrays.asList;
import static java.util.Calendar.SECOND;
import static java.util.Collections.singletonList; import static java.util.Collections.singletonList;
import static java.util.stream.Collectors.toList; import static java.util.stream.Collectors.toList;
import static org.apache.commons.lang3.time.DateUtils.truncatedEquals;
import static org.openhab.binding.astro.internal.AstroBindingConstants.*; import static org.openhab.binding.astro.internal.AstroBindingConstants.*;
import static org.openhab.binding.astro.internal.util.DateTimeUtils.*; import static org.openhab.binding.astro.internal.util.DateTimeUtils.*;
@ -132,16 +129,12 @@ public interface Job extends SchedulerRunnable, Runnable {
return; return;
} }
AstroChannelConfig config = channel.getConfiguration().as(AstroChannelConfig.class); AstroChannelConfig config = channel.getConfiguration().as(AstroChannelConfig.class);
Calendar configStart = applyConfig(start, config); Calendar configStart = truncateToSecond(applyConfig(start, config));
Calendar configEnd = applyConfig(end, config); Calendar configEnd = truncateToSecond(applyConfig(end, config));
if (truncatedEquals(configStart, configEnd, SECOND)) {
scheduleEvent(thingUID, astroHandler, configStart, asList(EVENT_START, EVENT_END), channelId, true);
} else {
scheduleEvent(thingUID, astroHandler, configStart, EVENT_START, channelId, true); scheduleEvent(thingUID, astroHandler, configStart, EVENT_START, channelId, true);
scheduleEvent(thingUID, astroHandler, configEnd, EVENT_END, channelId, true); scheduleEvent(thingUID, astroHandler, configEnd, EVENT_END, channelId, true);
} }
}
/** /**
* Schedules Planet events * Schedules Planet events

View File

@ -14,6 +14,7 @@ package org.openhab.binding.astro.internal.model;
import javax.measure.quantity.Angle; import javax.measure.quantity.Angle;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.openhab.core.library.types.QuantityType; import org.openhab.core.library.types.QuantityType;
import org.openhab.core.library.unit.Units; import org.openhab.core.library.unit.Units;
@ -24,6 +25,7 @@ import org.openhab.core.library.unit.Units;
* @author Gaël L'hopital - Added shade length * @author Gaël L'hopital - Added shade length
* @author Christoph Weitkamp - Introduced UoM * @author Christoph Weitkamp - Introduced UoM
*/ */
@NonNullByDefault
public class Position { public class Position {
private double azimuth; private double azimuth;

View File

@ -12,11 +12,14 @@
*/ */
package org.openhab.binding.astro.internal.model; package org.openhab.binding.astro.internal.model;
import org.eclipse.jdt.annotation.NonNullByDefault;
/** /**
* All sun phases. * All sun phases.
* *
* @author Gerhard Riegler - Initial contribution * @author Gerhard Riegler - Initial contribution
*/ */
@NonNullByDefault
public enum SunPhaseName { public enum SunPhaseName {
SUN_RISE, SUN_RISE,
ASTRO_DAWN, ASTRO_DAWN,

View File

@ -12,11 +12,14 @@
*/ */
package org.openhab.binding.astro.internal.model; package org.openhab.binding.astro.internal.model;
import org.eclipse.jdt.annotation.NonNullByDefault;
/** /**
* All zodiac signs. * All zodiac signs.
* *
* @author Gerhard Riegler - Initial contribution * @author Gerhard Riegler - Initial contribution
*/ */
@NonNullByDefault
public enum ZodiacSign { public enum ZodiacSign {
ARIES, ARIES,
TAURUS, TAURUS,

View File

@ -13,10 +13,8 @@
package org.openhab.binding.astro.internal.util; package org.openhab.binding.astro.internal.util;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import org.apache.commons.lang3.time.DateUtils;
import org.openhab.binding.astro.internal.config.AstroChannelConfig; import org.openhab.binding.astro.internal.config.AstroChannelConfig;
import org.openhab.binding.astro.internal.model.Range; import org.openhab.binding.astro.internal.model.Range;
import org.slf4j.Logger; import org.slf4j.Logger;
@ -31,19 +29,40 @@ public class DateTimeUtils {
private static final Logger LOGGER = LoggerFactory.getLogger(DateTimeUtils.class); private static final Logger LOGGER = LoggerFactory.getLogger(DateTimeUtils.class);
private static final Pattern HHMM_PATTERN = Pattern.compile("^([0-1][0-9]|2[0-3])(:[0-5][0-9])$"); private static final Pattern HHMM_PATTERN = Pattern.compile("^([0-1][0-9]|2[0-3])(:[0-5][0-9])$");
public static final double J1970 = 2440588.0; private static final double J1970 = 2440588.0;
public static final double MILLISECONDS_PER_DAY = 1000 * 60 * 60 * 24; private static final double MILLISECONDS_PER_DAY = 1000 * 60 * 60 * 24;
/** Constructor */ /** Constructor */
private DateTimeUtils() { private DateTimeUtils() {
throw new IllegalAccessError("Non-instantiable"); throw new IllegalAccessError("Non-instantiable");
} }
/**
* Truncates the time from the calendar object.
*/
public static Calendar truncateToSecond(Calendar calendar) {
Calendar cal = (Calendar) calendar.clone();
cal.set(Calendar.MILLISECOND, 0);
return cal;
}
/**
* Truncates the time from the calendar object.
*/
private static Calendar truncateToMinute(Calendar calendar) {
Calendar cal = truncateToSecond(calendar);
cal.set(Calendar.SECOND, 0);
return cal;
}
/** /**
* Truncates the time from the calendar object. * Truncates the time from the calendar object.
*/ */
public static Calendar truncateToMidnight(Calendar calendar) { public static Calendar truncateToMidnight(Calendar calendar) {
return DateUtils.truncate(calendar, Calendar.DAY_OF_MONTH); Calendar cal = truncateToMinute(calendar);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
return cal;
} }
/** /**
@ -79,7 +98,11 @@ public class DateTimeUtils {
long millis = (long) ((julianDate + 0.5 - J1970) * MILLISECONDS_PER_DAY); long millis = (long) ((julianDate + 0.5 - J1970) * MILLISECONDS_PER_DAY);
Calendar cal = Calendar.getInstance(); Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(millis); cal.setTimeInMillis(millis);
return DateUtils.round(cal, Calendar.MINUTE); int second = cal.get(Calendar.SECOND);
if (second > 30) {
cal.add(Calendar.MINUTE, 1);
}
return truncateToMinute(cal);
} }
/** /**
@ -100,8 +123,8 @@ public class DateTimeUtils {
* Returns the end of day from the calendar object. * Returns the end of day from the calendar object.
*/ */
public static Calendar endOfDayDate(Calendar calendar) { public static Calendar endOfDayDate(Calendar calendar) {
Calendar cal = (Calendar) calendar.clone(); Calendar cal = truncateToMidnight(calendar);
cal = DateUtils.ceiling(cal, Calendar.DATE); cal.add(Calendar.DATE, 1);
cal.add(Calendar.MILLISECOND, -1); cal.add(Calendar.MILLISECOND, -1);
return cal; return cal;
} }
@ -139,21 +162,16 @@ public class DateTimeUtils {
} }
cal.set(Calendar.HOUR_OF_DAY, hour); cal.set(Calendar.HOUR_OF_DAY, hour);
cal.set(Calendar.MINUTE, minute); cal.set(Calendar.MINUTE, minute);
return DateUtils.truncate(cal, Calendar.MINUTE); return truncateToMinute(cal);
} }
/** /**
* Returns true, if two calendar objects are on the same day ignoring time. * Returns true, if two calendar objects are on the same day ignoring time.
*/ */
public static boolean isSameDay(Calendar cal1, Calendar cal2) { public static boolean isSameDay(Calendar cal1, Calendar cal2) {
return cal1 != null && cal2 != null && DateUtils.isSameDay(cal1, cal2); return cal1 != null && cal2 != null && cal1.get(Calendar.ERA) == cal2.get(Calendar.ERA)
} && cal1.get(Calendar.YEAR) == cal2.get(Calendar.YEAR)
&& cal1.get(Calendar.DAY_OF_YEAR) == cal2.get(Calendar.DAY_OF_YEAR);
/**
* Returns a date object from a calendar.
*/
public static Date getDate(Calendar calendar) {
return calendar == null ? null : calendar.getTime();
} }
/** /**
@ -181,8 +199,8 @@ public class DateTimeUtils {
* Returns true, if cal1 is greater or equal than cal2, ignoring seconds. * Returns true, if cal1 is greater or equal than cal2, ignoring seconds.
*/ */
public static boolean isTimeGreaterEquals(Calendar cal1, Calendar cal2) { public static boolean isTimeGreaterEquals(Calendar cal1, Calendar cal2) {
Calendar truncCal1 = DateUtils.truncate(cal1, Calendar.MINUTE); Calendar truncCal1 = truncateToMinute(cal1);
Calendar truncCal2 = DateUtils.truncate(cal2, Calendar.MINUTE); Calendar truncCal2 = truncateToMinute(cal2);
return truncCal1.getTimeInMillis() >= truncCal2.getTimeInMillis(); return truncCal1.getTimeInMillis() >= truncCal2.getTimeInMillis();
} }
@ -212,8 +230,7 @@ public class DateTimeUtils {
private static Calendar adjustTime(Calendar cal, int minutes) { private static Calendar adjustTime(Calendar cal, int minutes) {
if (minutes > 0) { if (minutes > 0) {
Calendar cTime = Calendar.getInstance(); Calendar cTime = truncateToMidnight(cal);
cTime = DateUtils.truncate(cal, Calendar.DAY_OF_MONTH);
cTime.add(Calendar.MINUTE, minutes); cTime.add(Calendar.MINUTE, minutes);
return cTime; return cTime;
} }

View File

@ -17,8 +17,10 @@ import java.math.BigDecimal;
import java.math.RoundingMode; import java.math.RoundingMode;
import java.time.ZoneId; import java.time.ZoneId;
import java.time.ZonedDateTime; import java.time.ZonedDateTime;
import java.util.ArrayList;
import java.util.Calendar; import java.util.Calendar;
import java.util.GregorianCalendar; import java.util.GregorianCalendar;
import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.TimeZone; import java.util.TimeZone;
@ -77,23 +79,22 @@ public class PropertyUtils {
* Returns the property value from the object instance, nested properties are possible. If the propertyName is for * Returns the property value from the object instance, nested properties are possible. If the propertyName is for
* example rise.start, the methods getRise().getStart() are called. * example rise.start, the methods getRise().getStart() are called.
*/ */
public static @Nullable Object getPropertyValue(ChannelUID channelUID, Object instance) throws Exception { private static @Nullable Object getPropertyValue(ChannelUID channelUID, Object instance) throws Exception {
String[] properties = channelUID.getId().split("#"); ArrayList<String> properties = new ArrayList<>(List.of(channelUID.getId().split("#")));
return getPropertyValue(instance, properties, 0); return getPropertyValue(instance, properties);
} }
/** /**
* Iterates through the nested properties and returns the getter value. * Iterates through the nested properties and returns the getter value.
*/ */
@SuppressWarnings("all") @SuppressWarnings("all")
private static @Nullable Object getPropertyValue(Object instance, String[] properties, int nestedIndex) private static @Nullable Object getPropertyValue(Object instance, List<String> properties) throws Exception {
throws Exception { String propertyName = properties.remove(0);
String propertyName = properties[nestedIndex];
Method m = instance.getClass().getMethod(toGetterString(propertyName), null); Method m = instance.getClass().getMethod(toGetterString(propertyName), null);
Object result = m.invoke(instance, (Object[]) null); Object result = m.invoke(instance, (Object[]) null);
if (nestedIndex + 1 < properties.length) { if (!properties.isEmpty()) {
Objects.requireNonNull(result); Objects.requireNonNull(result);
return getPropertyValue(result, properties, nestedIndex + 1); return getPropertyValue(result, properties);
} }
return result; return result;
} }

View File

@ -63,6 +63,19 @@ public class DateTimeUtilsTest {
assertNextSeason(season.getAutumn(), DEC_10_2020, season); assertNextSeason(season.getAutumn(), DEC_10_2020, season);
} }
@Test
void testTruncate() {
Calendar cal = newCalendar(2021, 9, 30, 11, 54, TIME_ZONE);
Calendar target = newCalendar(2021, 9, 30, 0, 0, TIME_ZONE);
Calendar truncated = DateTimeUtils.truncateToMidnight(cal);
assertEquals(truncated, target);
Calendar endOfDay = DateTimeUtils.endOfDayDate(cal);
Calendar target2 = new GregorianCalendar(2021, 9, 30, 23, 59, 59);
target2.setTimeZone(TIME_ZONE);
target2.set(Calendar.MILLISECOND, 999);
assertEquals(endOfDay, target2);
}
private void assertNextSeason(Calendar expectedSeason, Calendar date, Season season) { private void assertNextSeason(Calendar expectedSeason, Calendar date, Season season) {
assertEquals(expectedSeason, DateTimeUtils.getNext(date, season.getSpring(), season.getSummer(), assertEquals(expectedSeason, DateTimeUtils.getNext(date, season.getSpring(), season.getSummer(),
season.getAutumn(), season.getWinter())); season.getAutumn(), season.getWinter()));