【问题标题】:calendar start date before end date on same day difference日历开始日期早于结束日期在同一天的差异
【发布时间】:2018-09-18 02:35:27
【问题描述】:

我有两个日历日期,我得到了天、小时和分钟之间的差异。

如果结束日期大于开始日期,这将非常有效。 如果开始日期与结束日期在一周中的同一天,但比结束日期更早,则不起作用。 例如:结束日期为星期六下午 2:20,开始日期为星期六下午 7:20。 它以 0 天和 5 小时计算。但是,应该更像是 7 天。

这里是代码

    long t1 = curCal.getTimeInMillis();
    long t2 = setCal.getTimeInMillis();

    if(t2 < t1){
         days = t1-t2;
    }else{
         days = t2-t1;
    }

    long toDays = TimeUnit.MILLISECONDS.toDays(days);
    long toHours = TimeUnit.MILLISECONDS.toHours(days) % 24;
    long toMinutes = TimeUnit.MILLISECONDS.toMinutes(days) % 60;
    String toastMessage =   String.format(" %d Days %d Hours %d Minutes", toDays, toHours, toMinutes);
    Toast.makeText(context, "ALARM in"  + " " + toastMessage , Toast.LENGTH_LONG).show();

我该如何处理结束日期与开始日期相同的情况,但结束日期是开始日期之前的时间?

谢谢

编辑

我想我解决了我的问题。我正在为其他有同样问题的人添加它。如果结束日期 = 开始日期(同一天)将 7 添加到日历对象以作为结束日期。伪代码

if (enddate == startdate)) {
   enddate.add(Calendar.DAY_OF_YEAR, 7);
}

【问题讨论】:

  • 仅供参考,java.util.Datejava.util.Calendarjava.text.SimpleDateFormat 等麻烦的旧日期时间类现在已被 java.time 类所取代。在ThreeTen-Backport 项目中,大部分java.time 功能都被反向移植到Java 6 和Java 7。在ThreeTenABP 项目中进一步适用于早期的Android。见How to use ThreeTenABP…

标签: java android time date-difference java.util.calendar


【解决方案1】:

以另一种方式阅读您的问题,如果t1 是开始日期,t2 是结束日期,您的逻辑不包括t1 &lt; t2t2 - t1

long t1 = curCal.getTimeInMillis();
long t2 = setCal.getTimeInMillis();

if(t2 < t1){
     days = t1-t2;
}else{
     days = t2-t1;
     if (days < 1) {
         days += 7;
     }
}

所有这些都可以简化为

days = Math.abs(t1 - t2);
if (days < 1 && t1 < t2) {
    days += 7;
}

【讨论】:

  • 这仍然是零。他们的关键是将 7 添加到日历对象中。
  • 你的想法是对的。尽管有变量名,OP 的 days 以毫秒为单位。增加 7 毫秒不足以解决问题。 ;-)
【解决方案2】:
    ZoneId zone = ZoneId.of("Europe/Busingen");

    DayOfWeek alarmDay = DayOfWeek.SUNDAY;
    LocalTime alarmTime = LocalTime.of(14, 20);
    ZonedDateTime now = ZonedDateTime.now(zone);

    ZonedDateTime alarmDateTime = now.with(alarmDay).with(alarmTime);
    if (alarmDateTime.isBefore(now)) {
        alarmDateTime = alarmDateTime.plusWeeks(1);
    }
    Duration difference = Duration.between(now, alarmDateTime);
    String toastMessage = String.format(" %d Days %d Hours %d Minutes",
            difference.toDaysPart(), difference.toHoursPart(), difference.toMinutesPart());
    System.out.println(toastMessage);

刚刚跑步(比辛根周日 22:03:17)我得到了:

6 天 16 小时 16 分钟

我相信我正在贡献的答案不仅是现代的,而且是更强大的。

  • 现代Calendar 类早已过时,按照今天的标准设计得很糟糕。相反,我使用并推荐 java.time,现代 Java 日期和时间 API。
  • 稳健:据我所知,您的代码不仅在今天和闹钟日期是一周中的同一天时存在问题,而且如果闹钟在一周中的较早日期出现问题。我考虑到了这一点。
  • 此外准确:如果您在夏令时 (DST) 之间进行交叉转换,则在计算中使用毫秒值时可能会得到错误的小时数。使用两个ZonedDateTime 对象可以最大限度地减少意外。它确实需要您填写我放置欧洲/布辛根的所需时区,因为夏季时间转换是特定于时区的。
  • 此外更精确地建模:使用Calendar,一个日期和时间,每周重复警报似乎有点有趣。您需要的是一周中的某一天和一天中的某个时间,所以我使用它。 java.time 提供所需的类,DayOfWeek 枚举和 LocalTime 类。

事实上,我是如此现代,以至于我正在使用 Java 9 中引入的 Duration 类的 toXxxPart 方法。对于格式化 Duration,如果您尚未使用 Java 9,则需要减去首先从持续时间获取小时数:使用minusDays 方法。然后对minusHours 进行类似操作以获取会议记录。

    long toDays = difference.toDays();
    difference = difference.minusDays(toDays);
    long toHours = difference.toHours();
    difference = difference.minusHours(toHours);
    long toMinutes = difference.toMinutes();

问题:我可以在 Android 上使用 java.time 吗?

是的,java.time 在较旧和较新的 Android 设备上都能很好地工作。它只需要至少 Java 6

  • 在 Java 8 及更高版本以及更新的 Android 设备上(据我所知,从 API 级别 26 开始)现代 API 是内置的。
  • 在 Java 6 和 7 中,获取 ThreeTen Backport,即新类的后向端口(对于 JSR 310,ThreeTen;请参阅底部的链接)。
  • 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从 org.threeten.bp 导入日期和时间类以及子包。

链接

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-05
    相关资源
    最近更新 更多