Junaid
Junaid

Reputation: 7860

Weird behaviour of a seconds elapsed function

Class level variables:

    static int secondsInterval = 100000000;
    static long secondsSpecial=0;
    static Date dateSecondsReg; 

I have the following function I pass two arguments to this function:

  1. The number of seconds which have elapsed since a certain date.
  2. The actual date (Beginning date) since when the calculation commences.

the method is:

public static void secondsToNotify(long seconds, String d){
        Date dt = Convert(d); 
        System.out.println(""+dt);
        Calendar cal = Calendar.getInstance(); 
        cal.setTime(dt); 
        secondsSpecial = secondsInterval*(1+(seconds/secondsInterval)); 
        cal.add(Calendar.SECOND, (int) secondsSpecial);
        
        dateSecondsReg = cal.getTime(); 
        System.out.println(""+dateSecondsReg);
        System.out.println(""+secondsSpecial);
    }

I pass the following arguments to the method:

secondsToNotify(2682810000L, "1929-01-02"); 

To my amazement the resulting date, instead of being in future is in past:

Results

1929-01-02
Mon Jun 17 17:08:24 IST 1878
2700000000
    

Cant understand where I am going wrong, any hints?

Upvotes: 0

Views: 94

Answers (4)

Junaid
Junaid

Reputation: 7860

For anyone who stumbles here, this is what I came up with as of now ( Not too robust though, improving it)

public class testSplSec {


    static int secondsInterval = 100000000;
    static long secondsSpecial=0;
    static Date dateSecondsReg; 
    static Integer intValue;


    public static void secondsToNotify(long seconds, String d){
        Date dt = Convert(d); 
        System.out.println(""+dt);
        Calendar cal = Calendar.getInstance(); 
        cal.setTime(dt); 
        secondsSpecial = secondsInterval*(1+(seconds/secondsInterval));     
        System.out.println(""+(secondsSpecial));

        long hour = (secondsSpecial /60)/60; 
        System.out.println(""+hour);

        if(hour >= Integer.MAX_VALUE){

        }else{
            intValue =  (int) (long)hour; 
        }
        cal.add(Calendar.HOUR,intValue);    
        dateSecondsReg = cal.getTime(); 
        System.out.println(""+dateSecondsReg);
        System.out.println(""+secondsSpecial);
    }

    public static Date Convert(String S){

        String DateStr = S;
        Date d = null;
        try {
            d = new SimpleDateFormat("yyyy-MM-dd").parse(DateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        java.sql.Date d1 = new java.sql.Date(d.getTime());

        return d1; 
    }


    public static void main(String[] args){
        secondsToNotify(2682810000L, "1929-01-02"); 
    }

}

Upvotes: 0

mzzzzb
mzzzzb

Reputation: 1452

you have an integer overflow here

Cal.add(Calendar.SECOND, (int) secondsSpecial);

that cast to int results in -1594967296 being passed

Check System.out.println(Integer.MAX_VALUE); will give 2147483647 ie 2^31 -1

since it seems that Calendar.add only takes in int as increment how about

cal.setTimeInMillis(dt.getTime() + secondsSpecial)

Upvotes: 2

Pete Verdon
Pete Verdon

Reputation: 335

I think the problem lies in:

Cal.add(Calendar.SECOND, (int) secondsSpecial);

You're casting a long to int, and unless I've miscounted a zero or two I think your long is bigger than Integer.MAX_VALUE. So this will wrap around to some negative number, and there's your subtraction.

(For the record, starting variable names with capital letters is very bad style in Java, and made your code quite hard to read.)

Upvotes: 1

Bathsheba
Bathsheba

Reputation: 234785

seconds / secondsInterval will be carried out in integer arithmetic which means that any remainder is lost.

Pre-multiplying by 1.0 will force the calculation to be carried out in floating point:

1.0 * seconds / secondsInterval

(P.S. Eventually, your cast (int)secondsSpecial will give you trouble if secondsSpecial gets large: you need to rethink that. One idea would be to drop all your int types. Then, as a workaround to Calendar.add having an int as the interval argument, convert secondsSpecial to years and seconds and add the intervals successively.)

Upvotes: 3

Related Questions