Przeglądaj źródła

datetime - draft

ca678 11 miesięcy temu
rodzic
commit
43381ee072

+ 1 - 1
assira.commons/src/main/java/net/ranides/assira/time2/DateTimeUtils.java

@@ -58,7 +58,7 @@ public class DateTimeUtils {
         if(Objects.isNull(date2)) {
             return date1;
         }
-        return date1.isBefore(date2) ? date2 : date1;
+        return date1.isBefore(date2) ? date1 : date2;
     }
 
     @Contract("!null,_ -> !null; _,!null -> !null; null,null -> null")

+ 29 - 20
assira.commons/src/main/java/net/ranides/assira/time2/ZonedDateSet.java

@@ -2,35 +2,48 @@ package net.ranides.assira.time2;
 
 import net.ranides.assira.collection.sets.AVLTreeSet;
 
+import java.time.Duration;
 import java.time.LocalDateTime;
 import java.time.ZonedDateTime;
 import java.util.Collection;
 import java.util.SortedSet;
 
+import static java.time.LocalDateTime.MAX;
+import static java.time.LocalDateTime.MIN;
+
+// @todo ZonedDateSet
 public abstract class ZonedDateSet {
 
-    public abstract boolean contains(ZonedDate date);
+    public boolean contains(ZonedDate date) {
+        return !contains(ZonedRange.of(date)).isZero();
+    }
+
+    public boolean containsFully(ZonedDate date) {
+        return contains(ZonedRange.of(date)).equals(Duration.ofDays(1));
+    }
 
     public abstract boolean contains(ZonedDateTime datetime);
 
-    public static class EmptyHolidaySchedule extends ZonedDateSet {
+    public abstract Duration contains(ZonedRange range);
+
+    public static class Empty extends ZonedDateSet {
 
         @Override
-        public boolean contains(ZonedDate date) {
+        public boolean contains(ZonedDateTime datetime) {
             return false;
         }
 
         @Override
-        public boolean contains(ZonedDateTime datetime) {
-            return false;
+        public Duration contains(ZonedRange range) {
+            return null;
         }
     }
 
-    public static class SimpleHolidaySchedule extends ZonedDateSet {
+    public static class Simple extends ZonedDateSet {
 
         private final SortedSet<ZonedDateTime> set;
 
-        public SimpleHolidaySchedule(Collection<ZonedDate> input) {
+        public Simple(Collection<ZonedDate> input) {
             this.set = new AVLTreeSet<>();
             for(ZonedDate item : input) {
                 set.add(DateTimeUtils.withZoneUtc(item.withZero()));
@@ -39,31 +52,27 @@ public abstract class ZonedDateSet {
 
         @ZoneHazard
         @Override
-        public boolean contains(ZonedDate date) {
-            ZonedDateTime lower = DateTimeUtils.withZoneUtc(date.withZero());
-            ZonedDateTime upper = lower.plusDays(1);
+        public Duration contains(ZonedRange range) {
+            ZonedDateTime lower = range.begin();
+            ZonedDateTime upper = range.end();
 
-            for(ZonedDateTime mid : set.tailSet(lower.with(LocalDateTime.MIN))) {
+            for(ZonedDateTime mid : set.subSet(lower.with(MIN), upper.with(MAX))) {
                 if(mid.isEqual(lower) || (mid.isBefore(upper) && mid.plusDays(1).isAfter(lower))) {
-                    return true;
-                }
-                if(mid.plusDays(1).isAfter(upper)) {
-                    return false;
+                    return ZonedRange.of(mid, mid.plusDays(1)).intersection(range).duration();
                 }
             }
-            return false;
+            return Duration.ZERO;
         }
 
         @Override
         public boolean contains(ZonedDateTime datetime) {
             // @todo test, may not work at all
-            for(ZonedDateTime mid : set.tailSet(datetime.minusDays(1))) {
+            ZonedDateTime lowerMin = datetime.minusDays(1);
+            ZonedDateTime upperMax = datetime.plusDays(1);
+            for(ZonedDateTime mid : set.subSet(lowerMin, upperMax)) {
                 if(mid.isEqual(datetime) || (mid.isBefore(datetime) && mid.plusDays(1).isAfter(datetime))) {
                     return true;
                 }
-                if(mid.plusDays(1).isAfter(datetime)) {
-                    return false;
-                }
             }
             return false;
         }

+ 49 - 0
assira.commons/src/main/java/net/ranides/assira/time2/ZonedRange.java

@@ -0,0 +1,49 @@
+package net.ranides.assira.time2;
+
+import java.time.Duration;
+import java.time.ZonedDateTime;
+
+import static net.ranides.assira.time2.DateTimeUtils.max;
+import static net.ranides.assira.time2.DateTimeUtils.min;
+
+// @todo ZonedRange
+public class ZonedRange {
+
+    private final ZonedDateTime begin;
+
+    private final ZonedDateTime end;
+
+    private ZonedRange(ZonedDateTime begin, ZonedDateTime end) {
+        if(begin.isAfter(end)) {
+            this.begin = end;
+            this.end = begin;
+        } else {
+            this.begin = begin;
+            this.end = end;
+        }
+    }
+
+    public static ZonedRange of(ZonedDateTime begin, ZonedDateTime end) {
+        return new ZonedRange(begin, end);
+    }
+
+    public static ZonedRange of(ZonedDate date) {
+        return new ZonedRange(date.withMin(), date.plusDays(1).withMin());
+    }
+
+    public ZonedDateTime begin() {
+        return begin;
+    }
+
+    public ZonedDateTime end() {
+        return end;
+    }
+
+    public Duration duration() {
+        return Duration.between(begin, end);
+    }
+
+    public ZonedRange intersection(ZonedRange range) {
+        return of(max(range.begin(), begin), min(range.end(), end));
+    }
+}

+ 3 - 1
assira.commons/src/test/java/net/ranides/assira/time2/ZonedDateSetTest.java

@@ -10,7 +10,7 @@ public class ZonedDateSetTest {
 
     @Test
     public void basic() {
-        ZonedDateSet set = new ZonedDateSet.SimpleHolidaySchedule(Arrays.asList(
+        ZonedDateSet set = new ZonedDateSet.Simple(Arrays.asList(
             DateTimeLiteral.dateUtc(2020, 3, 15),
             DateTimeLiteral.dateUtc(2020, 3, 16),
             DateTimeLiteral.dateUtc(2020, 4, 20),
@@ -26,6 +26,7 @@ public class ZonedDateSetTest {
         assertTrue(set.contains(DateTimeLiteral.dateUtc(2020, 3, 16)));
         assertFalse(set.contains(DateTimeLiteral.dateUtc(2020, 3, 17)));
         assertFalse(set.contains(DateTimeLiteral.dateUtc(2020, 3, 18)));
+        assertFalse(set.contains(DateTimeLiteral.dateUtc(2021, 3, 14)));
 
 
         assertFalse(set.contains(DateTimeLiteral.date(DateTimeUtils.ZONE_PL, 2020, 3, 14)));
@@ -33,5 +34,6 @@ public class ZonedDateSetTest {
         assertTrue(set.contains(DateTimeLiteral.date(DateTimeUtils.ZONE_PL, 2020, 3, 16)));
         assertTrue(set.contains(DateTimeLiteral.date(DateTimeUtils.ZONE_PL, 2020, 3, 17)));
         assertFalse(set.contains(DateTimeLiteral.date(DateTimeUtils.ZONE_PL, 2020, 3, 18)));
+        assertFalse(set.contains(DateTimeLiteral.date(DateTimeUtils.ZONE_PL, 2021, 3, 14)));
     }
 }

+ 32 - 0
assira.commons/src/test/java/net/ranides/assira/time2/ZonedRangeTest.java

@@ -0,0 +1,32 @@
+package net.ranides.assira.time2;
+
+import org.junit.Test;
+
+import java.time.ZoneId;
+
+public class ZonedRangeTest {
+
+    @Test
+    public void intersection2() {
+        ZoneId zone = ZoneId.of("Pacific/Funafuti");
+
+        ZonedRange a = ZonedRange.of(
+                DateTimeLiteral.datetimeUtc(2020, 9, 15, 10, 0, 0),
+                DateTimeLiteral.datetimeUtc(2020, 9, 18, 10, 0, 0)
+        );
+
+        ZonedRange b = ZonedRange.of(
+                DateTimeLiteral.datetimeUtc(2020, 9, 14, 10, 0, 0),
+                DateTimeLiteral.datetimeUtc(2020, 9, 17, 10, 0, 0)
+        );
+
+        ZonedRange c = ZonedRange.of(
+                DateTimeLiteral.datetime(zone, 2020, 9, 15, 10, 0, 0),
+                DateTimeLiteral.datetime(zone, 2020, 9, 18, 10, 0, 0)
+        );
+
+        System.out.println(a.intersection(a));
+        System.out.println(a.intersection(b));
+        System.out.println(a.intersection(c));
+    }
+}