From 7d18cb0481612ee09f3ce822f4a6cd9d609c9cf6 Mon Sep 17 00:00:00 2001 From: Ben Fortuna Date: Tue, 27 Nov 2018 23:27:18 +1100 Subject: [PATCH] Replace UtcOffset with java.time.ZoneOffset --- .../net/fortuna/ical4j/model/TimeZone.java | 8 +- .../net/fortuna/ical4j/model/UtcOffset.java | 1 + .../ical4j/model/ZoneOffsetAdapter.java | 39 +++ .../ical4j/model/component/Observance.java | 2 +- .../ical4j/model/property/TzOffsetFrom.java | 21 +- .../ical4j/model/property/TzOffsetTo.java | 301 +++++++++--------- .../ical4j/model/ZoneOffsetAdapterTest.groovy | 19 ++ .../model/property/TzOffsetFromTest.java | 5 +- .../ical4j/model/property/TzOffsetToTest.java | 8 +- 9 files changed, 233 insertions(+), 171 deletions(-) create mode 100644 src/main/java/net/fortuna/ical4j/model/ZoneOffsetAdapter.java create mode 100644 src/test/groovy/net/fortuna/ical4j/model/ZoneOffsetAdapterTest.groovy diff --git a/src/main/java/net/fortuna/ical4j/model/TimeZone.java b/src/main/java/net/fortuna/ical4j/model/TimeZone.java index 9c282fb64..cdf2d09da 100644 --- a/src/main/java/net/fortuna/ical4j/model/TimeZone.java +++ b/src/main/java/net/fortuna/ical4j/model/TimeZone.java @@ -96,7 +96,7 @@ public final int getOffset(final int era, final int year, final int month, final final Observance observance = vTimeZone.getApplicableObservance(new DateTime(cal.getTime())); if (observance != null) { final TzOffsetTo offset = observance.getProperty(Property.TZOFFSETTO); - return (int) offset.getOffset().getOffset(); + return (int) (offset.getOffset().getTotalSeconds() * 1000L); } return 0; } @@ -108,10 +108,10 @@ public int getOffset(long date) { final Observance observance = vTimeZone.getApplicableObservance(new DateTime(date)); if (observance != null) { final TzOffsetTo offset = observance.getProperty(Property.TZOFFSETTO); - if (offset.getOffset().getOffset() < getRawOffset()) { + if ((offset.getOffset().getTotalSeconds() * 1000L) < getRawOffset()) { return getRawOffset(); } else { - return (int) offset.getOffset().getOffset(); + return (int) (offset.getOffset().getTotalSeconds() * 1000L); } } return 0; @@ -192,7 +192,7 @@ private static int getRawOffset(VTimeZone vt) { if (latestSeasonalTime != null) { final TzOffsetTo offsetTo = latestSeasonalTime.getProperty(Property.TZOFFSETTO); if (offsetTo != null) { - return (int) offsetTo.getOffset().getOffset(); + return (int) (offsetTo.getOffset().getTotalSeconds() * 1000L); } } return 0; diff --git a/src/main/java/net/fortuna/ical4j/model/UtcOffset.java b/src/main/java/net/fortuna/ical4j/model/UtcOffset.java index eb83a204b..0ee6c2889 100644 --- a/src/main/java/net/fortuna/ical4j/model/UtcOffset.java +++ b/src/main/java/net/fortuna/ical4j/model/UtcOffset.java @@ -47,6 +47,7 @@ * * @author Ben Fortuna */ +@Deprecated public class UtcOffset implements Serializable { private static final long serialVersionUID = 5883111996721531728L; diff --git a/src/main/java/net/fortuna/ical4j/model/ZoneOffsetAdapter.java b/src/main/java/net/fortuna/ical4j/model/ZoneOffsetAdapter.java new file mode 100644 index 000000000..7e8473328 --- /dev/null +++ b/src/main/java/net/fortuna/ical4j/model/ZoneOffsetAdapter.java @@ -0,0 +1,39 @@ +package net.fortuna.ical4j.model; + +import java.io.Serializable; +import java.time.ZoneOffset; + +/** + * Support adapter for {@link java.time.ZoneOffset} to output in iCalendar format. + */ +public class ZoneOffsetAdapter implements Serializable { + + private final ZoneOffset offset; + + public ZoneOffsetAdapter(ZoneOffset offset) { + this.offset = offset; + } + + public ZoneOffset getOffset() { + return offset; + } + + @Override + public String toString() { + String retVal = ""; + if (offset != null) { + int hours = Math.abs(offset.getTotalSeconds()) / (60 * 60); + if (offset.getTotalSeconds() < 0) { + hours = -hours; + } + int minutes = Math.abs(offset.getTotalSeconds()) % (60 * 60) / 60; + int seconds = Math.abs(offset.getTotalSeconds()) % (60 * 60) % 60; + if (seconds > 0) { + retVal = String.format("%+03d%02d%02d", hours, minutes, seconds); + } else { + retVal = String.format("%+03d%02d", hours, minutes); + } + } + return retVal; + } +} diff --git a/src/main/java/net/fortuna/ical4j/model/component/Observance.java b/src/main/java/net/fortuna/ical4j/model/component/Observance.java index 91611ed27..ed475013e 100644 --- a/src/main/java/net/fortuna/ical4j/model/component/Observance.java +++ b/src/main/java/net/fortuna/ical4j/model/component/Observance.java @@ -322,7 +322,7 @@ private DateTime calculateOnset(String dateStr) throws ParseException { private DateTime applyOffsetFrom(DateTime orig) { DateTime withOffset = new DateTime(true); - withOffset.setTime(orig.getTime() - getOffsetFrom().getOffset().getOffset()); + withOffset.setTime(orig.getTime() - (getOffsetFrom().getOffset().getTotalSeconds() * 1000L)); return withOffset; } } diff --git a/src/main/java/net/fortuna/ical4j/model/property/TzOffsetFrom.java b/src/main/java/net/fortuna/ical4j/model/property/TzOffsetFrom.java index d80a48219..8c31f90fe 100644 --- a/src/main/java/net/fortuna/ical4j/model/property/TzOffsetFrom.java +++ b/src/main/java/net/fortuna/ical4j/model/property/TzOffsetFrom.java @@ -37,6 +37,7 @@ import java.io.IOException; import java.net.URISyntaxException; import java.text.ParseException; +import java.time.ZoneOffset; /** * $Id$ @@ -51,7 +52,7 @@ public class TzOffsetFrom extends Property { private static final long serialVersionUID = 450274263165493502L; - private UtcOffset offset; + private ZoneOffsetAdapter offset; /** * Default constructor. @@ -80,32 +81,32 @@ public TzOffsetFrom(final ParameterList aList, final String aValue) { /** * @param anOffset a timezone offset in milliseconds */ - public TzOffsetFrom(final UtcOffset anOffset) { + public TzOffsetFrom(final ZoneOffset anOffset) { super(TZOFFSETFROM, new Factory()); - offset = anOffset; + offset = new ZoneOffsetAdapter(anOffset); } /** * @param aList a list of parameters for this component * @param anOffset a timezone offset in milliseconds */ - public TzOffsetFrom(final ParameterList aList, final UtcOffset anOffset) { + public TzOffsetFrom(final ParameterList aList, final ZoneOffset anOffset) { super(TZOFFSETFROM, aList, new Factory()); - offset = anOffset; + offset = new ZoneOffsetAdapter(anOffset); } /** * @return Returns the offset. */ - public final UtcOffset getOffset() { - return offset; + public final ZoneOffset getOffset() { + return offset.getOffset(); } /** * {@inheritDoc} */ public final void setValue(final String aValue) { - offset = new UtcOffset(aValue); + offset = new ZoneOffsetAdapter(ZoneOffset.of(aValue)); } /** @@ -121,8 +122,8 @@ public final String getValue() { /** * @param offset The offset to set. */ - public final void setOffset(final UtcOffset offset) { - this.offset = offset; + public final void setOffset(final ZoneOffset offset) { + this.offset = new ZoneOffsetAdapter(offset); } @Override diff --git a/src/main/java/net/fortuna/ical4j/model/property/TzOffsetTo.java b/src/main/java/net/fortuna/ical4j/model/property/TzOffsetTo.java index a3c41bb50..3e22dcecb 100644 --- a/src/main/java/net/fortuna/ical4j/model/property/TzOffsetTo.java +++ b/src/main/java/net/fortuna/ical4j/model/property/TzOffsetTo.java @@ -1,150 +1,151 @@ -/** - * Copyright (c) 2012, Ben Fortuna - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * - * o Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * - * o Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * o Neither the name of Ben Fortuna nor the names of any other contributors - * may be used to endorse or promote products derived from this software - * without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS - * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT - * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR - * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR - * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, - * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, - * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR - * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF - * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING - * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS - * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - */ -package net.fortuna.ical4j.model.property; - -import net.fortuna.ical4j.model.*; -import net.fortuna.ical4j.validate.ValidationException; - -import java.io.IOException; -import java.net.URISyntaxException; -import java.text.ParseException; - -/** - * $Id$ - *

- * Created: [Apr 6, 2004] - *

- * Defines a TZOFFSETTO iCalendar component property. - * - * @author benf - */ -public class TzOffsetTo extends Property { - - private static final long serialVersionUID = 8213874575051177732L; - - private UtcOffset offset; - - /** - * Default constructor. - */ - public TzOffsetTo() { - super(TZOFFSETTO, new Factory()); - } - - /** - * @param value an offset value - */ - public TzOffsetTo(String value) { - super(TZOFFSETTO, new Factory()); - setValue(value); - } - - /** - * @param aList a list of parameters for this component - * @param aValue a value string for this component - */ - public TzOffsetTo(final ParameterList aList, final String aValue) { - super(TZOFFSETTO, aList, new Factory()); - setValue(aValue); - } - - /** - * @param anOffset a timezone offset in milliseconds - */ - public TzOffsetTo(final UtcOffset anOffset) { - super(TZOFFSETTO, new Factory()); - offset = anOffset; - } - - /** - * @param aList a list of parameters for this component - * @param anOffset a timezone offset in milliseconds - */ - public TzOffsetTo(final ParameterList aList, final UtcOffset anOffset) { - super(TZOFFSETTO, aList, new Factory()); - offset = anOffset; - } - - /** - * @return Returns the offset. - */ - public final UtcOffset getOffset() { - return offset; - } - - /** - * {@inheritDoc} - */ - public final void setValue(final String aValue) { - offset = new UtcOffset(aValue); - } - - /** - * {@inheritDoc} - */ - public final String getValue() { - if (offset != null) { - return offset.toString(); - } - return ""; - } - - /** - * @param offset The offset to set. - */ - public final void setOffset(final UtcOffset offset) { - this.offset = offset; - } - - @Override - public void validate() throws ValidationException { - - } - - public static class Factory extends Content.Factory implements PropertyFactory { - private static final long serialVersionUID = 1L; - - public Factory() { - super(TZOFFSETTO); - } - - public Property createProperty(final ParameterList parameters, final String value) - throws IOException, URISyntaxException, ParseException { - return new TzOffsetTo(parameters, value); - } - - public Property createProperty() { - return new TzOffsetTo(); - } - } - -} +/** + * Copyright (c) 2012, Ben Fortuna + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * o Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * o Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * o Neither the name of Ben Fortuna nor the names of any other contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.fortuna.ical4j.model.property; + +import net.fortuna.ical4j.model.*; +import net.fortuna.ical4j.validate.ValidationException; + +import java.io.IOException; +import java.net.URISyntaxException; +import java.text.ParseException; +import java.time.ZoneOffset; + +/** + * $Id$ + *

+ * Created: [Apr 6, 2004] + *

+ * Defines a TZOFFSETTO iCalendar component property. + * + * @author benf + */ +public class TzOffsetTo extends Property { + + private static final long serialVersionUID = 8213874575051177732L; + + private ZoneOffsetAdapter offset; + + /** + * Default constructor. + */ + public TzOffsetTo() { + super(TZOFFSETTO, new Factory()); + } + + /** + * @param value an offset value + */ + public TzOffsetTo(String value) { + super(TZOFFSETTO, new Factory()); + setValue(value); + } + + /** + * @param aList a list of parameters for this component + * @param aValue a value string for this component + */ + public TzOffsetTo(final ParameterList aList, final String aValue) { + super(TZOFFSETTO, aList, new Factory()); + setValue(aValue); + } + + /** + * @param anOffset a timezone offset in milliseconds + */ + public TzOffsetTo(final ZoneOffset anOffset) { + super(TZOFFSETTO, new Factory()); + offset = new ZoneOffsetAdapter(anOffset); + } + + /** + * @param aList a list of parameters for this component + * @param anOffset a timezone offset in milliseconds + */ + public TzOffsetTo(final ParameterList aList, final ZoneOffset anOffset) { + super(TZOFFSETTO, aList, new Factory()); + offset = new ZoneOffsetAdapter(anOffset); + } + + /** + * @return Returns the offset. + */ + public final ZoneOffset getOffset() { + return offset.getOffset(); + } + + /** + * {@inheritDoc} + */ + public final void setValue(final String aValue) { + offset = new ZoneOffsetAdapter(ZoneOffset.of(aValue)); + } + + /** + * {@inheritDoc} + */ + public final String getValue() { + if (offset != null) { + return offset.toString(); + } + return ""; + } + + /** + * @param offset The offset to set. + */ + public final void setOffset(final ZoneOffset offset) { + this.offset = new ZoneOffsetAdapter(offset); + } + + @Override + public void validate() throws ValidationException { + + } + + public static class Factory extends Content.Factory implements PropertyFactory { + private static final long serialVersionUID = 1L; + + public Factory() { + super(TZOFFSETTO); + } + + public Property createProperty(final ParameterList parameters, final String value) + throws IOException, URISyntaxException, ParseException { + return new TzOffsetTo(parameters, value); + } + + public Property createProperty() { + return new TzOffsetTo(); + } + } + +} diff --git a/src/test/groovy/net/fortuna/ical4j/model/ZoneOffsetAdapterTest.groovy b/src/test/groovy/net/fortuna/ical4j/model/ZoneOffsetAdapterTest.groovy new file mode 100644 index 000000000..077879967 --- /dev/null +++ b/src/test/groovy/net/fortuna/ical4j/model/ZoneOffsetAdapterTest.groovy @@ -0,0 +1,19 @@ +package net.fortuna.ical4j.model + +import spock.lang.Specification + +import java.time.ZoneOffset + +class ZoneOffsetAdapterTest extends Specification { + + def "verify string representation"() { + expect: + new ZoneOffsetAdapter(offset) as String == expectedValue + + where: + offset | expectedValue + ZoneOffset.ofHours(4) | "+0400" + ZoneOffset.ofHoursMinutes(5, 30) | "+0530" + ZoneOffset.ofHoursMinutesSeconds(-6, -30, -15) | "-063015" + } +} diff --git a/src/test/java/net/fortuna/ical4j/model/property/TzOffsetFromTest.java b/src/test/java/net/fortuna/ical4j/model/property/TzOffsetFromTest.java index 4e40d1776..b8a0c7dae 100755 --- a/src/test/java/net/fortuna/ical4j/model/property/TzOffsetFromTest.java +++ b/src/test/java/net/fortuna/ical4j/model/property/TzOffsetFromTest.java @@ -33,7 +33,8 @@ import junit.framework.TestSuite; import net.fortuna.ical4j.model.PropertyTest; -import net.fortuna.ical4j.model.UtcOffset; + +import java.time.ZoneOffset; /** * $Id$ @@ -65,7 +66,7 @@ public TzOffsetFromTest(String testMethod, TzOffsetFrom property) { */ public static TestSuite suite() { TestSuite suite = new TestSuite(); - TzOffsetFrom offset = new TzOffsetFrom(new UtcOffset("+1000")); + TzOffsetFrom offset = new TzOffsetFrom(ZoneOffset.of("+1000")); suite.addTest(new TzOffsetFromTest(offset, "+1000")); suite.addTest(new TzOffsetFromTest("testValidation", offset)); suite.addTest(new TzOffsetFromTest("testEquals", offset)); diff --git a/src/test/java/net/fortuna/ical4j/model/property/TzOffsetToTest.java b/src/test/java/net/fortuna/ical4j/model/property/TzOffsetToTest.java index 293c4430b..5a784e601 100755 --- a/src/test/java/net/fortuna/ical4j/model/property/TzOffsetToTest.java +++ b/src/test/java/net/fortuna/ical4j/model/property/TzOffsetToTest.java @@ -31,11 +31,11 @@ */ package net.fortuna.ical4j.model.property; -import java.text.ParseException; - import junit.framework.TestSuite; import net.fortuna.ical4j.model.PropertyTest; -import net.fortuna.ical4j.model.UtcOffset; + +import java.text.ParseException; +import java.time.ZoneOffset; /** * $Id$ @@ -68,7 +68,7 @@ public TzOffsetToTest(String testMethod, TzOffsetTo property) { */ public static TestSuite suite() { TestSuite suite = new TestSuite(); - TzOffsetTo offset = new TzOffsetTo(new UtcOffset("+1000")); + TzOffsetTo offset = new TzOffsetTo(ZoneOffset.of("+1000")); suite.addTest(new TzOffsetToTest(offset, "+1000")); suite.addTest(new TzOffsetToTest("testValidation", offset)); suite.addTest(new TzOffsetToTest("testEquals", offset));