将日期分为几年,几个月,几天,几小时的单独部分。 Java的

时间:2012-09-26 23:46:09

标签: java date calendar gregorian-calendar

有没有办法通过计算两个日期之间的差异来计算一些天数,分成不同的部分,例如:为364天,它将是:0年,11个月,30天,小时,分钟等。 我认为使用逻辑运算符可能会像%和/那样工作,但由于不同的月份有不同的天数,而有些年份是闰年,我不知道该怎么做。任何帮助将非常感激。我的代码:

import java.util.*;

public class CleanDate {

    public static void main(String[] args) {
        Calendar cDate = GregorianCalendar.getInstance();
        cDate.set(2011, 0, 31, 00, 00, 00);
        Date date1 = cDate.getTime();
        Date date2 = new Date();
        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("Time in minutes: " + diffMinutes + " minutes.");
        System.out.println("Time in hours: " + diffHours + " hours.");
        System.out.println("Time in days: " + diffDays + " days.");
    }
}

2 个答案:

答案 0 :(得分:3)

你可以像这样有效地使用Joda Time: Interval允许获得两个日期之间的时间间隔。

DateTime end = new DateTime(2006, 1, 1, 0, 0, 0, 0);
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");

答案 1 :(得分:0)

tl; dr

Duration.between(          // Represent a span-of-time unattached to the timeline, on scale of days-hours-minutes-seconds.
    ZonedDateTime          // Represent a moment in the wall-clock time used by the people of a particular region (a time zone). 
    .of( 2011 , 1 , 31 , 0 , 0 , 0 , 0 , ZoneId.of( "Africa/Tunis" ) )
    ,
    ZonedDateTime.of( … ) 
)                          // Returns a `Duration` object.
.toDaysPart()              // Or `toHoursPart`, `toMinutesPart`, `toSecondsPart`, `toNanosPart`. These return either a `long` or an `int`. 

java.time

现代方法使用 java.time 类,而不是可怕的旧DateCalendar类。在other Answer中看到的 Joda-Time 库也被 java.time 所取代。

指定日期和时间需要一个时区来确定确切的时刻。对于任何给定时刻,日期和时间在全球范围内都会发生变化。

continent/region的格式指定proper time zone name,例如America/MontrealAfrica/CasablancaPacific/Auckland。切勿使用3-4个字母的缩写,例如ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的(!)。

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;

如果您想要一天的第一时刻,请让 java.time 确定该日期在该区域中的时间。一天并非总是在00:00:00开始。

LocalDate ld = LocalDate.of( 2011 , Month.JANUARY , 31 ) ;
ZonedDateTime start = ld.atStartOfDay( z ) ;  // Let java.time determine the first moment of the day. Never assume 00:00:00.

使用Duration类计算经过的天数(实际上是24小时的时间),小时,分钟和秒。对于年月日(日历日,而不是24小时的时间段),请使用Period类。

ZonedDateTime stop = … ;
Duration d = Duration.between( start , stop ) ;

使用标准ISO 8601格式的文本生成String对象。

String output = d.toString() ;  // Generate standard ISO 8601 text.
  

PT2H3M42.725S

提取各种碎片。

long days = d.toDaysPart() ;       // 24-hour chunks of time, *not* calendar days.
int hours = d.toHoursPart() ;
int minutes = d.toMinutesPart() ;
int seconds = d.toSecondsPart() ;
int nanos = d.toNanosPart() ;      // Fractional second as a count of nanoseconds, from 0 to 999,999,999.

年-月-日-天-小时-分钟-秒

如果考虑到这一点,尝试用年-月-天-小时-分钟-秒-来表示时间跨度几乎没有任何意义。其中涉及棘手的问题,例如日历天与24小时的时间段,以及天长短不一的事实,例如23、24、25或其他小时数。

但是,如果您真的坚持这种方法,请将ThreeTen-Extra库添加到项目中以访问PeriodDuration类。此类尝试将两个概念结合起来。

  

ISO-8601日历系统中的时间量,其中包含时间段和持续时间。

     

此类根据时间段和持续时间来建模时间量或时间量。期间是基于日期的时间量,包括年,月和日。持续时间是基于时间的时间量,由秒和纳秒组成。有关更多详细信息,请参见“期间”和“持续时间”类。

     

时段中的日期考虑了夏令时更改(23或25小时制)。执行计算时,首先添加期间,然后添加持续时间。


关于 java.time

java.time框架已内置在Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendarSimpleDateFormat

目前位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解更多信息,请参见Oracle Tutorial。并在Stack Overflow中搜索许多示例和说明。规格为JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

在哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展了java.time。该项目为将来可能在java.time中添加内容提供了一个试验场。您可能会在这里找到一些有用的类,例如IntervalYearWeekYearQuartermore