计算两个 Java 日期实例之间的差异

发布于 2024-09-14 11:19:19 字数 260 浏览 7 评论 0原文

我在 Scala 中使用 Java 的 java.util.Date 类,并且想要比较 Date 对象和当前时间。我知道我可以使用 getTime() 来计算增量:

(new java.util.Date()).getTime() - oldDate.getTime()

但是,这只会给我留下一个代表毫秒的 long 。有没有更简单、更好的方法来获取时间增量?

I'm using Java's java.util.Date class in Scala and want to compare a Date object and the current time. I know I can calculate the delta by using getTime():

(new java.util.Date()).getTime() - oldDate.getTime()

However, this just leaves me with a long representing milliseconds. Is there any simpler, nicer way to get a time delta?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(30

于我来说 2024-09-21 11:19:19

简单的 diff (不带 lib)

/**
 * Get a diff between two dates
 * @param date1 the oldest date
 * @param date2 the newest date
 * @param timeUnit the unit in which you want the diff
 * @return the diff value, in the provided unit
 */
public static long getDateDiff(Date date1, Date date2, TimeUnit timeUnit) {
    long diffInMillies = date2.getTime() - date1.getTime();
    return timeUnit.convert(diffInMillies,TimeUnit.MILLISECONDS);
}

然后你可以调用:

getDateDiff(date1,date2,TimeUnit.MINUTES);

来获取 2 个日期的差异(以分钟为单位)。

TimeUnitjava.util.concurrent.TimeUnit,一个从纳秒到天的标准 Java 枚举。


人类可读的差异(不带 lib)

public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) {

    long diffInMillies = date2.getTime() - date1.getTime();

    //create the list
    List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));
    Collections.reverse(units);

    //create the result map of TimeUnit and difference
    Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();
    long milliesRest = diffInMillies;

    for ( TimeUnit unit : units ) {
        
        //calculate difference in millisecond 
        long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);
        long diffInMilliesForUnit = unit.toMillis(diff);
        milliesRest = milliesRest - diffInMilliesForUnit;

        //put the result in the map
        result.put(unit,diff);
    }

    return result;
}

http://ideone.com/5dXeu6

输出类似于 Map :{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0},单位已排序。

您只需将该映射转换为用户友好的字符串即可。


警告

上面的代码片段计算两个时刻之间的简单差异。它可能会在夏令时切换期间导致问题,如这篇文章中所述。这意味着,如果您计算没有时间的日期之间的差异,则可能会缺少日期/小时。

在我看来,日期差异有点主观,尤其是在几天内。您可以:

  • 计算 24 小时经过的时间:天+1 - 天=1 天=24 小时

  • 计算经过的时间数,考虑夏令时:day+1 - day = 1 = 24h(但使用午夜时间和夏令时)节省时间可能是 0 天 23 小时)

  • 计算日切换的数量,这意味着 day+1 1pm - day 11am = 1 天,即使经过的时间只有 2 小时(如果有夏令时则​​为 1 小时:p)

我的答案是如果您对天数的日期差异的定义与第一种情况匹配,则有效 使用

JodaTime

如果您使用 JodaTime,您可以通过以下方式获取 2 个瞬间(米莉支持 ReadableInstant)日期的差异:

Interval interval = new Interval(oldInstant, new Instant());

但您也可以获取本地日期/时间的差异:

// returns 4 because of the leap year of 366 days
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5), PeriodType.years()).getYears() 

// this time it returns 5
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5+1), PeriodType.years()).getYears() 

// And you can also use these static methods
Years.yearsBetween(LocalDate.now(), LocalDate.now().plusDays(365*5)).getYears()

Simple diff (without lib)

/**
 * Get a diff between two dates
 * @param date1 the oldest date
 * @param date2 the newest date
 * @param timeUnit the unit in which you want the diff
 * @return the diff value, in the provided unit
 */
public static long getDateDiff(Date date1, Date date2, TimeUnit timeUnit) {
    long diffInMillies = date2.getTime() - date1.getTime();
    return timeUnit.convert(diffInMillies,TimeUnit.MILLISECONDS);
}

And then you can call:

getDateDiff(date1,date2,TimeUnit.MINUTES);

to get the diff of the 2 dates in minutes unit.

TimeUnit is java.util.concurrent.TimeUnit, a standard Java enum going from nanos to days.


Human readable diff (without lib)

public static Map<TimeUnit,Long> computeDiff(Date date1, Date date2) {

    long diffInMillies = date2.getTime() - date1.getTime();

    //create the list
    List<TimeUnit> units = new ArrayList<TimeUnit>(EnumSet.allOf(TimeUnit.class));
    Collections.reverse(units);

    //create the result map of TimeUnit and difference
    Map<TimeUnit,Long> result = new LinkedHashMap<TimeUnit,Long>();
    long milliesRest = diffInMillies;

    for ( TimeUnit unit : units ) {
        
        //calculate difference in millisecond 
        long diff = unit.convert(milliesRest,TimeUnit.MILLISECONDS);
        long diffInMilliesForUnit = unit.toMillis(diff);
        milliesRest = milliesRest - diffInMilliesForUnit;

        //put the result in the map
        result.put(unit,diff);
    }

    return result;
}

http://ideone.com/5dXeu6

The output is something like Map:{DAYS=1, HOURS=3, MINUTES=46, SECONDS=40, MILLISECONDS=0, MICROSECONDS=0, NANOSECONDS=0}, with the units ordered.

You just have to convert that map to a user-friendly string.


Warning

The above code snippets compute a simple diff between 2 instants. It can cause problems during a daylight saving switch, like explained in this post. This means if you compute the diff between dates with no time you may have a missing day/hour.

In my opinion the date diff is kind of subjective, especially on days. You may:

  • count the number of 24h elapsed time: day+1 - day = 1 day = 24h

  • count the number of elapsed time, taking care of daylight savings: day+1 - day = 1 = 24h (but using midnight time and daylight savings it could be 0 day and 23h)

  • count the number of day switches, which means day+1 1pm - day 11am = 1 day, even if the elapsed time is just 2h (or 1h if there is a daylight saving :p)

My answer is valid if your definition of date diff on days match the 1st case

With JodaTime

If you are using JodaTime you can get the diff for 2 instants (millies backed ReadableInstant) dates with:

Interval interval = new Interval(oldInstant, new Instant());

But you can also get the diff for Local dates/times:

// returns 4 because of the leap year of 366 days
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5), PeriodType.years()).getYears() 

// this time it returns 5
new Period(LocalDate.now(), LocalDate.now().plusDays(365*5+1), PeriodType.years()).getYears() 

// And you can also use these static methods
Years.yearsBetween(LocalDate.now(), LocalDate.now().plusDays(365*5)).getYears()
早茶月光 2024-09-21 11:19:19

不幸的是,JDK Date API 严重损坏。我建议使用 Joda Time 库

Joda Time 有一个时间概念 间隔

Interval interval = new Interval(oldTime, new Instant());

编辑:顺便说一下,Joda 有两个概念:Interval 用于表示两个时刻之间的时间间隔(表示上午 8 点到 10 点之间的时间),以及 Duration 表示没有实际时间的时间长度边界(例如代表两个小时!)

如果您只关心时间比较,大多数 Date 实现(包括 JDK 的)都实现 Comparable 接口,该接口允许您使用 Comparable.compareTo()

The JDK Date API is horribly broken unfortunately. I recommend using Joda Time library.

Joda Time has a concept of time Interval:

Interval interval = new Interval(oldTime, new Instant());

EDIT: By the way, Joda has two concepts: Interval for representing an interval of time between two time instants (represent time between 8am and 10am), and a Duration that represents a length of time without the actual time boundaries (e.g. represent two hours!)

If you only care about time comparisions, most Date implementations (including the JDK one) implements Comparable interface which allows you to use the Comparable.compareTo()

圈圈圆圆圈圈 2024-09-21 11:19:19
int diffInDays = (int)( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) )

请注意,这适用于 UTC 日期,因此如果您查看本地日期,差异可能是休息一天。由于夏令时的原因,要使其与本地日期正确配合需要采用完全不同的方法。

int diffInDays = (int)( (newerDate.getTime() - olderDate.getTime()) 
                 / (1000 * 60 * 60 * 24) )

Note that this works with UTC dates, so the difference may be a day off if you look at local dates. And getting it to work correctly with local dates requires a completely different approach due to daylight savings time.

孤君无依 2024-09-21 11:19:19

使用 java.time 框架构建进入 Java 8+:

ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime oldDate = now.minusDays(1).minusMinutes(10);
Duration duration = Duration.between(oldDate, now);
System.out.println("ISO-8601: " + duration);
System.out.println("Minutes: " + duration.toMinutes());

输出:

ISO-8601:PT24H10M

分钟:1450

有关详细信息,请参阅 Oracle 教程ISO 8601 标准。

Using the java.time framework built into Java 8+:

ZonedDateTime now = ZonedDateTime.now();
ZonedDateTime oldDate = now.minusDays(1).minusMinutes(10);
Duration duration = Duration.between(oldDate, now);
System.out.println("ISO-8601: " + duration);
System.out.println("Minutes: " + duration.toMinutes());

Output:

ISO-8601: PT24H10M

Minutes: 1450

For more info, see the Oracle Tutorial and the ISO 8601 standard.

少女情怀诗 2024-09-21 11:19:19

tl;dr

将过时的 java.util.Date 对象转换为其替换对象 java.time.Instant。然后将经过的时间计算为Duration

Duration d = 
    Duration.between(                   // Calculate the span of time between two moments as a number of hours, minutes, and seconds.
        myJavaUtilDate.toInstant() ,    // Convert legacy class to modern class by calling new method added to the old class.
        Instant.now()                   // Capture the current moment in UTC. About two and a half hours later in this example.
    )
;

d.toString(): PT2H34M56S

d.toMinutes(): 154

d.toMinutesPart(): 34

ISO 8601 格式: PnYnMnDTnHnMnS

合理的标准 ISO 8601 定义了一段时间跨度的简明文本表示,如年、月、日、小时等。该标准将这样的跨度称为 < a href="https://en.wikipedia.org/wiki/ISO_8601#Durations" rel="noreferrer">持续时间。格式为 PnYnMnDTnHnMnS,其中 P 表示“周期”,T 将日期部分与时间部分分开,其间是后面跟随的数字通过一封信。

示例:

  • P3Y6M4DT12H30M5S
    三年六个月四天十二小时三十分钟五秒
  • PT4H30M
    四个半小时

java.time

内置的 java.time 框架Java 8 及更高版本取代了麻烦的旧 java.util.Date/java.util.Calendar 类。新类的灵感来自于非常成功的 Joda-Time 框架,旨在作为其后继者,类似在概念上但重新架构。由 JSR 310 定义。由 ThreeTen-Extra 项目扩展。请参阅教程

a

即时 类代表 UTC 时间轴上的一个时刻,分辨率为 纳秒(最多九 (9) 位小数)。

Instant instant = Instant.now() ;  // Capture current moment in UTC.

最好避免使用遗留类,例如 Date/Calendar。但是,如果您必须与尚未更新到 java.time 的旧代码进行互操作,请来回转换。调用添加到旧类中的新转换方法。用于从 java.util.Date< /code>Instant,调用 日期::toInstant

Instant instant = myJavaUtilDate.toInstant() ;  // Convert from legacy `java.util.Date` class to modern `java.time.Instant` class.

时间跨度

将这种将时间跨度表示为年、月、日、小时、分钟、秒的想法分成两半:

  • java.time类 com/javase/8/docs/api/java/time/Period.html" rel="noreferrer">Period 代表年、月、日
  • Duration 表示天、小时、分钟、秒

这里就是一个例子。

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now ( zoneId );
ZonedDateTime future = now.plusMinutes ( 63 );
Duration duration = Duration.between ( now , future );

转储到控制台。

PeriodDuration 均使用 ISO 8601< /a> 用于生成其值的字符串表示形式的标准。

System.out.println ( "now: " + now + " to future: " + now + " = " + duration );

现在:2015-11-26T00:46:48.016-05:00[美国/蒙特利尔] 到未来:2015-11-26T00:46:48.016-05:00[美国/蒙特利尔] = PT1H3M

Java 9 向 Duration 获取天部分、小时部分、分钟部分和秒部分。

您可以获得整个 Duration 内的总天数或小时数或分钟数或秒数或毫秒数或纳秒数。

long totalHours = duration.toHours();

在 Java 9 中,Duration 类获得新方法返回天、小时、分钟、秒、毫秒/纳秒的各个部分。调用 to...Part 方法:toDaysPart()toHoursPart() 等。

ChronoUnit

如果您只关心更简单的较大时间粒度,例如“经过的天数”,请使用 ChronoUnit 枚举。

long daysElapsed = ChronoUnit.DAYS.between( earlier , later );

另一个例子。

Instant now = Instant.now();
Instant later = now.plus( Duration.ofHours( 2 ) );
…
long minutesElapsed = ChronoUnit.MINUTES.between( now , later );

120


关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧遗留日期时间类,例如java.util.Date, 日历,& SimpleDateFormat

Joda-Time 项目,现位于 维护模式,建议迁移到 java.time。

要了解更多信息,请参阅 Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范为 JSR 310

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是 java.time 未来可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如 IntervalYearWeekYearQuarter,以及更多


Joda-Time

更新: Joda-Time 项目现已位于 维护模式,团队建议迁移到 java.time 类。我将这一部分原封不动地留作历史。

Joda-Time 库使用 ISO 8601 作为默认值。它的Period类解析并生成这些PnYnMnDTnHnMnS字符串。

DateTime now = DateTime.now(); // Caveat: Ignoring the important issue of time zones.
Period period = new Period( now, now.plusHours( 4 ).plusMinutes( 30));
System.out.println( "period: " + period );

渲染:

period: PT4H30M

tl;dr

Convert your obsolete java.util.Date objects to their replacement, java.time.Instant. Then calculate the elapsed time as a Duration.

Duration d = 
    Duration.between(                   // Calculate the span of time between two moments as a number of hours, minutes, and seconds.
        myJavaUtilDate.toInstant() ,    // Convert legacy class to modern class by calling new method added to the old class.
        Instant.now()                   // Capture the current moment in UTC. About two and a half hours later in this example.
    )
;

d.toString(): PT2H34M56S

d.toMinutes(): 154

d.toMinutesPart(): 34

ISO 8601 Format: PnYnMnDTnHnMnS

The sensible standard ISO 8601 defines a concise textual representation of a span of time as a number of years, months, days, hours, etc. The standard calls such such a span a duration. The format is PnYnMnDTnHnMnS where the P means "Period", the T separates the date portion from the time portion, and in between are numbers followed by a letter.

Examples:

  • P3Y6M4DT12H30M5S
    three years, six months, four days, twelve hours, thirty minutes, and five seconds
  • PT4H30M
    Four and a half hours

java.time

The java.time framework built into Java 8 and later supplants the troublesome old java.util.Date/java.util.Calendar classes. The new classes are inspired by the highly successful Joda-Time framework, intended as its successor, similar in concept but re-architected. Defined by JSR 310. Extended by the ThreeTen-Extra project. See the Tutorial.

Moment

The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Instant instant = Instant.now() ;  // Capture current moment in UTC.

Best to avoid the legacy classes such as Date/Calendar. But if you must inter-operate with old code not yet updated to java.time, convert back and forth. Call new conversion methods added to the old classes. For moving from a java.util.Date to an Instant, call Date::toInstant.

Instant instant = myJavaUtilDate.toInstant() ;  // Convert from legacy `java.util.Date` class to modern `java.time.Instant` class.

Span of time

The java.time classes have split this idea of representing a span of time as a number of years, months, days, hours, minutes, seconds into two halves:

  • Period for years, months, days
  • Duration for days, hours, minutes, seconds

Here is an example.

ZoneId zoneId = ZoneId.of ( "America/Montreal" );
ZonedDateTime now = ZonedDateTime.now ( zoneId );
ZonedDateTime future = now.plusMinutes ( 63 );
Duration duration = Duration.between ( now , future );

Dump to console.

Both Period and Duration use the ISO 8601 standard for generating a String representation of their value.

System.out.println ( "now: " + now + " to future: " + now + " = " + duration );

now: 2015-11-26T00:46:48.016-05:00[America/Montreal] to future: 2015-11-26T00:46:48.016-05:00[America/Montreal] = PT1H3M

Java 9 adds methods to Duration to get the days part, hours part, minutes part, and seconds part.

You can get the total number of days or hours or minutes or seconds or milliseconds or nanoseconds in the entire Duration.

long totalHours = duration.toHours();

In Java 9 the Duration class gets new methods for returning the various parts of days, hours, minutes, seconds, milliseconds/nanoseconds. Call the to…Part methods: toDaysPart(), toHoursPart(), and so on.

ChronoUnit

If you only care about a simpler larger granularity of time, such as “number of days elapsed”, use the ChronoUnit enum.

long daysElapsed = ChronoUnit.DAYS.between( earlier , later );

Another example.

Instant now = Instant.now();
Instant later = now.plus( Duration.ofHours( 2 ) );
…
long minutesElapsed = ChronoUnit.MINUTES.between( now , later );

120


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to java.time.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.


Joda-Time

UPDATE: The Joda-Time project is now in maintenance mode, with the team advising migration to the java.time classes. I leave this section intact for history.

The Joda-Time library uses ISO 8601 for its defaults. Its Period class parses and generates these PnYnMnDTnHnMnS strings.

DateTime now = DateTime.now(); // Caveat: Ignoring the important issue of time zones.
Period period = new Period( now, now.plusHours( 4 ).plusMinutes( 30));
System.out.println( "period: " + period );

Renders:

period: PT4H30M
你的背包 2024-09-21 11:19:19

您需要更清楚地定义您的问题。例如,您可以仅获取两个 Date 对象之间的毫秒数,然后除以 24 小时内的毫秒数...但是:

  • 这不会花费考虑时区 - 日期 始终采用 UTC
  • 这不会考虑夏令时(例如,可能有几天只有 23 小时长)
  • 即使在 UTC 内,也有多少天8月16日晚上11点到8月18日凌晨2点有吗?才27个小时,难道就是一天吗?或者应该是三天,因为它涵盖了三个日期?

You need to define your problem more clearly. You could just take the number of milliseconds between the two Date objects and divide by the number of milliseconds in 24 hours, for example... but:

  • This won't take time zones into consideration - Date is always in UTC
  • This won't take daylight saving time into consideration (where there can be days which are only 23 hours long, for example)
  • Even within UTC, how many days are there in August 16th 11pm to August 18th 2am? It's only 27 hours, so does that mean one day? Or should it be three days because it covers three dates?
宣告ˉ结束 2024-09-21 11:19:19
Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();

https://www.joda.org/joda-time/faq.html#datediff

Days d = Days.daysBetween(startDate, endDate);
int days = d.getDays();

https://www.joda.org/joda-time/faq.html#datediff

我的奇迹 2024-09-21 11:19:19

由于这里的所有答案都是正确的,但使用遗留的java或第3方库,如joda或类似的库,我将使用新的 java.time 类。请参阅 Oracle 教程

使用 LocalDateChronoUnit :

LocalDate d1 = LocalDate.of(2017, 5, 1);
LocalDate d2 = LocalDate.of(2017, 5, 18);

long days = ChronoUnit.DAYS.between(d1, d2);
System.out.println( days );

Since all the answers here are correct but use legacy java or 3rd party libs like joda or similar, I will just drop another way using new java.time classes in Java 8 and later. See Oracle Tutorial.

Use LocalDate and ChronoUnit:

LocalDate d1 = LocalDate.of(2017, 5, 1);
LocalDate d2 = LocalDate.of(2017, 5, 18);

long days = ChronoUnit.DAYS.between(d1, d2);
System.out.println( days );
┼── 2024-09-21 11:19:19

一个稍微简单的替代方案:

System.currentTimeMillis() - oldDate.getTime()

至于“更好”:那么,您到底需要什么?将持续时间表示为小时数和天数等的问题在于,由于日期的复杂性,它可能会导致不准确和错误的期望(例如,由于夏令时,天可能有 23 或 25 小时)。

A slightly simpler alternative:

System.currentTimeMillis() - oldDate.getTime()

As for "nicer": well, what exactly do you need? The problem with representing time durations as a number of hours and days etc. is that it may lead to inaccuracies and wrong expectations due to the complexity of dates (e.g. days can have 23 or 25 hours due to daylight savings time).

风尘浪孓 2024-09-21 11:19:19

使用毫秒方法可能会在某些区域设置中导致问题。

例如,两个日期 03/24/2007 和 03/25/2007 之间的差异应为 1 天;

但是,如果您在英国运行此路线,则使用毫秒路线,您将获得 0 天!

/** Manual Method - YIELDS INCORRECT RESULTS - DO NOT USE**/  
/* This method is used to find the no of days between the given dates */  
public long calculateDays(Date dateEarly, Date dateLater) {  
   return (dateLater.getTime() - dateEarly.getTime()) / (24 * 60 * 60 * 1000);  
} 

实现此目的的更好方法是使用 java.util.Calendar

/** Using Calendar - THE CORRECT WAY**/  
public static long daysBetween(Calendar startDate, Calendar endDate) {  
  Calendar date = (Calendar) startDate.clone();  
  long daysBetween = 0;  
  while (date.before(endDate)) {  
    date.add(Calendar.DAY_OF_MONTH, 1);  
    daysBetween++;  
  }  
  return daysBetween;  
}  

Using millisecond approach can cause problems in some locales.

Lets take, for example, the difference between the two dates 03/24/2007 and 03/25/2007 should be 1 day;

However, using the millisecond route, you'll get 0 days, if you run this in the UK!

/** Manual Method - YIELDS INCORRECT RESULTS - DO NOT USE**/  
/* This method is used to find the no of days between the given dates */  
public long calculateDays(Date dateEarly, Date dateLater) {  
   return (dateLater.getTime() - dateEarly.getTime()) / (24 * 60 * 60 * 1000);  
} 

Better way to implement this is to use java.util.Calendar

/** Using Calendar - THE CORRECT WAY**/  
public static long daysBetween(Calendar startDate, Calendar endDate) {  
  Calendar date = (Calendar) startDate.clone();  
  long daysBetween = 0;  
  while (date.before(endDate)) {  
    date.add(Calendar.DAY_OF_MONTH, 1);  
    daysBetween++;  
  }  
  return daysBetween;  
}  
旧梦荧光笔 2024-09-21 11:19:19

您可以通过多种方法找到日期和日期之间的差异。次。我所知道的最简单的方法之一是:

      Calendar calendar1 = Calendar.getInstance();
      Calendar calendar2 = Calendar.getInstance();
      calendar1.set(2012, 04, 02);
      calendar2.set(2012, 04, 04);
      long milsecs1= calendar1.getTimeInMillis();
      long milsecs2 = calendar2.getTimeInMillis();
      long diff = milsecs2 - milsecs1;
      long dsecs = diff / 1000;
      long dminutes = diff / (60 * 1000);
      long dhours = diff / (60 * 60 * 1000);
      long ddays = diff / (24 * 60 * 60 * 1000);

      System.out.println("Your Day Difference="+ddays);

print 语句只是一个示例 - 您可以按照您喜欢的方式格式化它。

There are many ways you can find the difference between dates & times. One of the simplest ways that I know of would be:

      Calendar calendar1 = Calendar.getInstance();
      Calendar calendar2 = Calendar.getInstance();
      calendar1.set(2012, 04, 02);
      calendar2.set(2012, 04, 04);
      long milsecs1= calendar1.getTimeInMillis();
      long milsecs2 = calendar2.getTimeInMillis();
      long diff = milsecs2 - milsecs1;
      long dsecs = diff / 1000;
      long dminutes = diff / (60 * 1000);
      long dhours = diff / (60 * 60 * 1000);
      long ddays = diff / (24 * 60 * 60 * 1000);

      System.out.println("Your Day Difference="+ddays);

The print statement is just an example - you can format it, the way you like.

一页 2024-09-21 11:19:19

以毫秒为单位减去日期是可行的(如另一篇文章中所述),但在清除日期的时间部分时,您必须使用 HOUR_OF_DAY 而不是 HOUR:

public static final long MSPERDAY = 60 * 60 * 24 * 1000;
...
final Calendar dateStartCal = Calendar.getInstance();
dateStartCal.setTime(dateStart);
dateStartCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateStartCal.set(Calendar.MINUTE, 0);
dateStartCal.set(Calendar.SECOND, 0);
dateStartCal.set(Calendar.MILLISECOND, 0);
final Calendar dateEndCal = Calendar.getInstance();
dateEndCal.setTime(dateEnd);
dateEndCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateEndCal.set(Calendar.MINUTE, 0);
dateEndCal.set(Calendar.SECOND, 0);
dateEndCal.set(Calendar.MILLISECOND, 0);
final long dateDifferenceInDays = ( dateStartCal.getTimeInMillis()
                                  - dateEndCal.getTimeInMillis()
                                  ) / MSPERDAY;
if (dateDifferenceInDays > 15) {
    // Do something if difference > 15 days
}

Subtracting the dates in milliseconds works (as described in another post), but you have to use HOUR_OF_DAY and not HOUR when clearing the time parts of your dates:

public static final long MSPERDAY = 60 * 60 * 24 * 1000;
...
final Calendar dateStartCal = Calendar.getInstance();
dateStartCal.setTime(dateStart);
dateStartCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateStartCal.set(Calendar.MINUTE, 0);
dateStartCal.set(Calendar.SECOND, 0);
dateStartCal.set(Calendar.MILLISECOND, 0);
final Calendar dateEndCal = Calendar.getInstance();
dateEndCal.setTime(dateEnd);
dateEndCal.set(Calendar.HOUR_OF_DAY, 0); // Crucial.
dateEndCal.set(Calendar.MINUTE, 0);
dateEndCal.set(Calendar.SECOND, 0);
dateEndCal.set(Calendar.MILLISECOND, 0);
final long dateDifferenceInDays = ( dateStartCal.getTimeInMillis()
                                  - dateEndCal.getTimeInMillis()
                                  ) / MSPERDAY;
if (dateDifferenceInDays > 15) {
    // Do something if difference > 15 days
}
淡莣 2024-09-21 11:19:19

如果你不想使用JodaTime或类似的,最好的解决方案可能是这样的:

final static long MILLIS_PER_DAY = 24 * 3600 * 1000;
long msDiff= date1.getTime() - date2.getTime();
long daysDiff = Math.round(msDiff / ((double)MILLIS_PER_DAY));

每天的毫秒数并不总是相同的(因为夏令时和闰秒),但它非常接近,并且至少有偏差由于夏令时会在较长时间内取消。因此,除法然后舍入将给出正确的结果(至少只要使用的本地日历不包含除 DST 和闰秒之外的奇怪时间跳跃)。

请注意,这仍然假设 date1date2 设置为一天中的同一时间。正如 Jon Skeet 所指出的,对于一天中的不同时间,您首先必须定义“日期差异”的含义。

If you don't want to use JodaTime or similar, the best solution is probably this:

final static long MILLIS_PER_DAY = 24 * 3600 * 1000;
long msDiff= date1.getTime() - date2.getTime();
long daysDiff = Math.round(msDiff / ((double)MILLIS_PER_DAY));

The number of ms per day is not always the same (because of daylight saving time and leap seconds), but it's very close, and at least deviations due to daylight saving time cancel out over longer periods. Therefore dividing and then rounding will give a correct result (at least as long as the local calendar used does not contain weird time jumps other than DST and leap seconds).

Note that this still assumes that date1 and date2 are set to the same time of day. For different times of day, you'd first have to define what "date difference" means, as pointed out by Jon Skeet.

一桥轻雨一伞开 2024-09-21 11:19:19

看一下 Joda Time,它是一个改进的 Java 日期/时间 API,应该与 Scala 配合良好。

Take a look at Joda Time, which is an improved Date/Time API for Java and should work fine with Scala.

机场等船 2024-09-21 11:19:19
int daysDiff = (date1.getTime() - date2.getTime()) / MILLIS_PER_DAY;
int daysDiff = (date1.getTime() - date2.getTime()) / MILLIS_PER_DAY;
陌伤ぢ 2024-09-21 11:19:19

让我展示一下 Joda 间隔和天数之间的区别:

DateTime start = new DateTime(2012, 2, 6, 10, 44, 51, 0);
DateTime end = new DateTime(2012, 2, 6, 11, 39, 47, 1);
Interval interval = new Interval(start, end);
Period period = interval.toPeriod();
System.out.println(period.getYears() + " years, " + period.getMonths() + " months, " + period.getWeeks() + " weeks, " + period.getDays() + " days");
System.out.println(period.getHours() + " hours, " + period.getMinutes() + " minutes, " + period.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *1 weeks, 1 days*
//0 hours, 54 minutes, 56 seconds 

//Period can set PeriodType,such as PeriodType.yearMonthDay(),PeriodType.yearDayTime()...
Period p = new Period(start, end, PeriodType.yearMonthDayTime());
System.out.println(p.getYears() + " years, " + p.getMonths() + " months, " + p.getWeeks() + " weeks, " + p.getDays() + "days");
System.out.println(p.getHours() + " hours, " + p.getMinutes() + " minutes, " + p.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *0 weeks, 8 days*
//0 hours, 54 minutes, 56 seconds 

Let me show difference between Joda Interval and Days:

DateTime start = new DateTime(2012, 2, 6, 10, 44, 51, 0);
DateTime end = new DateTime(2012, 2, 6, 11, 39, 47, 1);
Interval interval = new Interval(start, end);
Period period = interval.toPeriod();
System.out.println(period.getYears() + " years, " + period.getMonths() + " months, " + period.getWeeks() + " weeks, " + period.getDays() + " days");
System.out.println(period.getHours() + " hours, " + period.getMinutes() + " minutes, " + period.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *1 weeks, 1 days*
//0 hours, 54 minutes, 56 seconds 

//Period can set PeriodType,such as PeriodType.yearMonthDay(),PeriodType.yearDayTime()...
Period p = new Period(start, end, PeriodType.yearMonthDayTime());
System.out.println(p.getYears() + " years, " + p.getMonths() + " months, " + p.getWeeks() + " weeks, " + p.getDays() + "days");
System.out.println(p.getHours() + " hours, " + p.getMinutes() + " minutes, " + p.getSeconds() + " seconds ");
//Result is:
//0 years, 0 months, *0 weeks, 8 days*
//0 hours, 54 minutes, 56 seconds 
榕城若虚 2024-09-21 11:19:19

如果您需要格式化的返回字符串,例如
“2 天 03h 42m 07s”,试试这个:

public String fill2(int value)
{
    String ret = String.valueOf(value);

    if (ret.length() < 2)
        ret = "0" + ret;            
    return ret;
}

public String get_duration(Date date1, Date date2)
{                   
    TimeUnit timeUnit = TimeUnit.SECONDS;

    long diffInMilli = date2.getTime() - date1.getTime();
    long s = timeUnit.convert(diffInMilli, TimeUnit.MILLISECONDS);

    long days = s / (24 * 60 * 60);
    long rest = s - (days * 24 * 60 * 60);
    long hrs = rest / (60 * 60);
    long rest1 = rest - (hrs * 60 * 60);
    long min = rest1 / 60;      
    long sec = s % 60;

    String dates = "";
    if (days > 0) dates = days + " Days ";

    dates += fill2((int) hrs) + "h ";
    dates += fill2((int) min) + "m ";
    dates += fill2((int) sec) + "s ";

    return dates;
}

If you need a formatted return String like
"2 Days 03h 42m 07s", try this:

public String fill2(int value)
{
    String ret = String.valueOf(value);

    if (ret.length() < 2)
        ret = "0" + ret;            
    return ret;
}

public String get_duration(Date date1, Date date2)
{                   
    TimeUnit timeUnit = TimeUnit.SECONDS;

    long diffInMilli = date2.getTime() - date1.getTime();
    long s = timeUnit.convert(diffInMilli, TimeUnit.MILLISECONDS);

    long days = s / (24 * 60 * 60);
    long rest = s - (days * 24 * 60 * 60);
    long hrs = rest / (60 * 60);
    long rest1 = rest - (hrs * 60 * 60);
    long min = rest1 / 60;      
    long sec = s % 60;

    String dates = "";
    if (days > 0) dates = days + " Days ";

    dates += fill2((int) hrs) + "h ";
    dates += fill2((int) min) + "m ";
    dates += fill2((int) sec) + "s ";

    return dates;
}
巷雨优美回忆 2024-09-21 11:19:19

在浏览完所有其他答案后,为了保留 Java 7 Date 类型,但使用 Java 8 diff 方法更加精确/标准,

public static long daysBetweenDates(Date d1, Date d2) {
    Instant instant1 = d1.toInstant();
    Instant instant2 = d2.toInstant();
    long diff = ChronoUnit.DAYS.between(instant1, instant2);
    return diff;
}

After wading through all the other answers, to keep the Java 7 Date type but be more precise/standard with the Java 8 diff approach,

public static long daysBetweenDates(Date d1, Date d2) {
    Instant instant1 = d1.toInstant();
    Instant instant2 = d2.toInstant();
    long diff = ChronoUnit.DAYS.between(instant1, instant2);
    return diff;
}
眼眸里的那抹悲凉 2024-09-21 11:19:19

注意:startDate 和 endDate 为 -> java.util.Date

import org.joda.time.Duration;
import org.joda.time.Interval;
// Use .getTime() unless it is a joda DateTime object
Interval interval = new Interval(startDate.getTime(), endDate.getTime());
Duration period = interval.toDuration();
//gives the number of days elapsed between start and end date.
period.getStandardDays();

与天类似,也可以获取小时、分钟和秒

period.getStandardHours();
period.getStandardMinutes();
period.getStandardSeconds();

Note: startDate and endDates are -> java.util.Date

import org.joda.time.Duration;
import org.joda.time.Interval;
// Use .getTime() unless it is a joda DateTime object
Interval interval = new Interval(startDate.getTime(), endDate.getTime());
Duration period = interval.toDuration();
//gives the number of days elapsed between start and end date.
period.getStandardDays();

Similar to days, you can also get hours, minutes and seconds

period.getStandardHours();
period.getStandardMinutes();
period.getStandardSeconds();
二智少女猫性小仙女 2024-09-21 11:19:19

检查此处的示例 http://www.roseindia.net/java/beginners/DateDifferent.shtml< /a>
这个例子给出了天、小时、分钟、秒和毫秒的差异:)。

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.");
    }
}

Check example here http://www.roseindia.net/java/beginners/DateDifferent.shtml
This example give you difference in days, hours, minutes, secs and milli sec's :).

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.");
    }
}
煮酒 2024-09-21 11:19:19

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

Use GMT time zone to get an instance of the Calendar, set the time using the set method of Calendar class. The GMT timezone has 0 offset (not really important) and daylight saving time flag set to 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));
柠檬 2024-09-21 11:19:19

以下代码可以为您提供所需的输出:

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

Following code can give you the desired output:

String 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());
韬韬不绝 2024-09-21 11:19:19
public static String getDifferenceBtwTime(Date dateTime) {

    long timeDifferenceMilliseconds = new Date().getTime() - dateTime.getTime();
    long diffSeconds = timeDifferenceMilliseconds / 1000;
    long diffMinutes = timeDifferenceMilliseconds / (60 * 1000);
    long diffHours = timeDifferenceMilliseconds / (60 * 60 * 1000);
    long diffDays = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24);
    long diffWeeks = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 7);
    long diffMonths = (long) (timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 30.41666666));
    long diffYears = (long)(timeDifferenceMilliseconds / (1000 * 60 * 60 * 24 * 365));

    if (diffSeconds < 1) {
        return "one sec ago";
    } else if (diffMinutes < 1) {
        return diffSeconds + " seconds ago";
    } else if (diffHours < 1) {
        return diffMinutes + " minutes ago";
    } else if (diffDays < 1) {
        return diffHours + " hours ago";
    } else if (diffWeeks < 1) {
        return diffDays + " days ago";
    } else if (diffMonths < 1) {
        return diffWeeks + " weeks ago";
    } else if (diffYears < 12) {
        return diffMonths + " months ago";
    } else {
        return diffYears + " years ago";
    }
}   
public static String getDifferenceBtwTime(Date dateTime) {

    long timeDifferenceMilliseconds = new Date().getTime() - dateTime.getTime();
    long diffSeconds = timeDifferenceMilliseconds / 1000;
    long diffMinutes = timeDifferenceMilliseconds / (60 * 1000);
    long diffHours = timeDifferenceMilliseconds / (60 * 60 * 1000);
    long diffDays = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24);
    long diffWeeks = timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 7);
    long diffMonths = (long) (timeDifferenceMilliseconds / (60 * 60 * 1000 * 24 * 30.41666666));
    long diffYears = (long)(timeDifferenceMilliseconds / (1000 * 60 * 60 * 24 * 365));

    if (diffSeconds < 1) {
        return "one sec ago";
    } else if (diffMinutes < 1) {
        return diffSeconds + " seconds ago";
    } else if (diffHours < 1) {
        return diffMinutes + " minutes ago";
    } else if (diffDays < 1) {
        return diffHours + " hours ago";
    } else if (diffWeeks < 1) {
        return diffDays + " days ago";
    } else if (diffMonths < 1) {
        return diffWeeks + " weeks ago";
    } else if (diffYears < 12) {
        return diffMonths + " months ago";
    } else {
        return diffYears + " years ago";
    }
}   
空城仅有旧梦在 2024-09-21 11:19:19

最好的做法是

(Date1-Date2)/86 400 000 

该数字是一天中的毫秒数。

一个日期与另一个日期之间的差异以毫秒为单位。

将答案收集到 double 变量中。

Best thing to do is

(Date1-Date2)/86 400 000 

That number is the number of milliseconds in a day.

One date-other date gives you difference in milliseconds.

Collect the answer in a double variable.

仅一夜美梦 2024-09-21 11:19:19

这是 O(1) 的正确 Java 7 解决方案,没有任何依赖项。

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

Here's a correct Java 7 solution in O(1) without any dependencies.

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;
}
泪痕残 2024-09-21 11:19:19

这可能是最直接的方法 - 也许是因为我已经用 Java 编码(其无可否认的笨重的日期和时间库)有一段时间了,但该代码对我来说看起来“简单而漂亮”!

您对以毫秒为单位返回的结果是否满意,或者您希望以某种替代格式返回结果?

That's probably the most straightforward way to do it - perhaps it's because I've been coding in Java (with its admittedly clunky date and time libraries) for a while now, but that code looks "simple and nice" to me!

Are you happy with the result being returned in milliseconds, or is part of your question that you would prefer to have it returned in some alternative format?

萌辣 2024-09-21 11:19:19

不使用标准 API,不。您可以自己做这样的事情:

class Duration {
    private final TimeUnit unit;
    private final long length;
    // ...
}

或者您可以使用 Joda

DateTime a = ..., b = ...;
Duration d = new Duration(a, b);

Not using the standard API, no. You can roll your own doing something like this:

class Duration {
    private final TimeUnit unit;
    private final long length;
    // ...
}

Or you can use Joda:

DateTime a = ..., b = ...;
Duration d = new Duration(a, b);
旧城烟雨 2024-09-21 11:19:19

只是回答最初的问题:

将以下代码放入像 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 在日期计算中应用的偏移量。

:)

Just to answer the initial question:

Put the following code in a Function like 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;

The most important here is to work with long numbers when multiplying and dividing. And of course, the offset that Java applies in its calculus of Dates.

:)

失与倦" 2024-09-21 11:19:19

由于问题是用 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

Since the question is tagged with 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
镜花水月 2024-09-21 11:19:19

如果您想修复跨夏令时边界的日期范围问题(例如,一个日期为夏季时间,另一个日期为冬季时间),您可以使用此方法获取天数差异

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

If you want to fix the issue for date ranges that cross daylight savings time boundary (e.g. one date in summer time and the other one in winter time), you can use this to get the difference in days:

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);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文