diff --git a/.classpath b/.classpath index c4651da9..e01fe513 100644 --- a/.classpath +++ b/.classpath @@ -4,14 +4,8 @@ - - - - - - diff --git a/src/se/hal/deamon/SensorDataAggregatorDaemon.java b/src/se/hal/deamon/SensorDataAggregatorDaemon.java index fd1a4340..85b47412 100755 --- a/src/se/hal/deamon/SensorDataAggregatorDaemon.java +++ b/src/se/hal/deamon/SensorDataAggregatorDaemon.java @@ -2,7 +2,6 @@ package se.hal.deamon; import se.hal.HalContext; import se.hal.intf.HalDaemon; -import se.hal.intf.HalSensorData; import se.hal.struct.Sensor; import se.hal.intf.HalSensorData.AggregationMethod; import se.hal.util.TimeUtility; @@ -23,6 +22,18 @@ import java.util.logging.Logger; public class SensorDataAggregatorDaemon implements HalDaemon { private static final Logger logger = LogUtil.getLogger(); + + public enum AggregationPeriodLength{ + second, + minute, + fiveMinutes, + fifteenMinutes, + hour, + day, + week, + month, + year + } public void initiate(ScheduledExecutorService executor){ executor.scheduleAtFixedRate(this, 0, TimeUtility.FIVE_MINUTES_IN_MS, TimeUnit.MILLISECONDS); @@ -50,16 +61,16 @@ public class SensorDataAggregatorDaemon implements HalDaemon { logger.fine("The sensor is of type: " + sensor.getDeviceData().getClass().getName()); logger.fine("aggregating raw data up to a day old into five minute periods"); - aggregateRawData(sensor, TimeUtility.FIVE_MINUTES_IN_MS, TimeUtility.DAY_IN_MS, 5); + aggregateRawData(sensor, AggregationPeriodLength.fiveMinutes, TimeUtility.DAY_IN_MS, 5); - logger.fine("aggregating raw data up to a week old into five minute periods"); - aggregateRawData(sensor, TimeUtility.HOUR_IN_MS, TimeUtility.WEEK_IN_MS, 60); + logger.fine("aggregating raw data up to a week old into one hour periods"); + aggregateRawData(sensor, AggregationPeriodLength.hour, TimeUtility.WEEK_IN_MS, 60); logger.fine("aggregating raw data into one day periods"); - aggregateRawData(sensor, TimeUtility.DAY_IN_MS, TimeUtility.INFINITY, 60*24); + aggregateRawData(sensor, AggregationPeriodLength.day, TimeUtility.INFINITY, 60*24); logger.fine("aggregating raw data into one week periods"); - aggregateRawData(sensor, TimeUtility.WEEK_IN_MS, TimeUtility.INFINITY, 60*24*7); + aggregateRawData(sensor, AggregationPeriodLength.week, TimeUtility.INFINITY, 60*24*7); } /** @@ -68,7 +79,7 @@ public class SensorDataAggregatorDaemon implements HalDaemon { * @param ageLimitInMs Only aggregate up to this age * @param toPeriodSizeInMs The period length in ms to aggregate to */ - private void aggregateRawData(Sensor sensor, long toPeriodSizeInMs, long ageLimitInMs, int expectedSampleCount){ + private void aggregateRawData(Sensor sensor, AggregationPeriodLength aggrPeriodLength, long ageLimitInMs, int expectedSampleCount){ long sensorId = sensor.getId(); AggregationMethod aggrMethod = sensor.getDeviceData().getAggregationMethod(); DBConnection db = HalContext.getDB(); @@ -79,12 +90,21 @@ public class SensorDataAggregatorDaemon implements HalDaemon { + " WHERE sensor_id == ?" + " AND timestamp_end-timestamp_start == ?"); stmt.setLong(1, sensorId); - stmt.setLong(2, toPeriodSizeInMs-1); + switch(aggrPeriodLength){ + case second: stmt.setLong(2, TimeUtility.SECOND_IN_MS-1); break; + case minute: stmt.setLong(2, TimeUtility.MINUTE_IN_MS-1); break; + case fiveMinutes: stmt.setLong(2, TimeUtility.FIVE_MINUTES_IN_MS-1); break; + case fifteenMinutes: stmt.setLong(2, TimeUtility.FIFTEEN_MINUTES_IN_MS-1); break; + case hour: stmt.setLong(2, TimeUtility.HOUR_IN_MS-1); break; + case day: stmt.setLong(2, TimeUtility.DAY_IN_MS-1); break; + case week: stmt.setLong(2, TimeUtility.WEEK_IN_MS-1); break; + default: logger.warning("aggregation period length is not supported."); return; + } Long maxTimestampFoundForSensor = DBConnection.exec(stmt, new SimpleSQLResult()); if(maxTimestampFoundForSensor == null) maxTimestampFoundForSensor = 0l; - long currentPeriodStartTimestamp = TimeUtility.getTimestampPeriodStart_UTC(toPeriodSizeInMs, System.currentTimeMillis()); + long currentPeriodStartTimestamp = TimeUtility.getTimestampPeriodStart_UTC(aggrPeriodLength, System.currentTimeMillis()); logger.fine("Calculating periods... (from:"+ maxTimestampFoundForSensor +", to:"+ currentPeriodStartTimestamp +") with expected sample count: " + expectedSampleCount); @@ -98,7 +118,7 @@ public class SensorDataAggregatorDaemon implements HalDaemon { stmt.setLong(2, maxTimestampFoundForSensor); stmt.setLong(3, currentPeriodStartTimestamp); stmt.setLong(4, System.currentTimeMillis()-ageLimitInMs); - DBConnection.exec(stmt, new DataAggregator(sensorId, toPeriodSizeInMs, expectedSampleCount, aggrMethod)); + DBConnection.exec(stmt, new DataAggregator(sensorId, aggrPeriodLength, expectedSampleCount, aggrMethod)); } catch (SQLException e) { logger.log(Level.SEVERE, null, e); } @@ -108,14 +128,14 @@ public class SensorDataAggregatorDaemon implements HalDaemon { * Internal class for aggregating data to the aggregated DB table */ private class DataAggregator implements SQLResultHandler{ - private long sensorId = -1; - private long aggrTimeInMs = -1; - private int expectedSampleCount = -1; - private AggregationMethod aggrMethod = null; + private final long sensorId; + private final AggregationPeriodLength aggrPeriodLength; + private final int expectedSampleCount; + private final AggregationMethod aggrMethod; - public DataAggregator(long sensorId, long aggrTimeInMs, int expectedSampleCount, AggregationMethod aggrMethod) { + public DataAggregator(long sensorId, AggregationPeriodLength aggrPeriodLength, int expectedSampleCount, AggregationMethod aggrMethod) { this.sensorId = sensorId; - this.aggrTimeInMs = aggrTimeInMs; + this.aggrPeriodLength = aggrPeriodLength; this.expectedSampleCount = expectedSampleCount; this.aggrMethod = aggrMethod; } @@ -125,8 +145,9 @@ public class SensorDataAggregatorDaemon implements HalDaemon { try{ HalContext.getDB().getConnection().setAutoCommit(false); - long currentPeriodTimestamp = 0; - int sum = 0; + long currentPeriodTimestampStart = 0; + long currentPeriodTimestampEnd = 0; + float sum = 0; float confidenceSum = 0; int samples = 0; long highestSequenceId = Sensor.getHighestSequenceId(sensorId); @@ -137,35 +158,43 @@ public class SensorDataAggregatorDaemon implements HalDaemon { throw new IllegalArgumentException("found entry for aggregation for the wrong sensorId (expecting: "+sensorId+", but was: "+result.getInt("sensor_id")+")"); } long timestamp = result.getLong("timestamp"); - long periodTimestamp = TimeUtility.getTimestampPeriodStart_UTC(this.aggrTimeInMs, timestamp); - if(currentPeriodTimestamp != 0 && periodTimestamp != currentPeriodTimestamp){ + long dataPeriodTimestampStart = TimeUtility.getTimestampPeriodStart_UTC(this.aggrPeriodLength, timestamp); + long dataPerionTimestampEnd = TimeUtility.getTimestampPeriodEnd_UTC(this.aggrPeriodLength, timestamp); + + if(currentPeriodTimestampStart != 0 && currentPeriodTimestampEnd != 0 && dataPeriodTimestampStart != currentPeriodTimestampStart){ float aggrConfidence = confidenceSum / (float)this.expectedSampleCount; float data = -1; switch(aggrMethod){ case SUM: data = sum; break; case AVERAGE: data = sum/samples; break; } - logger.finer("Calculated period starting at timestamp: " + currentPeriodTimestamp + ", data: " + sum + ", confidence: " + aggrConfidence + ", samples: " + samples + ", aggrMethod: " + aggrMethod); + logger.finer("Calculated period starting at timestamp: " + currentPeriodTimestampStart + ", data: " + sum + ", confidence: " + aggrConfidence + ", samples: " + samples + ", aggrMethod: " + aggrMethod); preparedInsertStmt.setInt(1, result.getInt("sensor_id")); preparedInsertStmt.setLong(2, ++highestSequenceId); - preparedInsertStmt.setLong(3, currentPeriodTimestamp); - preparedInsertStmt.setLong(4, currentPeriodTimestamp + this.aggrTimeInMs - 1); + preparedInsertStmt.setLong(3, currentPeriodTimestampStart); + preparedInsertStmt.setLong(4, currentPeriodTimestampEnd); preparedInsertStmt.setFloat(5, data); preparedInsertStmt.setFloat(6, aggrConfidence); preparedInsertStmt.addBatch(); // Reset variables - currentPeriodTimestamp = periodTimestamp; + currentPeriodTimestampStart = dataPeriodTimestampStart; + currentPeriodTimestampEnd = dataPerionTimestampEnd; confidenceSum = 0; sum = 0; samples = 0; } - if(currentPeriodTimestamp == 0) currentPeriodTimestamp = periodTimestamp; - sum += result.getInt("data"); + + if(currentPeriodTimestampStart == 0){ + currentPeriodTimestampStart = dataPeriodTimestampStart; + } + if(currentPeriodTimestampEnd == 0){ + currentPeriodTimestampEnd = dataPerionTimestampEnd; + } + sum += result.getFloat("data"); confidenceSum += result.getFloat("confidence"); ++samples; } - DBConnection.execBatch(preparedInsertStmt); HalContext.getDB().getConnection().commit(); diff --git a/src/se/hal/deamon/SensorDataCleanupDaemon.java b/src/se/hal/deamon/SensorDataCleanupDaemon.java index d113c048..0c2f9f31 100755 --- a/src/se/hal/deamon/SensorDataCleanupDaemon.java +++ b/src/se/hal/deamon/SensorDataCleanupDaemon.java @@ -1,6 +1,7 @@ package se.hal.deamon; import se.hal.HalContext; +import se.hal.deamon.SensorDataAggregatorDaemon.AggregationPeriodLength; import se.hal.intf.HalDaemon; import se.hal.struct.Sensor; import se.hal.util.TimeUtility; @@ -41,10 +42,10 @@ public class SensorDataCleanupDaemon implements HalDaemon { public void cleanupSensor(Sensor sensor) { if (sensor.getUser() != null) { - cleanupSensorData(sensor.getId(), TimeUtility.FIVE_MINUTES_IN_MS, TimeUtility.DAY_IN_MS); //clear 5-minute data older than a day - cleanupSensorData(sensor.getId(), TimeUtility.HOUR_IN_MS, TimeUtility.WEEK_IN_MS); //clear 1-hour data older than a week - //cleanupSensorData(sensor.getId(), TimeUtility.DAY_IN_MS, TimeUtility.INFINITY); //clear 1-day data older than infinity - //cleanupSensorData(sensor.getId(), TimeUtility.WEEK_IN_MS, TimeUtility.INFINITY); //clear 1-week data older than infinity + cleanupSensorData(sensor.getId(), AggregationPeriodLength.fiveMinutes, TimeUtility.DAY_IN_MS); //clear 5-minute data older than a day + cleanupSensorData(sensor.getId(), AggregationPeriodLength.hour, TimeUtility.WEEK_IN_MS); //clear 1-hour data older than a week + //cleanupSensorData(sensor.getId(), AggregationPeriodLength.day, TimeUtility.INFINITY); //clear 1-day data older than infinity + //cleanupSensorData(sensor.getId(), AggregationPeriodLength.week, TimeUtility.INFINITY); //clear 1-week data older than infinity } } @@ -56,7 +57,7 @@ public class SensorDataCleanupDaemon implements HalDaemon { * @Param clearPeriodlength Will clear periods with this length * @param olderThan Data must be older than this many ms to be cleared from the DB */ - private void cleanupSensorData(long sensorId, long clearPeriodlength, long olderThan){ + private void cleanupSensorData(long sensorId, AggregationPeriodLength cleanupPeriodlength, long olderThan){ DBConnection db = HalContext.getDB(); PreparedStatement stmt = null; try { @@ -66,7 +67,16 @@ public class SensorDataCleanupDaemon implements HalDaemon { + "AND timestamp_end-timestamp_start == ?" + "AND timestamp_end < ?"); stmt.setLong(1, sensorId); - stmt.setLong(2, clearPeriodlength-1); + switch(cleanupPeriodlength){ + case second: stmt.setLong(2, TimeUtility.SECOND_IN_MS-1); break; + case minute: stmt.setLong(2, TimeUtility.MINUTE_IN_MS-1); break; + case fiveMinutes: stmt.setLong(2, TimeUtility.FIVE_MINUTES_IN_MS-1); break; + case fifteenMinutes: stmt.setLong(2, TimeUtility.FIFTEEN_MINUTES_IN_MS-1); break; + case hour: stmt.setLong(2, TimeUtility.HOUR_IN_MS-1); break; + case day: stmt.setLong(2, TimeUtility.DAY_IN_MS-1); break; + case week: stmt.setLong(2, TimeUtility.WEEK_IN_MS-1); break; + default: logger.warning("cleanup period length is not supported."); return; + } stmt.setLong(3, System.currentTimeMillis()-olderThan); DBConnection.exec(stmt, new AggregateDataDeleter(sensorId)); } catch (SQLException e) { @@ -91,7 +101,7 @@ public class SensorDataCleanupDaemon implements HalDaemon { if(sensorId != result.getInt("sensor_id")){ throw new IllegalArgumentException("Found entry for aggregation for the wrong sensorId (expecting: "+sensorId+", but was: "+result.getInt("sensor_id")+")"); } - logger.finer("Deleting sensor(id: "+ sensorId +") aggregate entry timestamp: "+ result.getLong("timestamp_start") +" - "+ result.getLong("timestamp_end") + " (" + TimeUtility.msToString(result.getLong("timestamp_end")-result.getLong("timestamp_start")) + ")"); + logger.finer("Deleting sensor(id: "+ sensorId +") aggregate entry timestamp: "+ result.getLong("timestamp_start") +" - "+ result.getLong("timestamp_end") + " (" + TimeUtility.timeInMsToString(result.getLong("timestamp_end")-result.getLong("timestamp_start")) + ")"); preparedDeleteStmt.setInt(1, result.getInt("sensor_id")); preparedDeleteStmt.setLong(2, result.getLong("sequence_id")); preparedDeleteStmt.addBatch(); diff --git a/src/se/hal/page/PCOverviewHttpPage.java b/src/se/hal/page/PCOverviewHttpPage.java index 9230e432..ed05dc9e 100755 --- a/src/se/hal/page/PCOverviewHttpPage.java +++ b/src/se/hal/page/PCOverviewHttpPage.java @@ -1,9 +1,11 @@ package se.hal.page; import se.hal.HalContext; +import se.hal.deamon.SensorDataAggregatorDaemon.AggregationPeriodLength; import se.hal.intf.HalHttpPage; import se.hal.util.AggregateDataListSqlResult; import se.hal.util.AggregateDataListSqlResult.*; +import se.hal.util.TimeUtility; import se.hal.struct.Sensor; import se.hal.struct.User; import zutil.db.DBConnection; @@ -41,13 +43,13 @@ public class PCOverviewHttpPage extends HalHttpPage { for(User user : users){ List userSensors = Sensor.getSensors(db, user); for(Sensor sensor : userSensors){ - minDataList.addAll(AggregateDataListSqlResult.getFiveMinuteAggregateData(db, sensor)); + minDataList.addAll(AggregateDataListSqlResult.getAggregateDataForPeriod(db, sensor, AggregationPeriodLength.fiveMinutes, TimeUtility.DAY_IN_MS)); - hourDataList.addAll(AggregateDataListSqlResult.getHourAggregateData(db, sensor)); + hourDataList.addAll(AggregateDataListSqlResult.getAggregateDataForPeriod(db, sensor, AggregationPeriodLength.hour, TimeUtility.WEEK_IN_MS)); - dayDataList.addAll(AggregateDataListSqlResult.getDayAggregateData(db, sensor)); + dayDataList.addAll(AggregateDataListSqlResult.getAggregateDataForPeriod(db, sensor, AggregationPeriodLength.day, TimeUtility.INFINITY)); - weekDataList.addAll(AggregateDataListSqlResult.getWeekAggregateData(db, sensor)); + weekDataList.addAll(AggregateDataListSqlResult.getAggregateDataForPeriod(db, sensor, AggregationPeriodLength.week, TimeUtility.INFINITY)); } } diff --git a/src/se/hal/page/SensorOverviewHttpPage.java b/src/se/hal/page/SensorOverviewHttpPage.java index 9a8ee2cb..c6ff0efd 100755 --- a/src/se/hal/page/SensorOverviewHttpPage.java +++ b/src/se/hal/page/SensorOverviewHttpPage.java @@ -1,15 +1,14 @@ package se.hal.page; -import se.hal.ControllerManager; import se.hal.HalContext; +import se.hal.deamon.SensorDataAggregatorDaemon.AggregationPeriodLength; import se.hal.intf.HalHttpPage; -import se.hal.struct.Event; import se.hal.struct.Sensor; -import se.hal.struct.SwitchEventData; import se.hal.util.AggregateDataListSqlResult; import zutil.db.DBConnection; import se.hal.util.HistoryDataListSqlResult; import se.hal.util.HistoryDataListSqlResult.*; +import se.hal.util.TimeUtility; import zutil.io.file.FileUtil; import zutil.parser.Templator; @@ -52,7 +51,7 @@ public class SensorOverviewHttpPage extends HalHttpPage { Templator tmpl = new Templator(FileUtil.find(DETAIL_TEMPLATE)); tmpl.set("sensor", sensor); tmpl.set("history", history); - tmpl.set("aggregation", AggregateDataListSqlResult.getHourAggregateData(db, sensor)); + tmpl.set("aggregation", AggregateDataListSqlResult.getAggregateDataForPeriod(db, sensor, AggregationPeriodLength.hour, TimeUtility.WEEK_IN_MS)); return tmpl; } else { diff --git a/src/se/hal/util/AggregateDataListSqlResult.java b/src/se/hal/util/AggregateDataListSqlResult.java index 346ba86f..154dad9c 100755 --- a/src/se/hal/util/AggregateDataListSqlResult.java +++ b/src/se/hal/util/AggregateDataListSqlResult.java @@ -1,5 +1,6 @@ package se.hal.util; +import se.hal.deamon.SensorDataAggregatorDaemon.AggregationPeriodLength; import se.hal.struct.Sensor; import zutil.db.DBConnection; import zutil.db.SQLResultHandler; @@ -23,32 +24,14 @@ public class AggregateDataListSqlResult implements SQLResultHandler getFiveMinuteAggregateData(DBConnection db, Sensor sensor) throws SQLException { - return getAggregateDataForPeriod(db, sensor, TimeUtility.FIVE_MINUTES_IN_MS, TimeUtility.DAY_IN_MS); - } - - public static List getHourAggregateData(DBConnection db, Sensor sensor) throws SQLException { - return getAggregateDataForPeriod(db, sensor, TimeUtility.HOUR_IN_MS, TimeUtility.WEEK_IN_MS); - } - - public static List getDayAggregateData(DBConnection db, Sensor sensor) throws SQLException { - return getAggregateDataForPeriod(db, sensor, TimeUtility.DAY_IN_MS, TimeUtility.INFINITY); - } - - public static List getWeekAggregateData(DBConnection db, Sensor sensor) throws SQLException { - return getAggregateDataForPeriod(db, sensor, TimeUtility.WEEK_IN_MS, TimeUtility.INFINITY); - } - private static List getAggregateDataForPeriod(DBConnection db, Sensor sensor, long periodLengthInMs, long ageLimitInMs) throws SQLException { + public static List getAggregateDataForPeriod(DBConnection db, Sensor sensor, AggregationPeriodLength aggrPeriodLength, long ageLimitInMs) throws SQLException { PreparedStatement stmt = db.getPreparedStatement( "SELECT user.username as username," + " sensor_data_aggr.timestamp_start as timestamp_start," + " sensor_data_aggr.timestamp_end as timestamp_end," + " sensor_data_aggr.data as data," - + " sensor_data_aggr.confidence as confidence," - + periodLengthInMs + " as period_length" + + " sensor_data_aggr.confidence as confidence " + " FROM sensor_data_aggr, user, sensor" + " WHERE sensor.id = sensor_data_aggr.sensor_id" + " AND sensor.id = ?" @@ -59,7 +42,16 @@ public class AggregateDataListSqlResult implements SQLResultHandler 0.5 ? estimatedData : null); //only present data with a confidence over 50% //add null data point to list if one or more periods of data is missing before this - if(previousTimestampEnd != -1 && timestampStart-previousTimestampEnd > periodLength){ + if(previousTimestampEnd != -1 && previousTimestampEnd+1 < timestampStart){ list.add(new AggregateData(previousTimestampEnd+1, "null", username)); } - list.add(new AggregateData(timestampStart, ""+ (data/1000.0), username)); //add this data point to list + list.add(new AggregateData(timestampStart, ""+ (estimatedData/1000.0), username)); //add this data point to list //update previous end timestamp previousTimestampEnd = timestampEnd; diff --git a/src/se/hal/util/TimeUtility.java b/src/se/hal/util/TimeUtility.java index dc601849..64145d7f 100755 --- a/src/se/hal/util/TimeUtility.java +++ b/src/se/hal/util/TimeUtility.java @@ -3,146 +3,210 @@ package se.hal.util; import java.util.Calendar; import java.util.TimeZone; -public class TimeUtility { +import se.hal.deamon.SensorDataAggregatorDaemon.AggregationPeriodLength; + +public class TimeUtility { public static final long SECOND_IN_MS = 1000; - public static final long MINUTES_IN_MS = SECOND_IN_MS * 60; - public static final long FIVE_MINUTES_IN_MS = MINUTES_IN_MS * 5; - public static final long HOUR_IN_MS = MINUTES_IN_MS * 60; + public static final long MINUTE_IN_MS = SECOND_IN_MS * 60; + public static final long FIVE_MINUTES_IN_MS = MINUTE_IN_MS * 5; + public static final long FIFTEEN_MINUTES_IN_MS = MINUTE_IN_MS * 15; + public static final long HOUR_IN_MS = MINUTE_IN_MS * 60; public static final long DAY_IN_MS = HOUR_IN_MS * 24; public static final long WEEK_IN_MS = DAY_IN_MS * 7; public static final long INFINITY = Long.MAX_VALUE; //sort of true - - public static long getTimestampPeriodStart_UTC(long periodLengthInMs, long timestamp) throws NumberFormatException{ - //return timestamp - (timestamp % periodLengthInMs); - return getTimestampPeriodStart(periodLengthInMs, timestamp, Calendar.getInstance(TimeZone.getTimeZone("UTC"))); - } - - /** - * Get the timstamp for the given timestamp floored with the period length. The result should point to the beginning of the timestamps period. - * @param periodLengthInMs The periods length to floor the timestamp with - * @param timestamp The timestamp to floor. - * @return - */ - public static long getTimestampPeriodStart_LOCAL(long periodLengthInMs, long timestamp) throws NumberFormatException{ - return getTimestampPeriodStart(periodLengthInMs, timestamp, Calendar.getInstance()); - } - private static long getTimestampPeriodStart(long periodLengthInMs, long timestamp, Calendar cal) throws NumberFormatException{ - if(periodLengthInMs < 0 || timestamp < 0) - throw new NumberFormatException("argument must be positive"); - + public static long getTimestampPeriodStart_UTC(AggregationPeriodLength aggrPeriodLength, long timestamp) throws NumberFormatException{ + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); cal.setTimeInMillis(timestamp); - boolean clear = false; - - int weeks = getWeeksFromTimestamp(periodLengthInMs); - if(weeks > 0){ - int currentWeek = cal.get(Calendar.WEEK_OF_YEAR); - cal.set(Calendar.WEEK_OF_YEAR, (currentWeek/weeks)*weeks); - clear = true; + switch(aggrPeriodLength){ + case year: + cal.set(Calendar.DAY_OF_YEAR, 1); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + break; + case month: + cal.set(Calendar.DAY_OF_MONTH, 1); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + break; + case week: + cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + break; + case day: + cal.set(Calendar.HOUR_OF_DAY, 0); + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + break; + case hour: + cal.set(Calendar.MINUTE, 0); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + break; + case fiveMinutes: + cal.set(Calendar.MINUTE, (cal.get(Calendar.MINUTE)/5)*5); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + break; + case fifteenMinutes: + cal.set(Calendar.MINUTE, (cal.get(Calendar.MINUTE)/15)*15); + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + break; + case minute: + cal.set(Calendar.SECOND, 0); + cal.set(Calendar.MILLISECOND, 0); + break; + case second: + cal.set(Calendar.MILLISECOND, 0); + break; } - - int days = getDaysFromTimestamp(periodLengthInMs); - if(days%7 > 0){ - int currentDay = cal.get(Calendar.DAY_OF_YEAR); - cal.set(Calendar.DAY_OF_YEAR, (currentDay/days)*days); - clear = true; - }else if(clear){ - cal.set(Calendar.DAY_OF_WEEK, Calendar.MONDAY); - } - - int hours = getHourOfDayFromTimestamp(periodLengthInMs); - if(hours > 0){ - int currentHour = cal.get(Calendar.HOUR_OF_DAY); - cal.set(Calendar.HOUR_OF_DAY, (currentHour/hours)*hours); - clear = true; - }else if(clear){ - cal.set(Calendar.HOUR_OF_DAY, 0); - } - - int minutes = getMinuteOfHourFromTimestamp(periodLengthInMs); - if(minutes > 0){ - int currentMinute = cal.get(Calendar.MINUTE); - cal.set(Calendar.MINUTE, (currentMinute/minutes)*minutes); - clear = true; - }else if(clear){ - cal.set(Calendar.MINUTE, 0); - } - - int seconds = getSecondOfMinuteFromTimestamp(periodLengthInMs); - if(seconds > 0){ - int currentSecond = cal.get(Calendar.SECOND); - cal.set(Calendar.SECOND, (currentSecond/seconds)*seconds); - clear = true; - }else if(clear){ - cal.set(Calendar.SECOND, 0); - } - - int milliseconds = getMillisecondInSecondFromTimestamp(periodLengthInMs); - if(milliseconds > 0){ - int currentMillisecond = cal.get(Calendar.MILLISECOND); - cal.set(Calendar.MILLISECOND, (currentMillisecond/milliseconds)*milliseconds); - }else if(clear){ - cal.set(Calendar.MILLISECOND, 0); - } - return cal.getTimeInMillis(); } + public static long getTimestampPeriodEnd_UTC(AggregationPeriodLength aggrPeriodLength, long timestamp) throws NumberFormatException{ + long start = getTimestampPeriodStart_UTC(aggrPeriodLength, timestamp); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + cal.setTimeInMillis(start); + switch(aggrPeriodLength){ + case year: + cal.add(Calendar.YEAR, 1); + break; + case month: + cal.add(Calendar.MONTH, 1); + break; + case week: + cal.add(Calendar.WEEK_OF_YEAR, 1); + break; + case day: + cal.add(Calendar.DAY_OF_YEAR, 1); + break; + case hour: + cal.add(Calendar.HOUR, 1); + break; + case fiveMinutes: + cal.add(Calendar.MINUTE, 5); + break; + case fifteenMinutes: + cal.add(Calendar.MINUTE, 15); + break; + case minute: + cal.add(Calendar.MINUTE, 1); + break; + case second: + cal.add(Calendar.SECOND, 1); + break; + } + return cal.getTimeInMillis()-1; //subtract one + } + public static int getMillisecondInSecondFromTimestamp(long ms) throws NumberFormatException{ if(ms < 0) throw new NumberFormatException("argument must be positive"); - return (int) (ms % SECOND_IN_MS); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + cal.setTimeInMillis(ms); + return cal.get(Calendar.MILLISECOND); } public static int getSecondOfMinuteFromTimestamp(long ms) throws NumberFormatException{ if(ms < 0) throw new NumberFormatException("argument must be positive"); - return (int) ((ms % MINUTES_IN_MS) / SECOND_IN_MS); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + cal.setTimeInMillis(ms); + return cal.get(Calendar.SECOND); } public static int getMinuteOfHourFromTimestamp(long ms) throws NumberFormatException{ if(ms < 0) throw new NumberFormatException("argument must be positive"); - return (int) ((ms % HOUR_IN_MS) / MINUTES_IN_MS); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + cal.setTimeInMillis(ms); + return cal.get(Calendar.MINUTE); } public static int getHourOfDayFromTimestamp(long ms) throws NumberFormatException{ if(ms < 0) throw new NumberFormatException("argument must be positive"); - return (int) ((ms % DAY_IN_MS) / HOUR_IN_MS); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + cal.setTimeInMillis(ms); + return cal.get(Calendar.HOUR_OF_DAY); } - public static int getDaysFromTimestamp(long ms) throws NumberFormatException{ + public static int getDayOfWeekFromTimestamp(long ms) throws NumberFormatException{ if(ms < 0) throw new NumberFormatException("argument must be positive"); - return (int) (ms / DAY_IN_MS); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + cal.setTimeInMillis(ms); + return cal.get(Calendar.DAY_OF_WEEK); } - public static int getWeeksFromTimestamp(long ms) throws NumberFormatException{ + public static int getDayOfMonthFromTimestamp(long ms) throws NumberFormatException{ if(ms < 0) throw new NumberFormatException("argument must be positive"); - return (int) (ms / WEEK_IN_MS); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + cal.setTimeInMillis(ms); + return cal.get(Calendar.DAY_OF_MONTH); } - public static String msToString(long ms) throws NumberFormatException{ + public static int getDayOfYearFromTimestamp(long ms) throws NumberFormatException{ + if(ms < 0) + throw new NumberFormatException("argument must be positive"); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + cal.setTimeInMillis(ms); + return cal.get(Calendar.DAY_OF_YEAR); + } + + public static int getWeekOfYearFromTimestamp(long ms) throws NumberFormatException{ + if(ms < 0) + throw new NumberFormatException("argument must be positive"); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + cal.setTimeInMillis(ms); + return cal.get(Calendar.WEEK_OF_YEAR); + } + + public static int getMonthOfYearFromTimestamp(long ms) throws NumberFormatException{ + if(ms < 0) + throw new NumberFormatException("argument must be positive"); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + cal.setTimeInMillis(ms); + return cal.get(Calendar.MONTH); + } + + public static int getYearFromTimestamp(long ms) throws NumberFormatException{ + if(ms < 0) + throw new NumberFormatException("argument must be positive"); + Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC")); + cal.setTimeInMillis(ms); + return cal.get(Calendar.YEAR); + } + + public static String timeInMsToString(long ms) throws NumberFormatException{ if(ms < 0) throw new NumberFormatException("argument must be positive"); String retval = ""; - int weeks = getWeeksFromTimestamp(ms); + int weeks = (int) (ms / WEEK_IN_MS); if(weeks > 0){ retval += weeks + "w+"; } - int days = getDaysFromTimestamp(ms) % 7; + int days = ((int) (ms / DAY_IN_MS)) % 7; if(days > 0){ retval += days + "d+"; } - int hours = getHourOfDayFromTimestamp(ms); + int hours = (int) ((ms % DAY_IN_MS) / HOUR_IN_MS); retval += (hours<10?"0"+hours:hours); - int minutes = getMinuteOfHourFromTimestamp(ms); + int minutes = (int) ((ms % HOUR_IN_MS) / MINUTE_IN_MS); retval += ":" + (minutes<10?"0"+minutes:minutes); - int seconds = getSecondOfMinuteFromTimestamp(ms); + int seconds = (int) ((ms % MINUTE_IN_MS) / SECOND_IN_MS); retval += ":" + (seconds<10?"0"+seconds:seconds); - int milliseconds = getMillisecondInSecondFromTimestamp(ms); + int milliseconds = (int) (ms % SECOND_IN_MS); retval += "." + (milliseconds<100?"0"+(milliseconds<10?"0"+milliseconds:milliseconds):milliseconds); return retval; } diff --git a/test/se/hal/util/TimeUtilityTest.java b/test/se/hal/util/TimeUtilityTest.java index 64f28f8d..097c3208 100755 --- a/test/se/hal/util/TimeUtilityTest.java +++ b/test/se/hal/util/TimeUtilityTest.java @@ -2,199 +2,302 @@ package se.hal.util; import org.junit.Before; import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.junit.runners.Parameterized.Parameters; +import se.hal.deamon.SensorDataAggregatorDaemon.AggregationPeriodLength; + +import java.util.Arrays; import java.util.Calendar; +import java.util.Collection; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; +@RunWith(Parameterized.class) public class TimeUtilityTest { - private long currentTime_UTC; - private Calendar referenceCalendar_LOCAL; + private final long currentTime_UTC; + + + /** + * Constructor + * @param timestamp + */ + public TimeUtilityTest(long timestamp){ + this.currentTime_UTC = timestamp; + } + + @Parameters + public static Collection data(){ + return Arrays.asList(new Object[][] { + {TimeUtility.WEEK_IN_MS}, //a week after 1970-01-01 00:00:00 + {694224000000L-1}, //1991-12-31 23:59:59.999 GMT + {694224000000L}, //1992-01-01 00:00:00.000 GMT + {1456704000000L}, //2016-02-29 00:00:00.000 GMT (leap day) + {1456749808000L}, //2016-02-29 12:43:28.000 GMT (leap day) + {1456790399999L}, //2016-02-29 23:59:59.999 GMT (leap day) + {System.currentTimeMillis()}, //current time + {System.currentTimeMillis()+TimeUtility.MINUTE_IN_MS}, //current time + 1m + {System.currentTimeMillis()+(2*TimeUtility.MINUTE_IN_MS)}, //current time + 2m + {System.currentTimeMillis()+(3*TimeUtility.MINUTE_IN_MS)}, //current time + 3m + {System.currentTimeMillis()+(4*TimeUtility.MINUTE_IN_MS)}, //current time + 4m + {System.currentTimeMillis()+(5*TimeUtility.MINUTE_IN_MS)}, //current time + 5m + {System.currentTimeMillis()+(6*TimeUtility.MINUTE_IN_MS)}, //current time + 6m + {System.currentTimeMillis()+(7*TimeUtility.MINUTE_IN_MS)}, //current time + 7m + {Long.MAX_VALUE-(60*TimeUtility.WEEK_IN_MS)}, //max time - 60w + }); + } @Before - public void setup(){ - currentTime_UTC = System.currentTimeMillis(); - referenceCalendar_LOCAL = Calendar.getInstance(); - referenceCalendar_LOCAL.setTimeInMillis(currentTime_UTC); + public void printCurrentTimeStamp(){ + System.out.println("Testing with timestamp: " + currentTime_UTC); } - // Test flooring LOCAL time to the closes day + // Test flooring & ceiling UTC time to the closes year @Test - public void testWeekStart_LOCAL_ForCurrentTime(){ - long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_LOCAL(TimeUtility.WEEK_IN_MS, currentTime_UTC); - Calendar testCalendar = Calendar.getInstance(); - testCalendar.setTimeInMillis(thisPeriodStartedAt); - - assertEquals("millisecond is wrong", 0, testCalendar.get(Calendar.MILLISECOND)); - assertEquals("second is wrong", 0, testCalendar.get(Calendar.SECOND)); - assertEquals("minute is wrong", 0, testCalendar.get(Calendar.MINUTE)); - assertEquals("hour is wrong", 0, testCalendar.get(Calendar.HOUR_OF_DAY)); - assertTrue("day is wrong", Math.abs(referenceCalendar_LOCAL.get(Calendar.DAY_OF_YEAR)-testCalendar.get(Calendar.DAY_OF_YEAR)) <= 6); //day cannot differ more than 6 days - assertEquals("week is wrong", referenceCalendar_LOCAL.get(Calendar.WEEK_OF_YEAR), testCalendar.get(Calendar.WEEK_OF_YEAR)); - } - - // Test flooring LOCAL time to the closes day - @Test - public void testDayStart_LOCAL_ForCurrentTime(){ - long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_LOCAL(TimeUtility.DAY_IN_MS, currentTime_UTC); - Calendar testCalendar = Calendar.getInstance(); - testCalendar.setTimeInMillis(thisPeriodStartedAt); - - assertEquals("millisecond is wrong", 0, testCalendar.get(Calendar.MILLISECOND)); - assertEquals("second is wrong", 0, testCalendar.get(Calendar.SECOND)); - assertEquals("minute is wrong", 0, testCalendar.get(Calendar.MINUTE)); - assertEquals("hour is wrong", 0, testCalendar.get(Calendar.HOUR_OF_DAY)); - assertEquals("day is wrong", referenceCalendar_LOCAL.get(Calendar.DAY_OF_YEAR), testCalendar.get(Calendar.DAY_OF_YEAR)); - assertEquals("week is wrong", referenceCalendar_LOCAL.get(Calendar.WEEK_OF_YEAR), testCalendar.get(Calendar.WEEK_OF_YEAR)); - } - - // Test flooring LOCAL time to the closes hour - @Test - public void testHourStart_LOCAL_ForCurrentTime(){ - long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_LOCAL(TimeUtility.HOUR_IN_MS, currentTime_UTC); - Calendar testCalendar = Calendar.getInstance(); - testCalendar.setTimeInMillis(thisPeriodStartedAt); - - assertEquals("millisecond is wrong", 0, testCalendar.get(Calendar.MILLISECOND)); - assertEquals("second is wrong", 0, testCalendar.get(Calendar.SECOND)); - assertEquals("minute is wrong", 0, testCalendar.get(Calendar.MINUTE)); - assertEquals("hour is wrong", referenceCalendar_LOCAL.get(Calendar.HOUR_OF_DAY), testCalendar.get(Calendar.HOUR_OF_DAY)); - assertEquals("day is wrong", referenceCalendar_LOCAL.get(Calendar.DAY_OF_YEAR), testCalendar.get(Calendar.DAY_OF_YEAR)); - assertEquals("week is wrong", referenceCalendar_LOCAL.get(Calendar.WEEK_OF_YEAR), testCalendar.get(Calendar.WEEK_OF_YEAR)); - } - - // Test flooring LOCAL time to the closes minute - @Test - public void testMinuteStart_LOCAL_ForCurrentTime(){ - long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_LOCAL(TimeUtility.MINUTES_IN_MS, currentTime_UTC); - Calendar testCalendar = Calendar.getInstance(); - testCalendar.setTimeInMillis(thisPeriodStartedAt); - - assertEquals("millisecond is wrong", 0, testCalendar.get(Calendar.MILLISECOND)); - assertEquals("second is wrong", 0, testCalendar.get(Calendar.SECOND)); - assertEquals("minute is wrong", referenceCalendar_LOCAL.get(Calendar.MINUTE), testCalendar.get(Calendar.MINUTE)); - assertEquals("hour is wrong", referenceCalendar_LOCAL.get(Calendar.HOUR_OF_DAY), testCalendar.get(Calendar.HOUR_OF_DAY)); - assertEquals("day is wrong", referenceCalendar_LOCAL.get(Calendar.DAY_OF_YEAR), testCalendar.get(Calendar.DAY_OF_YEAR)); - assertEquals("week is wrong", referenceCalendar_LOCAL.get(Calendar.WEEK_OF_YEAR), testCalendar.get(Calendar.WEEK_OF_YEAR)); - } - - // Test flooring LOCAL time to the closes second - @Test - public void testSecondStart_LOCAL_ForCurrentTime(){ - long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_LOCAL(TimeUtility.SECOND_IN_MS, currentTime_UTC); - Calendar testCalendar = Calendar.getInstance(); - testCalendar.setTimeInMillis(thisPeriodStartedAt); - - assertEquals("millisecond is wrong", 0, testCalendar.get(Calendar.MILLISECOND)); - assertEquals("second is wrong", referenceCalendar_LOCAL.get(Calendar.SECOND), testCalendar.get(Calendar.SECOND)); - assertEquals("minute is wrong", referenceCalendar_LOCAL.get(Calendar.MINUTE), testCalendar.get(Calendar.MINUTE)); - assertEquals("hour is wrong", referenceCalendar_LOCAL.get(Calendar.HOUR_OF_DAY), testCalendar.get(Calendar.HOUR_OF_DAY)); - assertEquals("day is wrong", referenceCalendar_LOCAL.get(Calendar.DAY_OF_YEAR), testCalendar.get(Calendar.DAY_OF_YEAR)); - assertEquals("week is wrong", referenceCalendar_LOCAL.get(Calendar.WEEK_OF_YEAR), testCalendar.get(Calendar.WEEK_OF_YEAR)); - } - - // Test flooring UTC time to the closes week - @Test - public void testWeekStart_UTC_ForCurrentTime(){ - long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_UTC(TimeUtility.WEEK_IN_MS, currentTime_UTC); - + public void testYear_UTC(){ + long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_UTC(AggregationPeriodLength.year, currentTime_UTC); assertEquals("millisecond is wrong", 0, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodStartedAt)); assertEquals("second is wrong", 0, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodStartedAt)); assertEquals("minute is wrong", 0, TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodStartedAt)); assertEquals("hour is wrong", 0, TimeUtility.getHourOfDayFromTimestamp(thisPeriodStartedAt)); - assertTrue("day is wrong", Math.abs(TimeUtility.getDaysFromTimestamp(currentTime_UTC)-TimeUtility.getDaysFromTimestamp(thisPeriodStartedAt)) <= 6); //day cannot differ more than 6 days - assertEquals("week is wrong", TimeUtility.getWeeksFromTimestamp(currentTime_UTC), TimeUtility.getWeeksFromTimestamp(thisPeriodStartedAt)); + assertEquals("day is wrong", 1, TimeUtility.getDayOfYearFromTimestamp(thisPeriodStartedAt)); + assertEquals("month is wrong", Calendar.JANUARY, TimeUtility.getMonthOfYearFromTimestamp(thisPeriodStartedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodStartedAt)); + + long thisPeriodEndedAt = TimeUtility.getTimestampPeriodEnd_UTC(AggregationPeriodLength.year, currentTime_UTC); + assertEquals("millisecond is wrong", 999, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodEndedAt)); + assertEquals("second is wrong", 59, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodEndedAt)); + assertEquals("minute is wrong", 59, TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodEndedAt)); + assertEquals("hour is wrong", 23, TimeUtility.getHourOfDayFromTimestamp(thisPeriodEndedAt)); + assertEquals("day is wrong", 31, TimeUtility.getDayOfMonthFromTimestamp(thisPeriodEndedAt)); + assertEquals("month is wrong", Calendar.DECEMBER, TimeUtility.getMonthOfYearFromTimestamp(thisPeriodEndedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodEndedAt)); } - // Test flooring UTC time to the closes day + // Test flooring & ceiling UTC time to the closes month @Test - public void testDayStart_UTC_ForCurrentTime(){ - long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_UTC(TimeUtility.DAY_IN_MS, currentTime_UTC); - + public void testMonth_UTC(){ + long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_UTC(AggregationPeriodLength.month, currentTime_UTC); assertEquals("millisecond is wrong", 0, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodStartedAt)); assertEquals("second is wrong", 0, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodStartedAt)); assertEquals("minute is wrong", 0, TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodStartedAt)); assertEquals("hour is wrong", 0, TimeUtility.getHourOfDayFromTimestamp(thisPeriodStartedAt)); - assertEquals("day is wrong", TimeUtility.getDaysFromTimestamp(currentTime_UTC), TimeUtility.getDaysFromTimestamp(thisPeriodStartedAt)); - assertEquals("week is wrong", TimeUtility.getWeeksFromTimestamp(currentTime_UTC), TimeUtility.getWeeksFromTimestamp(thisPeriodStartedAt)); + assertEquals("day is wrong", 1, TimeUtility.getDayOfMonthFromTimestamp(thisPeriodStartedAt)); + assertEquals("month is wrong", TimeUtility.getMonthOfYearFromTimestamp(currentTime_UTC), TimeUtility.getMonthOfYearFromTimestamp(thisPeriodStartedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodStartedAt)); + + long thisPeriodEndedAt = TimeUtility.getTimestampPeriodEnd_UTC(AggregationPeriodLength.month, currentTime_UTC); + assertEquals("millisecond is wrong", 999, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodEndedAt)); + assertEquals("second is wrong", 59, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodEndedAt)); + assertEquals("minute is wrong", 59, TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodEndedAt)); + assertEquals("hour is wrong", 23, TimeUtility.getHourOfDayFromTimestamp(thisPeriodEndedAt)); + assertTrue("day of month is less than 28", TimeUtility.getDayOfMonthFromTimestamp(thisPeriodEndedAt) >= 28); + assertEquals("month is wrong", TimeUtility.getMonthOfYearFromTimestamp(currentTime_UTC), TimeUtility.getMonthOfYearFromTimestamp(thisPeriodEndedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodEndedAt)); + } + + // Test flooring & ceiling UTC time to the closes week + @Test + public void testWeek_UTC(){ + long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_UTC(AggregationPeriodLength.week, currentTime_UTC); + assertEquals("millisecond is wrong", 0, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodStartedAt)); + assertEquals("second is wrong", 0, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodStartedAt)); + assertEquals("minute is wrong", 0, TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodStartedAt)); + assertEquals("hour is wrong", 0, TimeUtility.getHourOfDayFromTimestamp(thisPeriodStartedAt)); + assertEquals("day is wrong", Calendar.MONDAY, TimeUtility.getDayOfWeekFromTimestamp(thisPeriodStartedAt)); + assertEquals("week is wrong", TimeUtility.getWeekOfYearFromTimestamp(currentTime_UTC), TimeUtility.getWeekOfYearFromTimestamp(thisPeriodStartedAt)); + assertTrue("year is more than one year off", TimeUtility.getYearFromTimestamp(currentTime_UTC)-TimeUtility.getYearFromTimestamp(thisPeriodStartedAt) <= 1); + + long thisPeriodEndedAt = TimeUtility.getTimestampPeriodEnd_UTC(AggregationPeriodLength.week, currentTime_UTC); + assertEquals("millisecond is wrong", 999, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodEndedAt)); + assertEquals("second is wrong", 59, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodEndedAt)); + assertEquals("minute is wrong", 59, TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodEndedAt)); + assertEquals("hour is wrong", 23, TimeUtility.getHourOfDayFromTimestamp(thisPeriodEndedAt)); + assertEquals("day is wrong", Calendar.SUNDAY, TimeUtility.getDayOfWeekFromTimestamp(thisPeriodEndedAt)); + assertEquals("week is wrong", TimeUtility.getWeekOfYearFromTimestamp(currentTime_UTC), TimeUtility.getWeekOfYearFromTimestamp(thisPeriodEndedAt)); + assertTrue("year is more than one year off", TimeUtility.getYearFromTimestamp(thisPeriodEndedAt)-TimeUtility.getYearFromTimestamp(currentTime_UTC) <= 1); + } + + // Test flooring & ceiling UTC time to the closes day + @Test + public void testDay_UTC(){ + long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_UTC(AggregationPeriodLength.day, currentTime_UTC); + assertEquals("millisecond is wrong", 0, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodStartedAt)); + assertEquals("second is wrong", 0, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodStartedAt)); + assertEquals("minute is wrong", 0, TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodStartedAt)); + assertEquals("hour is wrong", 0, TimeUtility.getHourOfDayFromTimestamp(thisPeriodStartedAt)); + assertEquals("day is wrong", TimeUtility.getDayOfYearFromTimestamp(currentTime_UTC), TimeUtility.getDayOfYearFromTimestamp(thisPeriodStartedAt)); + assertEquals("week is wrong", TimeUtility.getWeekOfYearFromTimestamp(currentTime_UTC), TimeUtility.getWeekOfYearFromTimestamp(thisPeriodStartedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodStartedAt)); + + long thisPeriodEndedAt = TimeUtility.getTimestampPeriodEnd_UTC(AggregationPeriodLength.day, currentTime_UTC); + assertEquals("millisecond is wrong", 999, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodEndedAt)); + assertEquals("second is wrong", 59, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodEndedAt)); + assertEquals("minute is wrong", 59, TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodEndedAt)); + assertEquals("hour is wrong", 23, TimeUtility.getHourOfDayFromTimestamp(thisPeriodEndedAt)); + assertEquals("day is wrong", TimeUtility.getDayOfYearFromTimestamp(currentTime_UTC), TimeUtility.getDayOfYearFromTimestamp(thisPeriodEndedAt)); + assertEquals("week is wrong", TimeUtility.getWeekOfYearFromTimestamp(currentTime_UTC), TimeUtility.getWeekOfYearFromTimestamp(thisPeriodEndedAt)); + assertEquals("month is wrong", TimeUtility.getMonthOfYearFromTimestamp(currentTime_UTC), TimeUtility.getMonthOfYearFromTimestamp(thisPeriodEndedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodEndedAt)); } - // Test flooring UTC time to the closes hour + // Test flooring & ceiling UTC time to the closes hour @Test - public void testHourStart_UTC_ForCurrentTime(){ - long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_UTC(TimeUtility.HOUR_IN_MS, currentTime_UTC); - + public void testHour_UTC(){ + long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_UTC(AggregationPeriodLength.hour, currentTime_UTC); assertEquals("millisecond is wrong", 0, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodStartedAt)); assertEquals("second is wrong", 0, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodStartedAt)); assertEquals("minute is wrong", 0, TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodStartedAt)); assertEquals("hour is wrong", TimeUtility.getHourOfDayFromTimestamp(currentTime_UTC), TimeUtility.getHourOfDayFromTimestamp(thisPeriodStartedAt)); - assertEquals("day is wrong", TimeUtility.getDaysFromTimestamp(currentTime_UTC), TimeUtility.getDaysFromTimestamp(thisPeriodStartedAt)); - assertEquals("week is wrong", TimeUtility.getWeeksFromTimestamp(currentTime_UTC), TimeUtility.getWeeksFromTimestamp(thisPeriodStartedAt)); + assertEquals("day is wrong", TimeUtility.getDayOfWeekFromTimestamp(currentTime_UTC), TimeUtility.getDayOfWeekFromTimestamp(thisPeriodStartedAt)); + assertEquals("week is wrong", TimeUtility.getWeekOfYearFromTimestamp(currentTime_UTC), TimeUtility.getWeekOfYearFromTimestamp(thisPeriodStartedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodStartedAt)); + + long thisPeriodEndedAt = TimeUtility.getTimestampPeriodEnd_UTC(AggregationPeriodLength.hour, currentTime_UTC); + assertEquals("millisecond is wrong", 999, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodEndedAt)); + assertEquals("second is wrong", 59, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodEndedAt)); + assertEquals("minute is wrong", 59, TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodEndedAt)); + assertEquals("hour is wrong", TimeUtility.getHourOfDayFromTimestamp(currentTime_UTC), TimeUtility.getHourOfDayFromTimestamp(thisPeriodEndedAt)); + assertEquals("day is wrong", TimeUtility.getDayOfYearFromTimestamp(currentTime_UTC), TimeUtility.getDayOfYearFromTimestamp(thisPeriodEndedAt)); + assertEquals("week is wrong", TimeUtility.getWeekOfYearFromTimestamp(currentTime_UTC), TimeUtility.getWeekOfYearFromTimestamp(thisPeriodEndedAt)); + assertEquals("month is wrong", TimeUtility.getMonthOfYearFromTimestamp(currentTime_UTC), TimeUtility.getMonthOfYearFromTimestamp(thisPeriodEndedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodEndedAt)); } - // Test flooring UTC time to the closes minute + // Test flooring & ceiling UTC time to the closes 15-minute period @Test - public void testMinuteStart_UTC_ForCurrentTime(){ - long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_UTC(TimeUtility.MINUTES_IN_MS, currentTime_UTC); - + public void testFifteenMinute_UTC(){ + long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_UTC(AggregationPeriodLength.fifteenMinutes, currentTime_UTC); + assertEquals("millisecond is wrong", 0, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodStartedAt)); + assertEquals("second is wrong", 0, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodStartedAt)); + assertTrue("the period start minute is in the future of the current time", TimeUtility.getMinuteOfHourFromTimestamp(currentTime_UTC) >= TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodStartedAt)); + assertTrue("the period starts more than 5 minutes before the current time", TimeUtility.getMinuteOfHourFromTimestamp(currentTime_UTC)-TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodStartedAt) <= 14); + assertTrue("the period start minute is not a multiple of five", TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodStartedAt) % 15 == 0); + assertEquals("hour is wrong", TimeUtility.getHourOfDayFromTimestamp(currentTime_UTC), TimeUtility.getHourOfDayFromTimestamp(thisPeriodStartedAt)); + assertEquals("day is wrong", TimeUtility.getDayOfWeekFromTimestamp(currentTime_UTC), TimeUtility.getDayOfWeekFromTimestamp(thisPeriodStartedAt)); + assertEquals("week is wrong", TimeUtility.getWeekOfYearFromTimestamp(currentTime_UTC), TimeUtility.getWeekOfYearFromTimestamp(thisPeriodStartedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodStartedAt)); + + long thisPeriodEndedAt = TimeUtility.getTimestampPeriodEnd_UTC(AggregationPeriodLength.fifteenMinutes, currentTime_UTC); + assertEquals("millisecond is wrong", 999, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodEndedAt)); + assertEquals("second is wrong", 59, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodEndedAt)); + assertTrue("the period end minute is before of the current time", TimeUtility.getMinuteOfHourFromTimestamp(currentTime_UTC) <= TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodEndedAt)); + assertTrue("the period ends more than 15 minutes after the current time", TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodEndedAt)-TimeUtility.getMinuteOfHourFromTimestamp(currentTime_UTC) <= 14); + assertTrue("the period end minute(+1) is not a multiple of fifteen", TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodEndedAt+1) % 15 == 0); + assertEquals("hour is wrong", TimeUtility.getHourOfDayFromTimestamp(currentTime_UTC), TimeUtility.getHourOfDayFromTimestamp(thisPeriodEndedAt)); + assertEquals("day is wrong", TimeUtility.getDayOfWeekFromTimestamp(currentTime_UTC), TimeUtility.getDayOfWeekFromTimestamp(thisPeriodEndedAt)); + assertEquals("week is wrong", TimeUtility.getWeekOfYearFromTimestamp(currentTime_UTC), TimeUtility.getWeekOfYearFromTimestamp(thisPeriodEndedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodEndedAt)); + } + + // Test flooring & ceiling UTC time to the closes 5-minute period + @Test + public void testFiveMinute_UTC(){ + long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_UTC(AggregationPeriodLength.fiveMinutes, currentTime_UTC); + assertEquals("millisecond is wrong", 0, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodStartedAt)); + assertEquals("second is wrong", 0, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodStartedAt)); + assertTrue("the period start minute is in the future of the current time", TimeUtility.getMinuteOfHourFromTimestamp(currentTime_UTC) >= TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodStartedAt)); + assertTrue("the period starts more than 5 minutes before the current time", TimeUtility.getMinuteOfHourFromTimestamp(currentTime_UTC)-TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodStartedAt) <= 4); + assertTrue("the period start minute is not a multiple of five", TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodStartedAt) % 5 == 0); + assertEquals("hour is wrong", TimeUtility.getHourOfDayFromTimestamp(currentTime_UTC), TimeUtility.getHourOfDayFromTimestamp(thisPeriodStartedAt)); + assertEquals("day is wrong", TimeUtility.getDayOfWeekFromTimestamp(currentTime_UTC), TimeUtility.getDayOfWeekFromTimestamp(thisPeriodStartedAt)); + assertEquals("week is wrong", TimeUtility.getWeekOfYearFromTimestamp(currentTime_UTC), TimeUtility.getWeekOfYearFromTimestamp(thisPeriodStartedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodStartedAt)); + + long thisPeriodEndedAt = TimeUtility.getTimestampPeriodEnd_UTC(AggregationPeriodLength.fiveMinutes, currentTime_UTC); + assertEquals("millisecond is wrong", 999, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodEndedAt)); + assertEquals("second is wrong", 59, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodEndedAt)); + assertTrue("the period end minute is before of the current time", TimeUtility.getMinuteOfHourFromTimestamp(currentTime_UTC) <= TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodEndedAt)); + assertTrue("the period ends more than 5 minutes after the current time", TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodEndedAt)-TimeUtility.getMinuteOfHourFromTimestamp(currentTime_UTC) <= 4); + assertTrue("the period end minute(+1) is not a multiple of five", TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodEndedAt+1) % 5 == 0); + assertEquals("hour is wrong", TimeUtility.getHourOfDayFromTimestamp(currentTime_UTC), TimeUtility.getHourOfDayFromTimestamp(thisPeriodEndedAt)); + assertEquals("day is wrong", TimeUtility.getDayOfWeekFromTimestamp(currentTime_UTC), TimeUtility.getDayOfWeekFromTimestamp(thisPeriodEndedAt)); + assertEquals("week is wrong", TimeUtility.getWeekOfYearFromTimestamp(currentTime_UTC), TimeUtility.getWeekOfYearFromTimestamp(thisPeriodEndedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodEndedAt)); + } + + // Test flooring & ceiling UTC time to the closes minute + @Test + public void testMinute_UTC(){ + long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_UTC(AggregationPeriodLength.minute, currentTime_UTC); assertEquals("millisecond is wrong", 0, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodStartedAt)); assertEquals("second is wrong", 0, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodStartedAt)); assertEquals("minute is wrong", TimeUtility.getMinuteOfHourFromTimestamp(currentTime_UTC), TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodStartedAt)); assertEquals("hour is wrong", TimeUtility.getHourOfDayFromTimestamp(currentTime_UTC), TimeUtility.getHourOfDayFromTimestamp(thisPeriodStartedAt)); - assertEquals("day is wrong", TimeUtility.getDaysFromTimestamp(currentTime_UTC), TimeUtility.getDaysFromTimestamp(thisPeriodStartedAt)); - assertEquals("week is wrong", TimeUtility.getWeeksFromTimestamp(currentTime_UTC), TimeUtility.getWeeksFromTimestamp(thisPeriodStartedAt)); + assertEquals("day is wrong", TimeUtility.getDayOfWeekFromTimestamp(currentTime_UTC), TimeUtility.getDayOfWeekFromTimestamp(thisPeriodStartedAt)); + assertEquals("week is wrong", TimeUtility.getWeekOfYearFromTimestamp(currentTime_UTC), TimeUtility.getWeekOfYearFromTimestamp(thisPeriodStartedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodStartedAt)); + + long thisPeriodEndedAt = TimeUtility.getTimestampPeriodEnd_UTC(AggregationPeriodLength.minute, currentTime_UTC); + assertEquals("millisecond is wrong", 999, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodEndedAt)); + assertEquals("second is wrong", 59, TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodEndedAt)); + assertEquals("minute is wrong", TimeUtility.getMinuteOfHourFromTimestamp(currentTime_UTC), TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodEndedAt)); + assertEquals("hour is wrong", TimeUtility.getHourOfDayFromTimestamp(currentTime_UTC), TimeUtility.getHourOfDayFromTimestamp(thisPeriodEndedAt)); + assertEquals("day is wrong", TimeUtility.getDayOfWeekFromTimestamp(currentTime_UTC), TimeUtility.getDayOfWeekFromTimestamp(thisPeriodEndedAt)); + assertEquals("week is wrong", TimeUtility.getWeekOfYearFromTimestamp(currentTime_UTC), TimeUtility.getWeekOfYearFromTimestamp(thisPeriodEndedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodEndedAt)); } - // Test flooring UTC time to the closes second + // Test flooring & ceiling UTC time to the closes second @Test - public void testSecondStart_UTC_ForCurrentTime(){ - long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_UTC(TimeUtility.SECOND_IN_MS, currentTime_UTC); - + public void testSecond_UTC(){ + long thisPeriodStartedAt = TimeUtility.getTimestampPeriodStart_UTC(AggregationPeriodLength.second, currentTime_UTC); assertEquals("millisecond is wrong", 0, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodStartedAt)); assertEquals("second is wrong", TimeUtility.getSecondOfMinuteFromTimestamp(currentTime_UTC), TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodStartedAt)); assertEquals("minute is wrong", TimeUtility.getMinuteOfHourFromTimestamp(currentTime_UTC), TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodStartedAt)); assertEquals("hour is wrong", TimeUtility.getHourOfDayFromTimestamp(currentTime_UTC), TimeUtility.getHourOfDayFromTimestamp(thisPeriodStartedAt)); - assertEquals("day is wrong", TimeUtility.getDaysFromTimestamp(currentTime_UTC), TimeUtility.getDaysFromTimestamp(thisPeriodStartedAt)); - assertEquals("week is wrong", TimeUtility.getWeeksFromTimestamp(currentTime_UTC), TimeUtility.getWeeksFromTimestamp(thisPeriodStartedAt)); + assertEquals("day is wrong", TimeUtility.getDayOfWeekFromTimestamp(currentTime_UTC), TimeUtility.getDayOfWeekFromTimestamp(thisPeriodStartedAt)); + assertEquals("week is wrong", TimeUtility.getWeekOfYearFromTimestamp(currentTime_UTC), TimeUtility.getWeekOfYearFromTimestamp(thisPeriodStartedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodStartedAt)); + + long thisPeriodEndedAt = TimeUtility.getTimestampPeriodEnd_UTC(AggregationPeriodLength.second, currentTime_UTC); + assertEquals("millisecond is wrong", 999, TimeUtility.getMillisecondInSecondFromTimestamp(thisPeriodEndedAt)); + assertEquals("second is wrong", TimeUtility.getSecondOfMinuteFromTimestamp(currentTime_UTC), TimeUtility.getSecondOfMinuteFromTimestamp(thisPeriodEndedAt)); + assertEquals("minute is wrong", TimeUtility.getMinuteOfHourFromTimestamp(currentTime_UTC), TimeUtility.getMinuteOfHourFromTimestamp(thisPeriodEndedAt)); + assertEquals("hour is wrong", TimeUtility.getHourOfDayFromTimestamp(currentTime_UTC), TimeUtility.getHourOfDayFromTimestamp(thisPeriodEndedAt)); + assertEquals("day is wrong", TimeUtility.getDayOfWeekFromTimestamp(currentTime_UTC), TimeUtility.getDayOfWeekFromTimestamp(thisPeriodEndedAt)); + assertEquals("week is wrong", TimeUtility.getWeekOfYearFromTimestamp(currentTime_UTC), TimeUtility.getWeekOfYearFromTimestamp(thisPeriodEndedAt)); + assertEquals("year is wrong", TimeUtility.getYearFromTimestamp(currentTime_UTC), TimeUtility.getYearFromTimestamp(thisPeriodEndedAt)); } // Test printing converting milliseconds to text @Test public void testMsToString(){ //low values - assertEquals("00:00:00.000", TimeUtility.msToString(0)); - assertEquals("00:00:00.001", TimeUtility.msToString(1)); - assertEquals("00:00:01.000", TimeUtility.msToString(TimeUtility.SECOND_IN_MS)); - assertEquals("00:01:00.000", TimeUtility.msToString(TimeUtility.MINUTES_IN_MS)); - assertEquals("00:05:00.000", TimeUtility.msToString(TimeUtility.FIVE_MINUTES_IN_MS)); - assertEquals("01:00:00.000", TimeUtility.msToString(TimeUtility.HOUR_IN_MS)); - assertEquals("1d+00:00:00.000", TimeUtility.msToString(TimeUtility.DAY_IN_MS)); - assertEquals("1w+00:00:00.000", TimeUtility.msToString(TimeUtility.WEEK_IN_MS)); + assertEquals("00:00:00.000", TimeUtility.timeInMsToString(0)); + assertEquals("00:00:00.001", TimeUtility.timeInMsToString(1)); + assertEquals("00:00:01.000", TimeUtility.timeInMsToString(TimeUtility.SECOND_IN_MS)); + assertEquals("00:01:00.000", TimeUtility.timeInMsToString(TimeUtility.MINUTE_IN_MS)); + assertEquals("00:05:00.000", TimeUtility.timeInMsToString(TimeUtility.FIVE_MINUTES_IN_MS)); + assertEquals("01:00:00.000", TimeUtility.timeInMsToString(TimeUtility.HOUR_IN_MS)); + assertEquals("1d+00:00:00.000", TimeUtility.timeInMsToString(TimeUtility.DAY_IN_MS)); + assertEquals("1w+00:00:00.000", TimeUtility.timeInMsToString(TimeUtility.WEEK_IN_MS)); //high values - assertEquals("00:00:00.999", TimeUtility.msToString(999)); - assertEquals("00:00:59.000", TimeUtility.msToString(TimeUtility.SECOND_IN_MS*59)); - assertEquals("00:59:00.000", TimeUtility.msToString(TimeUtility.MINUTES_IN_MS*59)); - assertEquals("23:00:00.000", TimeUtility.msToString(TimeUtility.HOUR_IN_MS*23)); - assertEquals("52w+5d+00:00:00.000", TimeUtility.msToString(TimeUtility.DAY_IN_MS*369)); + assertEquals("00:00:00.999", TimeUtility.timeInMsToString(999)); + assertEquals("00:00:59.000", TimeUtility.timeInMsToString(TimeUtility.SECOND_IN_MS*59)); + assertEquals("00:59:00.000", TimeUtility.timeInMsToString(TimeUtility.MINUTE_IN_MS*59)); + assertEquals("23:00:00.000", TimeUtility.timeInMsToString(TimeUtility.HOUR_IN_MS*23)); + assertEquals("52w+5d+00:00:00.000", TimeUtility.timeInMsToString(TimeUtility.DAY_IN_MS*369)); //high overflow values - assertEquals("00:00:01.999", TimeUtility.msToString(1999)); - assertEquals("00:02:39.000", TimeUtility.msToString(TimeUtility.SECOND_IN_MS*159)); - assertEquals("02:39:00.000", TimeUtility.msToString(TimeUtility.MINUTES_IN_MS*159)); - assertEquals("5d+03:00:00.000", TimeUtility.msToString(TimeUtility.HOUR_IN_MS*123)); + assertEquals("00:00:01.999", TimeUtility.timeInMsToString(1999)); + assertEquals("00:02:39.000", TimeUtility.timeInMsToString(TimeUtility.SECOND_IN_MS*159)); + assertEquals("02:39:00.000", TimeUtility.timeInMsToString(TimeUtility.MINUTE_IN_MS*159)); + assertEquals("5d+03:00:00.000", TimeUtility.timeInMsToString(TimeUtility.HOUR_IN_MS*123)); //combinations - assertEquals("142w+5d+23:59:59.999", TimeUtility.msToString((TimeUtility.WEEK_IN_MS*142) + (TimeUtility.DAY_IN_MS*5) + (TimeUtility.HOUR_IN_MS*23) + (TimeUtility.MINUTES_IN_MS*59) + (TimeUtility.SECOND_IN_MS*59) + 999)); - assertEquals("6d+23:59:59.999", TimeUtility.msToString(TimeUtility.WEEK_IN_MS-1)); + assertEquals("142w+5d+23:59:59.999", TimeUtility.timeInMsToString((TimeUtility.WEEK_IN_MS*142) + (TimeUtility.DAY_IN_MS*5) + (TimeUtility.HOUR_IN_MS*23) + (TimeUtility.MINUTE_IN_MS*59) + (TimeUtility.SECOND_IN_MS*59) + 999)); + assertEquals("6d+23:59:59.999", TimeUtility.timeInMsToString(TimeUtility.WEEK_IN_MS-1)); } // Test printing converting milliseconds to text for a negative time @Test(expected=NumberFormatException.class) public void testMsToStringForNegativeArgument(){ //low values - TimeUtility.msToString(-1); + TimeUtility.timeInMsToString(-1); } }