简体   繁体   English

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

[英]Why does this time unit conversion return zeroes?

I am experiencing a problem with the code below. 我的以下代码有问题。 It's converting milliseconds to months, days, hours, and minutes. 它将毫秒转换为几个月,几天,几小时和几分钟。

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);

Why are the result values all zeroes? 为什么结果值全为零?

EDIT: @BicycleDude I modify your code into: 编辑:@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;

But the hours doesn't work 但是时间不起作用

'anything % 1' will return 0. it's probably not what you intended. “%1”将返回0。这可能不是您想要的。

  1. The variables you divide initially are type long. 您最初划分的变量的类型为long。 So their results will also be long. 因此,他们的结果也将很长。 (eg 12345 / 100 = 123 not 123.45). (例如12345/100 = 123而不是123.45)。
  2. The modulo operator works on remainder on division of integers. 模运算符处理整数除法的余数。 (eg 12345 % 100 = 45). (例如12345%100 = 45)。
  3. The algorithm you supplied doesn't extract day, month, hour, minute, second in the manner you expected. 您提供的算法不会以您期望的方式提取日,月,时,分,秒。 It requires rework before it's correct. 在正确之前,需要进行返工。

I've reworked the formulas with the assumption there are 31 days in a month: 我重新设计了公式,并假设一个月中有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;

The TimeUnit class provides factory methods that simplifies most of your work: 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);

I'm going to base my answer on the edited part of the code, since BicycleDude has already pointed out what was wrong with the modulo operations. 我将基于代码的编辑部分来回答问题,因为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)

Alright, I thought there would be multiple problems, but I think ( think , I'm probably missing something...) that the main error is coming from your calculation of months, which I denoted in the code by the comment (1) . 好的,我认为会有多个问题,但是我认为( 认为 ,我可能会遗漏某些东西...)主要错误来自于您对月份的计算,我在代码中用注释(1)表示了这一点。 。 You can't calculate the difference in months like that. 您无法像这样计算出几个月的差异。

Why? 为什么? What about if there was more than one month in differences? 如果差异超过一个月该怎么办? Wouldn't you need to divide by 31, instead? 您不需要除以31吗? Or if it was a leap year? 还是如果是a年? You'd need to divide by 29 if it was February. 如果是二月,则需要除以29。 Since integer division doesn't round or account for decimals, you can get inaccuracies in your difference-in-months calculation. 由于整数除法不会四舍五入或不计算小数,因此在月差计算中可能会出现误差。 It's probably best if you instead use the differences in hours to calculate the difference in days, and from there you can figure out the difference in months. 最好是改用小时数差异来计算天数差异,然后从中找出月份数差异。 ( Edit : I think you'd also need to take into account the factors I mentioned above when calculating the difference in months from the difference in days, by checking what your "origin" and "target" dates are, though I wouldn't be too sure of writing it myself at thie stage...) 编辑 :我认为您在通过天数差异计算月份差异时,还需要考虑上述因素,方法是检查您的“原始”和“目标”日期,尽管我不会一定要在自己编写阶段自己写它...)

Since you have a problem with the way you calculate the difference in months, and you use the erroneous value to calculate the difference in days, I think this results in the error propagating down to some of your other values (eg. the difference in hours). 由于您在计算月份差异方面的方式存在问题,并且您使用错误的值来计算以天为单位的差异,因此我认为这会导致错误传播到其他一些值(例如,小时差异) )。

EDIT 编辑

Okay, I mucked around with the code a bit more. 好的,我还弄乱了代码。 As I noted earlier, your months calculation was dangerous and affected your days calculation, which potentially introduced errors later on. 如前所述,您的月份计算很危险,并且影响了您的天数计算,这可能在以后引入错误。

With the example you provided in the comments, your code had a discrepancy of 3 days in the number of days. 在注释中提供的示例中,您的代码的天数差异为3天。 (The example was 19 January 2012 to 3 May 2012). (示例为2012年1月19日至2012年5月3日)。 I ran this against BicycleDude's code and it was fine. 我是根据BicycleDude的代码运行的,这很好。

I'll repost the code, and I've just added one line to find the number of days, based on how many hours have passed. 我将重新发布代码,并根据经过的小时数添加了一行代码来查找天数。

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;

If you like to make it so that you can read that "there are w days, x hours, y minutes and z seconds between date2l and date1l", you could do something like this: 如果您要这样做,可以读到“ 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);

And it appears to work. 它似乎起作用。

I haven't figured out the months part because that's a lot more non-trivial, but yeah. 我还没有弄清楚几个月的部分,因为那是不平凡的,但是是的。 This kinda works? 这种工作吗?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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