简体   繁体   中英

Java converting seconds to year day hours minute seconds

I have a problem regarding really big numbers in Java. I'm currently trying to convert a double consisting of a large number of seconds into years, days, hours, minutes and the seconds that are left. My code looks like this: `

import java.util.Scanner;


 public class timer {


 public static void main(String[] args){



     double sum = 1.1078087563769418E16;

    double sec=0;
    double min=0;
    double hou=0;
    double da=0;
    double yea=0;


    yea=sum/31536000;
    int year = (int) yea;
    sum=sum-year*31536000;

    da=sum/86400;
    int day = (int) da;
    sum=sum-day*86400;

    hou=sum/3600;
    int hour = (int) hou;
    sum=sum-hour*3600;

    min=sum/60;
    int minute = (int) min;
    sum=sum-minute*60;

    sec=sum;
    int second = (int) sec;
    sum=sum-second*60;

    System.out.println(year+" "+day+" "+hour+" "+minute+" "+second);            
}
}

`

When the double "sum" is as large as it is, the output gets weird. For example, the double "day" becomes larger than 365, which should be impossible.

Any solutions?

Overflow on the calculation sum=sum-year*31536000;

year and 31536000 are both integers, and their product is ~1E16, which is larger than java's max integer size. Use sum = sum-year*31536000.0 instead.

As a demonstration, add this code after you compute year :

System.out.println(year * 31536000.0); //  1.1078087556672E16
System.out.println(year * 31536000);   //  1100687872

You are facing with a very common problem that most developers should know about: Integer overflow.

Your year variable is an int, the constant for second->year conversion is constant int, so int*int is... int. Except if your year is larger than approx 68, the result cannot fit into an int. Hence - overflow and silly results.

You have a couple of options available to you:

  1. Do your timestamp arithmetic in longs. Really, that's the industry standard anyway.
  2. If you insist on precision of over microseconds (or nano if you're concerned with last century only) - BigDecimal or BigInteger are your friends.
  3. Use the TimeUnit class from concurrent package. It doesn't have years, but does have days and does conversion nicely (JodaTime would be even nicer though)

You can use java.math. BigDecimal class if you need to represent numbers with great precision.

If you need huge integers you can use java.math. BigInteger .

        First use long not double then try this logic

            long min = sum / (60) % 60;
            long hou = sum / (60 * 60 )% 24;
            long da = sum/(60*60*24)%30;
            long yea = sum/(60*60*24*30)%365;

If that number is beyond the limit of long then use BigInteger but then this calculation will not work.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM