diff --git a/app/src/commonTest/java/org/tasks/TestUtilities.kt b/app/src/commonTest/java/org/tasks/TestUtilities.kt index 0bcc61ed0..4f2e07fda 100644 --- a/app/src/commonTest/java/org/tasks/TestUtilities.kt +++ b/app/src/commonTest/java/org/tasks/TestUtilities.kt @@ -10,8 +10,21 @@ import org.tasks.time.DateTime import java.io.StringReader import java.nio.file.Files import java.nio.file.Paths +import java.util.* object TestUtilities { + fun withTZ(id: String, runnable: () -> Unit) = withTZ(TimeZone.getTimeZone(id), runnable) + + fun withTZ(tz: TimeZone, runnable: () -> Unit) { + val def = TimeZone.getDefault() + try { + TimeZone.setDefault(tz) + runnable() + } finally { + TimeZone.setDefault(def) + } + } + fun assertEquals(expected: Long, actual: DateTime) = org.junit.Assert.assertEquals(expected, actual.millis) diff --git a/app/src/main/java/org/tasks/time/DateTime.java b/app/src/main/java/org/tasks/time/DateTime.java index 8c44a9f8a..3683aa0cd 100644 --- a/app/src/main/java/org/tasks/time/DateTime.java +++ b/app/src/main/java/org/tasks/time/DateTime.java @@ -28,7 +28,7 @@ import org.tasks.locale.Locale; public class DateTime { public static final int MAX_MILLIS_PER_DAY = (int) TimeUnit.DAYS.toMillis(1) - 1; - private static final TimeZone UTC = TimeZone.getTimeZone("GMT"); + public static final TimeZone UTC = TimeZone.getTimeZone("GMT"); private static final int MILLIS_PER_HOUR = (int) TimeUnit.HOURS.toMillis(1); private static final int MILLIS_PER_MINUTE = (int) TimeUnit.MINUTES.toMillis(1); private static final int MILLIS_PER_SECOND = (int) TimeUnit.SECONDS.toMillis(1); @@ -100,6 +100,10 @@ public class DateTime { return new DateTime(date.getTime(), UTC); } + public static DateTime from(net.fortuna.ical4j.model.DateTime dateTime) { + return new DateTime(dateTime.getTime(), dateTime.getTimeZone()); + } + private DateTime setTime(int hours, int minutes, int seconds, int milliseconds) { Calendar calendar = getCalendar(); calendar.set(Calendar.HOUR_OF_DAY, hours); @@ -318,6 +322,9 @@ public class DateTime { } private DateTime toTimeZone(TimeZone timeZone) { + if (timeZone == this.timeZone) { + return this; + } Calendar current = getCalendar(); Calendar target = new GregorianCalendar(timeZone); target.setTimeInMillis(current.getTimeInMillis()); diff --git a/app/src/test/java/org/tasks/time/DateTimeTest.kt b/app/src/test/java/org/tasks/time/DateTimeTest.kt index 854e21eb4..80106f763 100644 --- a/app/src/test/java/org/tasks/time/DateTimeTest.kt +++ b/app/src/test/java/org/tasks/time/DateTimeTest.kt @@ -3,7 +3,7 @@ package org.tasks.time import org.junit.Assert.* import org.junit.Test import org.tasks.Freeze -import java.util.* +import org.tasks.TestUtilities.withTZ import java.util.concurrent.TimeUnit class DateTimeTest { @@ -21,39 +21,29 @@ class DateTimeTest { @Test fun testWithMillisOfDayDuringDST() { - val def = TimeZone.getDefault() - try { - TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago")) + withTZ("America/Chicago") { assertEquals( 2, DateTime(2015, 10, 31, 2, 0, 0) .withMillisOfDay(TimeUnit.HOURS.toMillis(2).toInt()) .hourOfDay) - } finally { - TimeZone.setDefault(def) } } @Test fun testWithMillisOfDayAfterDST() { - val def = TimeZone.getDefault() - try { - TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago")) + withTZ("America/Chicago") { assertEquals( 2, DateTime(2015, 11, 2, 2, 0, 0) .withMillisOfDay(TimeUnit.HOURS.toMillis(2).toInt()) .hourOfDay) - } finally { - TimeZone.setDefault(def) } } @Test fun testWithMillisOfDayStartDST() { - val def = TimeZone.getDefault() - try { - TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago")) + withTZ("America/Chicago") { assertEquals( 1, DateTime(2015, 3, 8, 0, 0, 0) @@ -81,16 +71,12 @@ class DateTimeTest { DateTime(2015, 3, 8, 0, 0, 0) .withMillisOfDay(TimeUnit.HOURS.toMillis(3).toInt()) .millis) - } finally { - TimeZone.setDefault(def) } } @Test fun testWithMillisOfDayEndDST() { - val def = TimeZone.getDefault() - try { - TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago")) + withTZ("America/Chicago") { assertEquals( 1, DateTime(2015, 11, 1, 0, 0, 0) @@ -106,8 +92,6 @@ class DateTimeTest { DateTime(2015, 11, 1, 0, 0, 0) .withMillisOfDay(TimeUnit.HOURS.toMillis(3).toInt()) .hourOfDay) - } finally { - TimeZone.setDefault(def) } } @@ -323,18 +307,40 @@ class DateTimeTest { } @Test - fun testToUTC() { - val def = TimeZone.getDefault() - try { - TimeZone.setDefault(TimeZone.getTimeZone("America/Chicago")) + fun toUTC() { + withTZ("America/Chicago") { assertEquals( - DateTime(2015, 10, 6, 14, 45, 15, 0, TimeZone.getTimeZone("GMT")), + DateTime(2015, 10, 6, 14, 45, 15, 0, DateTime.UTC), DateTime(2015, 10, 6, 9, 45, 15).toUTC()) - } finally { - TimeZone.setDefault(def) } } + @Test + fun fromUTC() { + withTZ("America/Chicago") { + assertEquals( + DateTime(2021, 1, 27, 10, 56, 15, 423), + DateTime(2021, 1, 27, 16, 56, 15, 423, DateTime.UTC).toLocal() + ) + } + } + + @Test + fun dontAdjustLocal() { + assertEquals( + DateTime(2021, 1, 27, 10, 56, 15, 423), + DateTime(2021, 1, 27, 10, 56, 15, 423).toLocal() + ) + } + + @Test + fun dontAdjustUTC() { + assertEquals( + DateTime(2021, 1, 27, 16, 56, 15, 423, DateTime.UTC), + DateTime(2021, 1, 27, 16, 56, 15, 423, DateTime.UTC).toUTC() + ) + } + @Test fun testStartOfMinute() { assertEquals(