Renamed Timeutility class to UTCTimeUtility

Added TimePeriod class for high level reprensentation of a period of time
This commit is contained in:
Daniel Collin 2016-02-18 11:10:27 +01:00
parent f670d2ceb4
commit 77a2b9ccb4
9 changed files with 655 additions and 267 deletions

View file

@ -4,7 +4,8 @@ import se.hal.HalContext;
import se.hal.intf.HalDaemon;
import se.hal.struct.Sensor;
import se.hal.intf.HalSensorData.AggregationMethod;
import se.hal.util.TimeUtility;
import se.hal.util.UTCTimePeriod;
import se.hal.util.UTCTimeUtility;
import zutil.db.DBConnection;
import zutil.db.SQLResultHandler;
import zutil.db.handler.SimpleSQLResult;
@ -36,7 +37,7 @@ public class SensorDataAggregatorDaemon implements HalDaemon {
}
public void initiate(ScheduledExecutorService executor){
executor.scheduleAtFixedRate(this, 0, TimeUtility.FIVE_MINUTES_IN_MS, TimeUnit.MILLISECONDS);
executor.scheduleAtFixedRate(this, 0, UTCTimeUtility.FIVE_MINUTES_IN_MS, TimeUnit.MILLISECONDS);
}
@Override
@ -61,16 +62,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, AggregationPeriodLength.FIVE_MINUTES, TimeUtility.DAY_IN_MS, 5);
aggregateRawData(sensor, AggregationPeriodLength.FIVE_MINUTES, UTCTimeUtility.DAY_IN_MS, 5);
logger.fine("aggregating raw data up to a week old into one hour periods");
aggregateRawData(sensor, AggregationPeriodLength.HOUR, TimeUtility.WEEK_IN_MS, 60);
aggregateRawData(sensor, AggregationPeriodLength.HOUR, UTCTimeUtility.WEEK_IN_MS, 60);
logger.fine("aggregating raw data into one day periods");
aggregateRawData(sensor, AggregationPeriodLength.DAY, TimeUtility.INFINITY, 60*24);
aggregateRawData(sensor, AggregationPeriodLength.DAY, UTCTimeUtility.INFINITY, 60*24);
logger.fine("aggregating raw data into one week periods");
aggregateRawData(sensor, AggregationPeriodLength.WEEK, TimeUtility.INFINITY, 60*24*7);
aggregateRawData(sensor, AggregationPeriodLength.WEEK, UTCTimeUtility.INFINITY, 60*24*7);
}
/**
@ -91,33 +92,34 @@ public class SensorDataAggregatorDaemon implements HalDaemon {
+ " AND timestamp_end-timestamp_start == ?");
stmt.setLong(1, sensorId);
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 FIVE_MINUTES: stmt.setLong(2, TimeUtility.FIVE_MINUTES_IN_MS-1); break;
case FIFTEEN_MINUTES: 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;
case SECOND: stmt.setLong(2, UTCTimeUtility.SECOND_IN_MS-1); break;
case MINUTE: stmt.setLong(2, UTCTimeUtility.MINUTE_IN_MS-1); break;
case FIVE_MINUTES: stmt.setLong(2, UTCTimeUtility.FIVE_MINUTES_IN_MS-1); break;
case FIFTEEN_MINUTES: stmt.setLong(2, UTCTimeUtility.FIFTEEN_MINUTES_IN_MS-1); break;
case HOUR: stmt.setLong(2, UTCTimeUtility.HOUR_IN_MS-1); break;
case DAY: stmt.setLong(2, UTCTimeUtility.DAY_IN_MS-1); break;
case WEEK: stmt.setLong(2, UTCTimeUtility.WEEK_IN_MS-1); break;
default: logger.warning("aggregation period length is not supported."); return;
}
Long maxTimestampFoundForSensor = DBConnection.exec(stmt, new SimpleSQLResult<Long>());
if(maxTimestampFoundForSensor == null)
maxTimestampFoundForSensor = 0l;
long currentPeriodStartTimestamp = TimeUtility.getTimestampPeriodStart_UTC(aggrPeriodLength, System.currentTimeMillis());
long latestCompletePeriodEndTimestamp = new UTCTimePeriod(System.currentTimeMillis(), aggrPeriodLength).getPreviosPeriod().getEndTimestamp();
long oldestPeriodStartTimestamp = new UTCTimePeriod(System.currentTimeMillis()-ageLimitInMs, aggrPeriodLength).getStartTimestamp();
logger.fine("Calculating periods... (from:"+ maxTimestampFoundForSensor +", to:"+ currentPeriodStartTimestamp +") with expected sample count: " + expectedSampleCount);
logger.fine("Calculating periods... (from:"+ maxTimestampFoundForSensor +", to:"+ latestCompletePeriodEndTimestamp +") with expected sample count: " + expectedSampleCount);
stmt = db.getPreparedStatement("SELECT *, 1 AS confidence FROM sensor_data_raw"
+" WHERE sensor_id == ?"
+ " AND timestamp > ?"
+ " AND timestamp < ? "
+ " AND timestamp <= ? "
+ " AND timestamp >= ? "
+" ORDER BY timestamp ASC");
stmt.setLong(1, sensorId);
stmt.setLong(2, maxTimestampFoundForSensor);
stmt.setLong(3, currentPeriodStartTimestamp);
stmt.setLong(4, TimeUtility.getTimestampPeriodStart_UTC(aggrPeriodLength, System.currentTimeMillis()-ageLimitInMs));
stmt.setLong(3, latestCompletePeriodEndTimestamp);
stmt.setLong(4, oldestPeriodStartTimestamp);
DBConnection.exec(stmt, new DataAggregator(sensorId, aggrPeriodLength, expectedSampleCount, aggrMethod));
} catch (SQLException e) {
logger.log(Level.SEVERE, null, e);
@ -145,8 +147,7 @@ public class SensorDataAggregatorDaemon implements HalDaemon {
try{
HalContext.getDB().getConnection().setAutoCommit(false);
long currentPeriodTimestampStart = 0;
long currentPeriodTimestampEnd = 0;
UTCTimePeriod currentPeriod = null;
float sum = 0;
float confidenceSum = 0;
int samples = 0;
@ -157,40 +158,35 @@ public class SensorDataAggregatorDaemon 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")+")");
}
long timestamp = result.getLong("timestamp");
long dataPeriodTimestampStart = TimeUtility.getTimestampPeriodStart_UTC(this.aggrPeriodLength, timestamp);
long dataPerionTimestampEnd = TimeUtility.getTimestampPeriodEnd_UTC(this.aggrPeriodLength, timestamp);
if(currentPeriodTimestampStart != 0 && currentPeriodTimestampEnd != 0 && dataPeriodTimestampStart != currentPeriodTimestampStart){
long timestamp = result.getLong("timestamp");
UTCTimePeriod dataPeriod = new UTCTimePeriod(timestamp, this.aggrPeriodLength);
if(currentPeriod == null)
currentPeriod = dataPeriod;
if(!dataPeriod.equals(currentPeriod)){
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: " + currentPeriodTimestampStart + ", data: " + sum + ", confidence: " + aggrConfidence + ", samples: " + samples + ", aggrMethod: " + aggrMethod);
logger.finer("Calculated period starting at timestamp: " + currentPeriod.getStartTimestamp() + ", data: " + sum + ", confidence: " + aggrConfidence + ", samples: " + samples + ", aggrMethod: " + aggrMethod);
preparedInsertStmt.setInt(1, result.getInt("sensor_id"));
preparedInsertStmt.setLong(2, ++highestSequenceId);
preparedInsertStmt.setLong(3, currentPeriodTimestampStart);
preparedInsertStmt.setLong(4, currentPeriodTimestampEnd);
preparedInsertStmt.setLong(3, currentPeriod.getStartTimestamp());
preparedInsertStmt.setLong(4, currentPeriod.getEndTimestamp());
preparedInsertStmt.setFloat(5, data);
preparedInsertStmt.setFloat(6, aggrConfidence);
preparedInsertStmt.addBatch();
// Reset variables
currentPeriodTimestampStart = dataPeriodTimestampStart;
currentPeriodTimestampEnd = dataPerionTimestampEnd;
currentPeriod = dataPeriod;
confidenceSum = 0;
sum = 0;
samples = 0;
}
if(currentPeriodTimestampStart == 0){
currentPeriodTimestampStart = dataPeriodTimestampStart;
}
if(currentPeriodTimestampEnd == 0){
currentPeriodTimestampEnd = dataPerionTimestampEnd;
}
sum += result.getFloat("data");
confidenceSum += result.getFloat("confidence");
++samples;

View file

@ -4,7 +4,7 @@ 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;
import se.hal.util.UTCTimeUtility;
import zutil.db.DBConnection;
import zutil.db.SQLResultHandler;
import zutil.log.LogUtil;
@ -23,7 +23,7 @@ public class SensorDataCleanupDaemon implements HalDaemon {
private static final Logger logger = LogUtil.getLogger();
public void initiate(ScheduledExecutorService executor){
executor.scheduleAtFixedRate(this, 5000, TimeUtility.FIVE_MINUTES_IN_MS, TimeUnit.MILLISECONDS);
executor.scheduleAtFixedRate(this, 5000, UTCTimeUtility.FIVE_MINUTES_IN_MS, TimeUnit.MILLISECONDS);
}
@Override
@ -42,8 +42,8 @@ public class SensorDataCleanupDaemon implements HalDaemon {
public void cleanupSensor(Sensor sensor) {
if (sensor.getUser() != null) {
cleanupSensorData(sensor.getId(), AggregationPeriodLength.FIVE_MINUTES, 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.FIVE_MINUTES, UTCTimeUtility.DAY_IN_MS); //clear 5-minute data older than a day
cleanupSensorData(sensor.getId(), AggregationPeriodLength.HOUR, UTCTimeUtility.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
}
@ -68,13 +68,13 @@ public class SensorDataCleanupDaemon implements HalDaemon {
+ "AND timestamp_end < ?");
stmt.setLong(1, sensorId);
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 FIVE_MINUTES: stmt.setLong(2, TimeUtility.FIVE_MINUTES_IN_MS-1); break;
case FIFTEEN_MINUTES: 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;
case SECOND: stmt.setLong(2, UTCTimeUtility.SECOND_IN_MS-1); break;
case MINUTE: stmt.setLong(2, UTCTimeUtility.MINUTE_IN_MS-1); break;
case FIVE_MINUTES: stmt.setLong(2, UTCTimeUtility.FIVE_MINUTES_IN_MS-1); break;
case FIFTEEN_MINUTES: stmt.setLong(2, UTCTimeUtility.FIFTEEN_MINUTES_IN_MS-1); break;
case HOUR: stmt.setLong(2, UTCTimeUtility.HOUR_IN_MS-1); break;
case DAY: stmt.setLong(2, UTCTimeUtility.DAY_IN_MS-1); break;
case WEEK: stmt.setLong(2, UTCTimeUtility.WEEK_IN_MS-1); break;
default: logger.warning("cleanup period length is not supported."); return;
}
stmt.setLong(3, System.currentTimeMillis()-olderThan);
@ -101,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.timeInMsToString(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") + " (" + UTCTimeUtility.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();

View file

@ -5,7 +5,7 @@ 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.util.UTCTimeUtility;
import se.hal.struct.Sensor;
import se.hal.struct.User;
import zutil.db.DBConnection;
@ -43,13 +43,13 @@ public class PCOverviewHttpPage extends HalHttpPage {
for(User user : users){
List<Sensor> userSensors = Sensor.getSensors(db, user);
for(Sensor sensor : userSensors){
minDataList.addAll(AggregateDataListSqlResult.getAggregateDataForPeriod(db, sensor, AggregationPeriodLength.FIVE_MINUTES, TimeUtility.DAY_IN_MS));
minDataList.addAll(AggregateDataListSqlResult.getAggregateDataForPeriod(db, sensor, AggregationPeriodLength.FIVE_MINUTES, UTCTimeUtility.DAY_IN_MS));
hourDataList.addAll(AggregateDataListSqlResult.getAggregateDataForPeriod(db, sensor, AggregationPeriodLength.HOUR, TimeUtility.WEEK_IN_MS));
hourDataList.addAll(AggregateDataListSqlResult.getAggregateDataForPeriod(db, sensor, AggregationPeriodLength.HOUR, UTCTimeUtility.WEEK_IN_MS));
dayDataList.addAll(AggregateDataListSqlResult.getAggregateDataForPeriod(db, sensor, AggregationPeriodLength.DAY, TimeUtility.INFINITY));
dayDataList.addAll(AggregateDataListSqlResult.getAggregateDataForPeriod(db, sensor, AggregationPeriodLength.DAY, UTCTimeUtility.INFINITY));
weekDataList.addAll(AggregateDataListSqlResult.getAggregateDataForPeriod(db, sensor, AggregationPeriodLength.WEEK, TimeUtility.INFINITY));
weekDataList.addAll(AggregateDataListSqlResult.getAggregateDataForPeriod(db, sensor, AggregationPeriodLength.WEEK, UTCTimeUtility.INFINITY));
}
}

View file

@ -8,7 +8,7 @@ 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 se.hal.util.UTCTimeUtility;
import zutil.io.file.FileUtil;
import zutil.parser.Templator;
@ -51,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.getAggregateDataForPeriod(db, sensor, AggregationPeriodLength.HOUR, TimeUtility.WEEK_IN_MS));
tmpl.set("aggregation", AggregateDataListSqlResult.getAggregateDataForPeriod(db, sensor, AggregationPeriodLength.HOUR, UTCTimeUtility.WEEK_IN_MS));
return tmpl;
}
else {

View file

@ -43,13 +43,13 @@ public class AggregateDataListSqlResult implements SQLResultHandler<ArrayList<Ag
stmt.setLong(1, sensor.getId());
stmt.setLong(2, sensor.getUser().getId());
switch(aggrPeriodLength){
case SECOND: stmt.setLong(3, TimeUtility.SECOND_IN_MS-1); break;
case MINUTE: stmt.setLong(3, TimeUtility.MINUTE_IN_MS-1); break;
case FIVE_MINUTES: stmt.setLong(3, TimeUtility.FIVE_MINUTES_IN_MS-1); break;
case FIFTEEN_MINUTES: stmt.setLong(3, TimeUtility.FIFTEEN_MINUTES_IN_MS-1); break;
case HOUR: stmt.setLong(3, TimeUtility.HOUR_IN_MS-1); break;
case DAY: stmt.setLong(3, TimeUtility.DAY_IN_MS-1); break;
case WEEK: stmt.setLong(3, TimeUtility.WEEK_IN_MS-1); break;
case SECOND: stmt.setLong(3, UTCTimeUtility.SECOND_IN_MS-1); break;
case MINUTE: stmt.setLong(3, UTCTimeUtility.MINUTE_IN_MS-1); break;
case FIVE_MINUTES: stmt.setLong(3, UTCTimeUtility.FIVE_MINUTES_IN_MS-1); break;
case FIFTEEN_MINUTES: stmt.setLong(3, UTCTimeUtility.FIFTEEN_MINUTES_IN_MS-1); break;
case HOUR: stmt.setLong(3, UTCTimeUtility.HOUR_IN_MS-1); break;
case DAY: stmt.setLong(3, UTCTimeUtility.DAY_IN_MS-1); break;
case WEEK: stmt.setLong(3, UTCTimeUtility.WEEK_IN_MS-1); break;
default: throw new IllegalArgumentException("selected aggrPeriodLength is not supported");
}
stmt.setLong(4, (System.currentTimeMillis() - ageLimitInMs) );

View file

@ -0,0 +1,48 @@
package se.hal.util;
import se.hal.deamon.SensorDataAggregatorDaemon.AggregationPeriodLength;
public class UTCTimePeriod{
private final long start;
private final long end;
private final AggregationPeriodLength periodLength;
public UTCTimePeriod(long timestamp, AggregationPeriodLength periodLength){
start = UTCTimeUtility.getTimestampPeriodStart(periodLength, timestamp);
end = UTCTimeUtility.getTimestampPeriodEnd(periodLength, timestamp);
this.periodLength = periodLength;
}
public long getStartTimestamp(){
return start;
}
public long getEndTimestamp(){
return end;
}
public UTCTimePeriod getNextPeriod(){
return new UTCTimePeriod(end+1, periodLength);
}
public UTCTimePeriod getPreviosPeriod(){
return new UTCTimePeriod(start-1, periodLength);
}
public boolean containsTimestamp(long timestamp){
return start <= timestamp && timestamp <= end;
}
public boolean equals(Object other){
if(other == null)
return false;
if(other instanceof UTCTimePeriod){
UTCTimePeriod o = (UTCTimePeriod)other;
return start == o.start
&& end == o.end
&& periodLength == o.periodLength;
}
return false;
}
}

View file

@ -1,11 +1,12 @@
package se.hal.util;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.TimeZone;
import se.hal.deamon.SensorDataAggregatorDaemon.AggregationPeriodLength;
public class TimeUtility {
public class UTCTimeUtility {
public static final long SECOND_IN_MS = 1000;
public static final long MINUTE_IN_MS = SECOND_IN_MS * 60;
public static final long FIVE_MINUTES_IN_MS = MINUTE_IN_MS * 5;
@ -15,9 +16,10 @@ public class TimeUtility {
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(AggregationPeriodLength aggrPeriodLength, long timestamp) throws NumberFormatException{
public static long getTimestampPeriodStart(AggregationPeriodLength aggrPeriodLength, long timestamp) throws NumberFormatException{
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.setTimeInMillis(timestamp);
cal.setFirstDayOfWeek(Calendar.MONDAY);
switch(aggrPeriodLength){
case YEAR:
cal.set(Calendar.DAY_OF_YEAR, 1);
@ -72,42 +74,64 @@ public class TimeUtility {
return cal.getTimeInMillis();
}
public static long getTimestampPeriodEnd_UTC(AggregationPeriodLength aggrPeriodLength, long timestamp) throws NumberFormatException{
long start = getTimestampPeriodStart_UTC(aggrPeriodLength, timestamp);
public static long getTimestampPeriodEnd(AggregationPeriodLength aggrPeriodLength, long timestamp) throws NumberFormatException{
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.setTimeInMillis(start);
cal.setTimeInMillis(timestamp);
cal.setFirstDayOfWeek(Calendar.MONDAY);
switch(aggrPeriodLength){
case YEAR:
cal.add(Calendar.YEAR, 1);
cal.set(Calendar.DAY_OF_YEAR, cal.getActualMaximum(Calendar.DAY_OF_YEAR));
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 1000);
break;
case MONTH:
cal.add(Calendar.MONTH, 1);
cal.set(Calendar.DAY_OF_MONTH, cal.getActualMaximum(Calendar.DAY_OF_MONTH));
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 1000);
break;
case WEEK:
cal.add(Calendar.WEEK_OF_YEAR, 1);
cal.set(Calendar.DAY_OF_WEEK, Calendar.SUNDAY);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 1000);
break;
case DAY:
cal.add(Calendar.DAY_OF_YEAR, 1);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 1000);
break;
case HOUR:
cal.add(Calendar.HOUR, 1);
cal.set(Calendar.MINUTE, 59);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 1000);
break;
case FIVE_MINUTES:
cal.add(Calendar.MINUTE, 5);
cal.set(Calendar.MINUTE, 4+(cal.get(Calendar.MINUTE)/5)*5);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 1000);
break;
case FIFTEEN_MINUTES:
cal.add(Calendar.MINUTE, 15);
cal.set(Calendar.MINUTE, 14+(cal.get(Calendar.MINUTE)/15)*15);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 1000);
break;
case MINUTE:
cal.add(Calendar.MINUTE, 1);
cal.set(Calendar.SECOND, 59);
cal.set(Calendar.MILLISECOND, 1000);
break;
case SECOND:
cal.add(Calendar.SECOND, 1);
cal.set(Calendar.MILLISECOND, 1000);
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");
@ -211,4 +235,12 @@ public class TimeUtility {
return retval;
}
public static String getDateString(long timestamp){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
format.setTimeZone(TimeZone.getTimeZone("UTC"));
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.setTimeInMillis(timestamp);
return format.format(cal.getTime());
}
}