我在Scala中使用Java的java.util.Date
类,想要比较一个Date
对象和当前时间。我知道可以通过使用getTime()
计算时间差:
(new java.util.Date()).getTime() - oldDate.getTime()
然而,这只给我留下了一个表示毫秒的long
。是否有更简单、更好的方法来获得时间差?
我在Scala中使用Java的java.util.Date
类,想要比较一个Date
对象和当前时间。我知道可以通过使用getTime()
计算时间差:
(new java.util.Date()).getTime() - oldDate.getTime()
然而,这只给我留下了一个表示毫秒的long
。是否有更简单、更好的方法来获得时间差?
点击这里查看示例。
该示例可以给出日期之间的天数、小时数、分钟数、秒数和毫秒数 :)
import java.util.Calendar;
import java.util.Date;
public class DateDifferent {
public static void main(String[] args) {
Date date1 = new Date(2009, 01, 10);
Date date2 = new Date(2009, 07, 01);
Calendar calendar1 = Calendar.getInstance();
Calendar calendar2 = Calendar.getInstance();
calendar1.setTime(date1);
calendar2.setTime(date2);
long milliseconds1 = calendar1.getTimeInMillis();
long milliseconds2 = calendar2.getTimeInMillis();
long diff = milliseconds2 - milliseconds1;
long diffSeconds = diff / 1000;
long diffMinutes = diff / (60 * 1000);
long diffHours = diff / (60 * 60 * 1000);
long diffDays = diff / (24 * 60 * 60 * 1000);
System.out.println("\nThe Date Different Example");
System.out.println("Time in milliseconds: " + diff + " milliseconds.");
System.out.println("Time in seconds: " + diffSeconds + " seconds.");
System.out.println("Time in minutes: " + diffMinutes + " minutes.");
System.out.println("Time in hours: " + diffHours + " hours.");
System.out.println("Time in days: " + diffDays + " days.");
}
}
使用 GMT 时区获取 Calendar 实例,使用 Calendar 类的 set 方法设置时间。GMT 时区具有 0 偏移量(并不重要),并且夏令时标志设置为 false。
final Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"));
cal.set(Calendar.YEAR, 2011);
cal.set(Calendar.MONTH, 9);
cal.set(Calendar.DAY_OF_MONTH, 29);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
final Date startDate = cal.getTime();
cal.set(Calendar.YEAR, 2011);
cal.set(Calendar.MONTH, 12);
cal.set(Calendar.DAY_OF_MONTH, 21);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
final Date endDate = cal.getTime();
System.out.println((endDate.getTime() - startDate.getTime()) % (1000l * 60l * 60l * 24l));
java.util.Date
等情况下这是一个好的答案。使用将时区设置为GMT的技巧可以使代码对夏令时效应不敏感。 - Meno HochschildString startDate = "Jan 01 2015";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMM dd yyyy");
LocalDate date = LocalDate.parse(startDate, formatter);
String currentDate = "Feb 11 2015";
LocalDate date1 = LocalDate.parse(currentDate, formatter);
System.out.println(date1.toEpochDay() - date.toEpochDay());
(Date1-Date2)/86 400 000
那个数字是一天中的毫秒数。
一个日期-另一个日期会给你毫秒级别的差异。
将答案收集在一个双精度变量中。
这里提供一种正确的Java 7解决方案,时间复杂度为O(1),不需要任何依赖。
public static int countDaysBetween(Date date1, Date date2) {
Calendar c1 = removeTime(from(date1));
Calendar c2 = removeTime(from(date2));
if (c1.get(YEAR) == c2.get(YEAR)) {
return Math.abs(c1.get(DAY_OF_YEAR) - c2.get(DAY_OF_YEAR)) + 1;
}
// ensure c1 <= c2
if (c1.get(YEAR) > c2.get(YEAR)) {
Calendar c = c1;
c1 = c2;
c2 = c;
}
int y1 = c1.get(YEAR);
int y2 = c2.get(YEAR);
int d1 = c1.get(DAY_OF_YEAR);
int d2 = c2.get(DAY_OF_YEAR);
return d2 + ((y2 - y1) * 365) - d1 + countLeapYearsBetween(y1, y2) + 1;
}
private static int countLeapYearsBetween(int y1, int y2) {
if (y1 < 1 || y2 < 1) {
throw new IllegalArgumentException("Year must be > 0.");
}
// ensure y1 <= y2
if (y1 > y2) {
int i = y1;
y1 = y2;
y2 = i;
}
int diff = 0;
int firstDivisibleBy4 = y1;
if (firstDivisibleBy4 % 4 != 0) {
firstDivisibleBy4 += 4 - (y1 % 4);
}
diff = y2 - firstDivisibleBy4 - 1;
int divisibleBy4 = diff < 0 ? 0 : diff / 4 + 1;
int firstDivisibleBy100 = y1;
if (firstDivisibleBy100 % 100 != 0) {
firstDivisibleBy100 += 100 - (firstDivisibleBy100 % 100);
}
diff = y2 - firstDivisibleBy100 - 1;
int divisibleBy100 = diff < 0 ? 0 : diff / 100 + 1;
int firstDivisibleBy400 = y1;
if (firstDivisibleBy400 % 400 != 0) {
firstDivisibleBy400 += 400 - (y1 % 400);
}
diff = y2 - firstDivisibleBy400 - 1;
int divisibleBy400 = diff < 0 ? 0 : diff / 400 + 1;
return divisibleBy4 - divisibleBy100 + divisibleBy400;
}
public static Calendar from(Date date) {
Calendar c = Calendar.getInstance();
c.setTime(date);
return c;
}
public static Calendar removeTime(Calendar c) {
c.set(HOUR_OF_DAY, 0);
c.set(MINUTE, 0);
c.set(SECOND, 0);
c.set(MILLISECOND, 0);
return c;
}
鉴于该问题标记了Scala,
import scala.concurrent.duration._
val diff = (System.currentTimeMillis() - oldDate.getTime).milliseconds
val diffSeconds = diff.toSeconds
val diffMinutes = diff.toMinutes
val diffHours = diff.toHours
val diffDays = diff.toDays
class Duration {
private final TimeUnit unit;
private final long length;
// ...
}
或者你可以使用Joda:
DateTime a = ..., b = ...;
Duration d = new Duration(a, b);
仅回答最初的问题:
将以下代码放入一个函数中,例如Long getAge(){}
Date dahora = new Date();
long MillisToYearsByDiv = 1000l *60l * 60l * 24l * 365l;
long javaOffsetInMillis = 1990l * MillisToYearsByDiv;
long realNowInMillis = dahora.getTime() + javaOffsetInMillis;
long realBirthDayInMillis = this.getFechaNac().getTime() + javaOffsetInMillis;
long ageInMillis = realNowInMillis - realBirthDayInMillis;
return ageInMillis / MillisToYearsByDiv;
在进行乘法和除法计算时,最重要的是使用长数字。当然,在Java计算日期时应用的偏移量也很重要。
:)
这可能是最直接的方法 - 也许是因为我已经用Java编码(虽然它的日期和时间库确实有些笨重)有一段时间了,但那段代码看起来对我来说“简单而美好”!
你是否满意以毫秒返回结果,或者你的问题的一部分是你希望以其他格式返回结果?
如果您想要解决日期范围跨越夏令时边界(例如一个日期在夏季时间,另一个日期在冬季时间)的问题,您可以使用以下方法来获取天数差异:
最初的回答
public static long calculateDifferenceInDays(Date start, Date end, Locale locale) {
Calendar cal = Calendar.getInstance(locale);
cal.setTime(start);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
long startTime = cal.getTimeInMillis();
cal.setTime(end);
cal.set(Calendar.HOUR_OF_DAY, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
long endTime = cal.getTimeInMillis();
// calculate the offset if one of the dates is in summer time and the other one in winter time
TimeZone timezone = cal.getTimeZone();
int offsetStart = timezone.getOffset(startTime);
int offsetEnd = timezone.getOffset(endTime);
int offset = offsetEnd - offsetStart;
return TimeUnit.MILLISECONDS.toDays(endTime - startTime + offset);
}
Date
、Calendar
和SimpleDateFormat
就太不应该了”。 - Basil Bourquejava.time.Period
和/或Duration
。请查看下面的Basil Bourque的答案。 - Ole V.V.