From 0c1f740dd6ddd6432dc29266e42ef851e26027bb Mon Sep 17 00:00:00 2001
From: Normand Briere <nbriere@noware.ca>
Date: Tue, 13 Aug 2019 21:21:38 -0400
Subject: [PATCH] Random node + optimizations.
---
timeflow/data/time/TimeUnit.java | 473 ++++++++++++++++++++++++++++++----------------------------
1 files changed, 244 insertions(+), 229 deletions(-)
diff --git a/timeflow/data/time/TimeUnit.java b/timeflow/data/time/TimeUnit.java
index 760b3be..070b0fa 100755
--- a/timeflow/data/time/TimeUnit.java
+++ b/timeflow/data/time/TimeUnit.java
@@ -3,241 +3,256 @@
import java.util.*;
import java.text.*;
-public class TimeUnit {
+public class TimeUnit
+{
+ public static final TimeUnit YEAR = new TimeUnit("Years", Calendar.YEAR, 365 * 24 * 60 * 60 * 1000L, "yyyy", "yyyy");
+ public static final TimeUnit MONTH = new TimeUnit("Months", Calendar.MONTH, 30 * 24 * 60 * 60 * 1000L, "MMM", "MMM yyyy");
+ public static final TimeUnit WEEK = new TimeUnit("Weeks", Calendar.WEEK_OF_YEAR, 7 * 24 * 60 * 60 * 1000L, "d", "MMM d yyyy");
+ public static final TimeUnit DAY = new TimeUnit("Days", Calendar.DAY_OF_MONTH, 24 * 60 * 60 * 1000L, "d", "MMM d yyyy");
+ public static final TimeUnit DAY_OF_WEEK = new TimeUnit("Days", Calendar.DAY_OF_WEEK, 24 * 60 * 60 * 1000L, "d", "MMM d yyyy");
+ public static final TimeUnit HOUR = new TimeUnit("Hours", Calendar.HOUR_OF_DAY, 60 * 60 * 1000L, "HH:mm", "MMM d yyyy HH:mm");
+ public static final TimeUnit MINUTE = new TimeUnit("Minutes", Calendar.MINUTE, 60 * 1000L, ":mm", "MMM d yyyy HH:mm");
+ public static final TimeUnit SECOND = new TimeUnit("Seconds", Calendar.SECOND, 1000L, ":ss", "MMM d yyyy HH:mm:ss");
+ public static final TimeUnit REALTIME = new TimeUnit("Realtime", Calendar.MILLISECOND, 1L, ".SS", "HH:mm:ss.SS");
+
+ public static final TimeUnit DECADE = multipleYears(10);
+ public static final TimeUnit CENTURY = multipleYears(100);
+ private static final double DAY_SIZE = 24 * 60 * 60 * 1000L;
+ private int quantity;
+ private long roughSize;
+ private SimpleDateFormat format, fullFormat;
+ private String name;
+ private int calendarCode;
- public static final TimeUnit YEAR=new TimeUnit("Years", Calendar.YEAR, 365*24*60*60*1000L, "yyyy", "yyyy");
- public static final TimeUnit MONTH=new TimeUnit("Months", Calendar.MONTH, 30*24*60*60*1000L, "MMM", "MMM yyyy");
- public static final TimeUnit WEEK=new TimeUnit("Weeks", Calendar.WEEK_OF_YEAR, 7*24*60*60*1000L, "d", "MMM d yyyy");
- public static final TimeUnit DAY=new TimeUnit("Days", Calendar.DAY_OF_MONTH, 24*60*60*1000L, "d", "MMM d yyyy");
- public static final TimeUnit DAY_OF_WEEK=new TimeUnit("Days", Calendar.DAY_OF_WEEK, 24*60*60*1000L, "d", "MMM d yyyy");
- public static final TimeUnit HOUR=new TimeUnit("Hours", Calendar.HOUR_OF_DAY, 60*60*1000L, "kk:mm", "MMM d yyyy kk:mm");
- public static final TimeUnit MINUTE=new TimeUnit("Minutes", Calendar.MINUTE, 60*1000L, ":mm", "MMM d yyyy kk:mm");
- public static final TimeUnit SECOND=new TimeUnit("Seconds", Calendar.SECOND, 1000L, ":ss", "MMM d yyyy kk:mm:ss");
- public static final TimeUnit DECADE=multipleYears(10);
- public static final TimeUnit CENTURY=multipleYears(100);
-
- private static final double DAY_SIZE=24*60*60*1000L;
-
- private int quantity;
- private long roughSize;
- private SimpleDateFormat format, fullFormat;
- private String name;
- private int calendarCode;
-
- private TimeUnit()
- {
- }
-
- private TimeUnit(String name, int calendarCode, long roughSize, String formatPattern, String fullFormatPattern)
- {
- this.name=name;
- this.calendarCode=calendarCode;
- this.roughSize=roughSize;
- format=new SimpleDateFormat(formatPattern);
- fullFormat=new SimpleDateFormat(fullFormatPattern);
- quantity=1;
- }
-
- public String toString()
- {
- return "[TimeUnit: "+name+"]";
- }
+ private TimeUnit()
+ {
+ }
- public static TimeUnit multipleYears(int numYears)
- {
- TimeUnit t=new TimeUnit();
- t.name=numYears+" Years";
- t.calendarCode=Calendar.YEAR;
- t.roughSize=YEAR.roughSize*numYears;
- t.format=YEAR.format;
- t.fullFormat=YEAR.fullFormat;
- t.quantity=numYears;
- return t;
- }
-
- public static TimeUnit multipleWeeks(int num)
- {
- TimeUnit t=new TimeUnit();
- t.name=num+" Weeks";
- t.calendarCode=Calendar.WEEK_OF_YEAR;
- t.roughSize=WEEK.roughSize*num;
- t.format=WEEK.format;
- t.fullFormat=WEEK.fullFormat;
- t.quantity=num;
- return t;
- }
-
- public TimeUnit times(int quantity)
- {
- TimeUnit t=new TimeUnit();
- t.name=quantity+" "+this.name;
- t.calendarCode=this.calendarCode;
- t.roughSize=this.roughSize*quantity;
- t.format=this.format;
- t.fullFormat=this.fullFormat;
- t.quantity=quantity;
- return t;
-
- }
+ private TimeUnit(String name, int calendarCode, long roughSize, String formatPattern, String fullFormatPattern)
+ {
+ this.name = name;
+ this.calendarCode = calendarCode;
+ this.roughSize = roughSize;
+ format = new SimpleDateFormat(formatPattern);
+ fullFormat = new SimpleDateFormat(fullFormatPattern);
+ quantity = 1;
+ }
-
- public int numUnitsIn(TimeUnit u)
- {
- return (int)Math.round(u.getRoughSize()/(double)getRoughSize());
- }
-
- public boolean isDayOrLess()
- {
- return roughSize <= 24*60*60*1000L;
- }
-
- public RoughTime roundDown(long timestamp)
- {
- return round(timestamp, false);
- }
-
- public RoughTime roundUp(long timestamp)
- {
- return round(timestamp, true);
- }
-
- private static final int[] calendarUnits={Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY, Calendar.DAY_OF_MONTH, Calendar.MONTH, Calendar.YEAR};
- public RoughTime round(long timestamp, boolean up)
- {
- Calendar c=TimeUtils.cal(timestamp);
-
- if (calendarCode==Calendar.WEEK_OF_YEAR )
- {
- c.set(Calendar.DAY_OF_WEEK, c.getMinimum(Calendar.DAY_OF_WEEK));
- }
- else
- {
-
- // set to minimum all fields of finer granularity.
- int roundingCode=calendarCode;
- if (calendarCode==Calendar.WEEK_OF_YEAR || calendarCode==Calendar.DAY_OF_WEEK)
- roundingCode=Calendar.DAY_OF_MONTH;
- for (int i=0; i<calendarUnits.length; i++)
- {
- if (calendarUnits[i]==roundingCode)
- break;
- if (i==calendarUnits.length-1)
- throw new IllegalArgumentException("Unsupported Calendar Unit: "+calendarCode);
- c.set(calendarUnits[i], c.getMinimum(calendarUnits[i]));
- }
- if (quantity>1)
- {
- c.set(calendarCode, quantity*(c.get(calendarCode)/quantity));
- }
- }
-
- // if rounding up, then add a unit at current granularity.
- if (up)
- c.add(calendarCode, quantity);
-
- return new RoughTime(c.getTimeInMillis(), this);
- }
-
- public int get(long timestamp)
- {
- Calendar c= TimeUtils.cal(timestamp);
- int n=c.get(calendarCode);
- return quantity==1 ? n : n%quantity;
- }
-
- public void addTo(RoughTime r)
- {
- addTo(r,1);
- }
-
- public void addTo(RoughTime r, int times)
- {
- Calendar c=TimeUtils.cal(r.getTime());
- c.add(calendarCode, quantity*times);
- r.setTime(c.getTimeInMillis());
- }
-
- // Finding the difference between two dates, in a given unit of time,
- // is much subtler than you'd think! And annoyingly, the Calendar class does not do
- // this for you, even though it actually "knows" how to do so since it
- // can add fields.
- //
- // The most vexing problem is dealing with daylight savings time,
- // which means that one day a year has 23 hours and one day has 25 hours.
- // We also have to handle the fact that months and years aren't constant lengths.
- //
- // Rather than write all this ourselves, in this code we
- // use the Calendar class to do the heavy lifting.
- public long difference(long x, long y)
- {
- // If this is not one of the hard cases,
- // just divide the timespan by the length of time unit.
- // Note that we're not worrying about hours and daylight savings time.
- if (calendarCode!=Calendar.YEAR && calendarCode!=Calendar.MONTH &&
- calendarCode!=Calendar.DAY_OF_MONTH && calendarCode!=Calendar.DAY_OF_WEEK &&
- calendarCode!=Calendar.WEEK_OF_YEAR)
- {
- return (x-y)/roughSize;
- }
-
- Calendar c1=TimeUtils.cal(x), c2=TimeUtils.cal(y);
- int diff=0;
- switch (calendarCode)
- {
- case Calendar.YEAR:
- return (c1.get(Calendar.YEAR)-c2.get(Calendar.YEAR))/quantity;
-
- case Calendar.MONTH:
- diff= 12*(c1.get(Calendar.YEAR)-c2.get(Calendar.YEAR))+
- c1.get(Calendar.MONTH)-c2.get(Calendar.MONTH);
- return diff/quantity;
-
- case Calendar.DAY_OF_MONTH:
- case Calendar.DAY_OF_WEEK:
- case Calendar.DAY_OF_YEAR:
- case Calendar.WEEK_OF_MONTH:
- case Calendar.WEEK_OF_YEAR:
- // This is ugly, but believe me, it beats the alternative methods :-)
- // We use the Calendar class's knowledge of daylight savings time.
- // and also the fact that if we calculate this naively, then we aren't going
- // to be off by more than one in either direction.
- int naive=(int)Math.round((x-y)/(double)roughSize);
- c2.add(calendarCode, naive*quantity);
- if (c1.get(calendarCode)==c2.get(calendarCode))
- return naive/quantity;
- c2.add(calendarCode, quantity);
- if (c1.get(calendarCode)==c2.get(calendarCode))
- return naive/quantity+1;
- return naive/quantity-1;
- }
- throw new IllegalArgumentException("Unexpected calendar code: "+calendarCode);
- }
+ public String toString()
+ {
+ return "[TimeUnit: " + name + "]";
+ }
- public long approxNumInRange(long start, long end)
- {
- return 1+(end-start)/roughSize;
- }
-
- public long getRoughSize() {
- return roughSize;
- }
+ public static TimeUnit multipleYears(int numYears)
+ {
+ TimeUnit t = new TimeUnit();
+ t.name = numYears + " Years";
+ t.calendarCode = Calendar.YEAR;
+ t.roughSize = YEAR.roughSize * numYears;
+ t.format = YEAR.format;
+ t.fullFormat = YEAR.fullFormat;
+ t.quantity = numYears;
+ return t;
+ }
- public String format(Date date)
- {
- return format.format(date);
- }
+ public static TimeUnit multipleWeeks(int num)
+ {
+ TimeUnit t = new TimeUnit();
+ t.name = num + " Weeks";
+ t.calendarCode = Calendar.WEEK_OF_YEAR;
+ t.roughSize = WEEK.roughSize * num;
+ t.format = WEEK.format;
+ t.fullFormat = WEEK.fullFormat;
+ t.quantity = num;
+ return t;
+ }
- public String formatFull(Date date)
- {
- return fullFormat.format(date);
- }
+ public TimeUnit times(int quantity)
+ {
+ TimeUnit t = new TimeUnit();
+ t.name = quantity + " " + this.name;
+ t.calendarCode = this.calendarCode;
+ t.roughSize = this.roughSize * quantity;
+ t.format = this.format;
+ t.fullFormat = this.fullFormat;
+ t.quantity = quantity;
+ return t;
- public String formatFull(long timestamp)
- {
- return fullFormat.format(new Date(timestamp));
- }
+ }
- public String getName() {
- return name;
- }
+ public int numUnitsIn(TimeUnit u)
+ {
+ return (int) Math.round(u.getRoughSize() / (double) getRoughSize());
+ }
+
+ public boolean isDayOrLess()
+ {
+ return roughSize <= 24 * 60 * 60 * 1000L;
+ }
+
+ public RoughTime roundDown(long timestamp)
+ {
+ return round(timestamp, false);
+ }
+
+ public RoughTime roundUp(long timestamp)
+ {
+ return round(timestamp, true);
+ }
+ private static final int[] calendarUnits =
+ {
+ Calendar.MILLISECOND, Calendar.SECOND, Calendar.MINUTE, Calendar.HOUR_OF_DAY, Calendar.DAY_OF_MONTH, Calendar.MONTH, Calendar.YEAR
+ };
+
+ public RoughTime round(long timestamp, boolean up)
+ {
+ Calendar c = TimeUtils.cal(timestamp);
+
+ if (calendarCode == Calendar.WEEK_OF_YEAR)
+ {
+ c.set(Calendar.DAY_OF_WEEK, c.getMinimum(Calendar.DAY_OF_WEEK));
+ } else
+ {
+
+ // set to minimum all fields of finer granularity.
+ int roundingCode = calendarCode;
+ if (calendarCode == Calendar.WEEK_OF_YEAR || calendarCode == Calendar.DAY_OF_WEEK)
+ {
+ roundingCode = Calendar.DAY_OF_MONTH;
+ }
+ for (int i = 0; i < calendarUnits.length; i++)
+ {
+ if (calendarUnits[i] == roundingCode)
+ {
+ break;
+ }
+ if (i == calendarUnits.length - 1)
+ {
+ //throw new IllegalArgumentException("Unsupported Calendar Unit: " + calendarCode);
+ }
+ c.set(calendarUnits[i], c.getMinimum(calendarUnits[i]));
+ }
+ if (quantity > 1)
+ {
+ c.set(calendarCode, quantity * (c.get(calendarCode) / quantity));
+ }
+ }
+
+ // if rounding up, then add a unit at current granularity.
+ if (up)
+ {
+ c.add(calendarCode, quantity);
+ }
+
+ return new RoughTime(c.getTimeInMillis(), this);
+ }
+
+ public int get(long timestamp)
+ {
+ Calendar c = TimeUtils.cal(timestamp);
+ int n = c.get(calendarCode);
+ return quantity == 1 ? n : n % quantity;
+ }
+
+ public void addTo(RoughTime r)
+ {
+ addTo(r, 1);
+ }
+
+ public void addTo(RoughTime r, int times)
+ {
+ Calendar c = TimeUtils.cal(r.getTime());
+ c.add(calendarCode, quantity * times);
+ r.setTime(c.getTimeInMillis());
+ }
+
+ // Finding the difference between two dates, in a given unit of time,
+ // is much subtler than you'd think! And annoyingly, the Calendar class does not do
+ // this for you, even though it actually "knows" how to do so since it
+ // can add fields.
+ //
+ // The most vexing problem is dealing with daylight savings time,
+ // which means that one day a year has 23 hours and one day has 25 hours.
+ // We also have to handle the fact that months and years aren't constant lengths.
+ //
+ // Rather than write all this ourselves, in this code we
+ // use the Calendar class to do the heavy lifting.
+ public long difference(long x, long y)
+ {
+ // If this is not one of the hard cases,
+ // just divide the timespan by the length of time unit.
+ // Note that we're not worrying about hours and daylight savings time.
+ if (calendarCode != Calendar.YEAR && calendarCode != Calendar.MONTH
+ && calendarCode != Calendar.DAY_OF_MONTH && calendarCode != Calendar.DAY_OF_WEEK
+ && calendarCode != Calendar.WEEK_OF_YEAR)
+ {
+ return (x - y) / roughSize;
+ }
+
+ Calendar c1 = TimeUtils.cal(x), c2 = TimeUtils.cal(y);
+ int diff = 0;
+ switch (calendarCode)
+ {
+ case Calendar.YEAR:
+ return (c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR)) / quantity;
+
+ case Calendar.MONTH:
+ diff = 12 * (c1.get(Calendar.YEAR) - c2.get(Calendar.YEAR))
+ + c1.get(Calendar.MONTH) - c2.get(Calendar.MONTH);
+ return diff / quantity;
+
+ case Calendar.DAY_OF_MONTH:
+ case Calendar.DAY_OF_WEEK:
+ case Calendar.DAY_OF_YEAR:
+ case Calendar.WEEK_OF_MONTH:
+ case Calendar.WEEK_OF_YEAR:
+ // This is ugly, but believe me, it beats the alternative methods :-)
+ // We use the Calendar class's knowledge of daylight savings time.
+ // and also the fact that if we calculate this naively, then we aren't going
+ // to be off by more than one in either direction.
+ int naive = (int) Math.round((x - y) / (double) roughSize);
+ c2.add(calendarCode, naive * quantity);
+ if (c1.get(calendarCode) == c2.get(calendarCode))
+ {
+ return naive / quantity;
+ }
+ c2.add(calendarCode, quantity);
+ if (c1.get(calendarCode) == c2.get(calendarCode))
+ {
+ return naive / quantity + 1;
+ }
+ return naive / quantity - 1;
+ }
+ throw new IllegalArgumentException("Unexpected calendar code: " + calendarCode);
+ }
+
+ public long approxNumInRange(long start, long end)
+ {
+ return 1 + (end - start) / roughSize;
+ }
+
+ public long getRoughSize()
+ {
+ return roughSize;
+ }
+
+ public String format(Date date)
+ {
+ return format.format(date);
+ }
+
+ public String formatFull(Date date)
+ {
+ return fullFormat.format(date);
+ }
+
+ public String formatFull(long timestamp)
+ {
+ return fullFormat.format(new Date(timestamp));
+ }
+
+ public String getName()
+ {
+ return name;
+ }
}
--
Gitblit v1.6.2