Search code examples
javasql-timestamp

Checking for a new day using sql.timestamp


I'm working with some legacy code and I'm iterating through some values, the legacy code is checking for the start of a new day using an sql.timestamp value:

public static final long MILLIS_PER_SECOND = 1000;
public static final long MILLIS_PER_MINUTE = 60 * MILLIS_PER_SECOND;
public static final long MILLIS_PER_HOUR = 60 * MILLIS_PER_MINUTE;
public static final long MILLIS_PER_DAY = 24 * MILLIS_PER_HOUR;

 if (entry.getPeriodEnd().getTime() % TimestampUtils.MILLIS_PER_DAY == 0 || i >= throughputEntries.size()) {

       ...
}

The result is never 0 so it only goes into the if when i >= throughputEntries.size()

I can't get me head around how he was getting a 0 result, possibly his data was different and always ended with a certain time period that would produce the 0

I could rewrite the code maybe to do a check on the date, but would like to know how he achieved it with his code.

I'm not sure that this could be solved with the code I have provided, but maybe I'm missing something...

Edit

So I got my head around this in the end, thanks to @t0r0X & @Leo

I've modified my code to use Joda-Time as follows:

 LocalDate newDay = null;
 int count = 0;


public void calcAvg(){

    DateTimeZone zone = DateTimeZone.getDefault();
    LocalDate throughtputDate = entry.getPeriodEnd().toDateTime(zone).toLocalDate();

    if ( this.newDay(throughtputDate) || i >= throughputEntries.size()) {

       ...
    }

}


public boolean newDay(LocalDate date){

    boolean go = false;
    if(count !=0){
        if(date.isAfter(newDay)){

            newDay = date;
            go = true;
        }
    }
    else{
        newDay = date;
        count++;
    }

    return go;
}

Probably a cleaner way of checking for the new date than the method I've written, but time waits for no man.


Solution

  • The author of the original code may have probably used synthetic "round" data. Maybe using the (nowadays deprecated) java.sql.Timestamp constructor ...

    new Timestamp(116, 1, 25, 0, 0, 0, 0)
    

    or maybe using the (also deprecated) Date constructor ...

    new Timestamp(new Date(116, 1, 25).getTime())
    

    Or he might have parsed some test data like e.g. '2016-01-25'...

    Look ma, no millis! ;-)

    Anyway, to check for a "new day" depends on how you define that. Usually you need a reference date, like the previously processed entry.

    Update:

    Looking a 4th time at the code entry.getPeriodEnd().getTime(): the entries look like time periods... So there must be a getPeriodBegin() method... and I suppose the needed check is to verify if the period end is in another day than the period begin... Am I right?

    Dirty code (deprecated methods):

    Timestamp begin = entry.getPeriodBegin()
    Timestamp end = entry.getPeriodEnd()
    if (begin.getYear() != end.getYear() || begin.getMonth() != end.getMonth() || begin.getDay() != end.getDay() ....) 
    

    Clean code:
    My recommendation: don't even start with java.util.Calendar (proposal on Stackoverflow). Either use DateUtils from Apache Commons Lang (also suggested here on Stackoverflow; comments are relevant), or, my favourite, get JodaTime and stop worring (suggestion also on Stackoverflow; comments are relevant). I personally have always got happy with JodaTime.

    PS

    Not to forget (thanks to @Leo for his comment on the question, I'm still living, ahem, working, in a Java 6-7 world :-/ ...): if using Java 8 or later, go for the new java.time classes.