为什么这个时间单位转换返回零?

时间:2012-01-19 03:28:30

标签: java math integer floating-point long-integer

我遇到了以下代码的问题。它将毫秒转换为月,日,小时和分钟。

long diffms = date2l - date1l; //The result here is in milliseconds; The value of date2l - date1l are different
long diff_minute = diffms / 60000;

long diff_hour = diff_minute / 60; float diff_minute_now = (diff_minute % 1) * 60; int dmn = (int) diff_minute_now;
long diff_day = diff_hour / 24; float diff_hour_now = (diff_hour % 1) * 24; int dhn = (int) diff_hour_now;
long diff_month = diff_day / 30; float diff_day_now = (diff_day % 1) * 30;  int ddn = (int) diff_day_now;   

diffe = new LabelField
("Remaining Time : " + Long.toString(diff_month) + " month(s) " 
                    + Integer.toString(ddn) + " day(s) " 
                    + Integer.toString(dhn) + " hour(s) "
                    + Integer.toString(dmn) + " minute(s)");
add(diffe);

为什么结果值全为零?

编辑: @BicycleDude我将你的代码修改为:

long diffms = date2l - date1l;
long ts = diffms / 1000;

long mo = ts / 60 / 60 / 24 / 30;
long d = (ts - mo * 30 * 24 * 60 * 60) / (60 * 60 * 24);
long h = (ts - d * 24 * 60 * 60) / (60 * 60);
long m = (ts - h * 60 * 60) / 60;

但是时间不起作用

3 个答案:

答案 0 :(得分:5)

'任何%1'将返回0.它可能不是你想要的。

  1. 您最初划分的变量是long类型。所以他们的结果也会很长。 (例如12345/100 = 123而不是123.45)。
  2. 模运算符用于整数除法的余数。 (例如12345%100 = 45)。
  3. 您提供的算法不会以您期望的方式提取日,月,小时,分钟,秒。它需要返工才能正确。
  4. 我假设一个月有31天,我重新设计了这些公式:

    long diffms = date2l - date1l;
    long mo = (diffms / 1000 / 60 / 60 / 24 / 31);
    long d = (diffms / 1000 / 60 / 60 / 24) % 31;
    long h = (diffms / 1000 / 60 / 60) % 24;
    long m = (diffms / 1000 / 60) % 60;
    long s = (diffms / 1000) % 60;
    

答案 1 :(得分:1)

我将根据代码的编辑部分给出答案,因为BicycleDude已经指出了模运算的错误。

long diffms = date2l - date1l; //difference in ms
long ts = diffms / 1000; //total difference in seconds

long mo = ts / 60 / 60 / 24 / 30; //(1)
long d = (ts - mo * 30 * 24 * 60 * 60) / (60 * 60 * 24); //follows on because of (1)
long h = (ts - d * 24 * 60 * 60) / (60 * 60); //follows on because of (1)
long m = (ts - h * 60 * 60) / 60; //follows on because of (1)

好吧,我认为会有多个问题,但我认为(认为,我可能会遗漏某些东西......)主要错误来自你的月计算,我在代码中由注释(1)表示。你无法计算这样的月份差异。

为什么呢?如果差异超过一个月怎么办?你需要除以31吗?或者如果是闰年?如果是2月,你需要除以29。由于整数除法不会舍入或占小数,因此您的差异计算可能会出现不准确的情况。如果您反而使用小时差异来计算天数差异,那么最好用几个月来计算差异。 (修改:我认为您还需要考虑我上面提到的因素,通过检查您的“来源”和“目标”日期来计算月份差异的月份差异是的,虽然我不太确定自己在这个舞台上写作......)

由于您计算差异的方式存在问题,并且您使用错误的值来计算天数的差异,我认为这会导致错误传播到您的其他一些值(例如小时差异。)

修改

好的,我更多地使用了代码。正如我前面提到的,您的月计算是危险的,会影响您的日期计算,这可能会在以后引入错误。

根据您在评论中提供的示例,您的代码在天数上存在3天的差异。 (该示例是2012年1月19日至2012年5月3日)。我针对BicycleDude的代码运行了这个,很好。

我将重新发布代码,我刚刚添加了一行来查找天数,具体取决于已经过了多少小时。

long h = ts / 60 / 60; // hour part
long m = (ts - h * 60 * 60) / 60; // minute part
long s = (ts - h * 60 * 60 - m * 60); // second part
long d = h / 24;

如果您愿意这样做,以便您可以阅读“在date2l和date1l之间有w天,x小时,y分钟和z秒” ,你可以这样做:

long date2l = Timestamp.valueOf("2012-05-03 05:30:10").getTime();
long date1l = Timestamp.valueOf("2012-01-19 00:00:00").getTime();
long diffms = date2l - date1l; //difference in ms
long diff_seconds = diffms / 1000; //total difference in seconds
long diff_mins = diff_seconds / 60; //total difference in minutes
long diff_hours = diff_mins / 60; //total difference in hours
long diff_days = diff_hours / 24; //total difference in days

long x = (diff_seconds - diff_days * 60 * 60 * 24) / (60 * 60);
long y = ((diff_seconds - (diff_hours * 60 * 60))) / 60;
long z = ((diff_seconds - (diff_mins * 60)));
long w = diff_days;

System.out.println(w + " " + x + " " + y + " " + z);

它似乎有用。

我还没有想出几个月的部分,因为那是非常重要的,但是是的。这有用吗?

答案 2 :(得分:1)

TimeUnit类提供简化大部分工作的工厂方法:

import static java.util.concurrent.TimeUnit.*; 


// First, calculate the total difference in each unit
long diffDays = MILLISECONDS.toDays(diffMs);
long diffHours = MILLISECONDS.toHours(diffMs);
long diffMinutes = MILLISECONDS.toMinutes(diffMs);
long diffSeconds = MILLISECONDS.toSeconds(diffMs);

// Next, calculate the differences
long months = diffDays / 30;
long days = diffDays - 30 * months;
long hours = diffHours - DAYS.toHours(diffDays);
long minutes = diffMinutes - HOURS.toMinutes(diffHours);
long seconds = diffSeconds - MINUTES.toSeconds(diffMinutes);