猿问

我如何转换两个 Calendar 对象之间的确切时间量(年、月、日、小时、分钟、秒)?

我试图隐藏 Java 中两个 Calendar 对象之间的确切时间量。


这是我目前拥有的代码......


public static Map<TimeUnit, Long> computeDifference(Calendar date1, Calendar date2) { 


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


    //create the list

    List<TimeUnit> units = new ArrayList<TimeUnit>();

    units.add(TimeUnit.SECONDS);

    units.add(TimeUnit.MINUTES);

    units.add(TimeUnit.HOURS);

    units.add(TimeUnit.DAYS);

    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;

}   

打印时,输出看起来像这样{DAYS=1, HOURS=10, MINUTES=30, SECONDS=45}输入date1 = 19 August 2019 02:00:00和date2 = 20 August 2019 12:30:45


此方法中可用的最大时间单位是DAYS,但我想找到同时包含月份和年份的内容。我意识到 TimeUnit 与特定的日历日期(而不是 24 小时间隔)没有任何关系,这就是为什么我想知道是否有任何方法可以使用 Calendar 类或类似的东西进行这种转换。我还研究了 ChronoUnit 作为 TimeUnit 的替代品,但由于 TimeUnit 不起作用的相同原因,它不起作用。


会喜欢关于如何合并更大的时间单位的任何建议。谢谢你!


蛊毒传说
浏览 155回答 2
2回答

慕神8447489

你不应该使用这个Calendar类,因为它已经过时了。您应该改用java.time包中的类。为了获得所需的结果,您可以使用该类Period。您首先需要将两个Calendar实例都转换为LocalDateinstances。然后您可以使用Period.between(startDate, endDate)to 获取一个Period实例,这使得getDays()和getMonths()方法getYears()对您可用。如果您还想包括时间组件(小时、分钟和秒),那么您可以Duration结合使用Period. 这样的事情可能会起作用:LocalDateTime start = LocalDateTime.of(2019, 1, 1, 12, 0, 0);LocalDateTime end = LocalDateTime.of(2021, 4, 26, 5, 56, 40);Duration d = Duration.between(start.toLocalTime(), end.toLocalTime());Period p = Period.between(start.toLocalDate(), end.toLocalDate());// If the startdate's time component lies behind the enddate's time component,// then we need to correct both the Period and Durationif (d.isNegative()) {    p = p.minusDays(1);    d = d.plusDays(1);}System.out.printf("y %s m %s d %s h %s m %s s %s%n",    p.getYears(),    p.getMonths(),    p.getDays(),    d.toHours() % 24,    d.toMinutes() % 60,    d.getSeconds() % 60);请注意,Java 9 附带to…Part方法,因此您不必再使用模运算符。请注意:由于夏令时,此代码未考虑时钟调整。

守候你守候我

Period.between(    ( ( GregorianCalendar ) myCalStart ).toZonedDateTime().toLocalDate() ,    ( ( GregorianCalendar ) myCalStop ).toZonedDateTime().toLocalDate() )…或者…Duration.between(    ( ( GregorianCalendar ) myCalStart ).toInstant() ,    ( ( GregorianCalendar ) myCalStop ).toInstant() )java.time您正在使用多年前被 JSR 310 中定义的现代java.time类所取代的可怕的日期时间类。切勿使用Calendar, GregorianCalendar, Date,SimpleDateFormat等。仅使用在java.time包中找到的类。ZonedDateTime假设您的两个Calendar对象实际上都是GregorianCalendar下面的对象,请转换。要进行转换,请调用添加到旧类的新to…/方法。from…// startGregorianCalendar gcStart = ( GregorianCalendar ) myCalStart ;ZonedDateTime zdtStart = gcStart.toZonedDateTime() ;// stopGregorianCalendar gcStop = ( GregorianCalendar ) myCalStop ;ZonedDateTime zdtStop = gcStop.toZonedDateTime() ;和 都GregorianCalendar代表ZonedDateTime一个日期和一个时区上下文中的时间,结合起来确定一个时刻(时间轴上的特定点)。ZonedDateTime解析到更精细的纳秒级而不是毫秒级。Period如果您关心以年-月-日为单位的经过时间,请使用Period对象LocalDate。LocalDate表示没有时间和时区的日期。我们可以从我们的对象中提取日期部分ZonedDateTime。LocalDate ldStart = zdtStart.toLocalDate() ;LocalDate ldStop = zdtStop.toLocalDate() ;Period p = Period.between( ldStart , ldStop ) ;生成标准ISO 8601格式的字符串。String output = p.toString() ;询问数年、数月、数日。int years = p.getYears() ;int months = p.getMonths() ;int days = p.getDays() ;Duration如果您以小时-分钟-秒的形式计算经过的时间,请使用Duration. 此类代表 UTC 中的一对时刻。因此,我们Instant从我们的ZonedDateTime对象对中提取对象,这些对象在内部保留自 UTC 1970 年第一时刻的纪元参考以来的整秒计数,加上小数秒作为纳秒计数。Instant instantStart = zdtStart.toInstant() ;Instant instantStop = zdtStop.toInstant() ;Duration d = Duration.between( instantStart , instantStop ) ;生成标准ISO 8601格式的字符串。String output = d.toString() ;查询天数(与日历无关的 24 小时时间块)、小时、分钟、秒。long days = d.toDaysPart() ;int hours = d.toHoursPart() ;int minutes = d.toMinutesPart() ;int seconds = d.toSecondsPart() ;int nanos = d.toNanosPart() ;PeriodDuration如果您考虑一下,您会发现将年/月/日与 24 小时-日/小时/分钟/秒结合起来是没有意义的。
随时随地看视频慕课网APP

相关分类

Java
我要回答