【问题标题】:How to check cutoff time before or after the current time instance?如何检查当前时间实例之前或之后的截止时间?
【发布时间】:2016-05-30 09:43:04
【问题描述】:

目前我正在处理运输条件。在这我会得到cut off time 反对公司像(05.00 PM)。 现在我想将以上时间与当前时间进行比较,无论是在cut off time 之前还是cut off time 之后? 我已经浏览了所有链接,我只能看到date 的示例。随着时间的流逝,我找不到任何东西。 请让我知道或提供一些线索,以便我进行整理。

这是我迄今为止尝试过的

String todayDate=LocalDate.now().toString("dd.MM.yyyy");

String s=todayDate+cutOffTime;//cutOffTime will get from DB
SimpleDateFormat simpleDateFormat=new SimpleDateFormat("dd.MM.yyyy HH:mm a");
LocalDate despatchDate=LocalDate.now();
try {
    Date cutoffDate=simpleDateFormat.parse(s);
    if (cutoffDate.after(Calendar.getInstance().getTime())){
        despatchDate.plusDays(1);
    }

} catch (ParseException e) {
    e.printStackTrace();
}

【问题讨论】:

  • 不要混合新旧日期时间类。新的在 java.time 包中,内置于 Java 8 及更高版本中。旧的在 java.time 包之外,应该避免使用(java.util.Date、java.util.Calendar、java.text.SimpleDateFormat)。旧类获得了一些新方法来促进新旧数据类型之间的转换。

标签: datetime java-8 datetime-format


【解决方案1】:

Java 8 日期/时间 API

LocalDateTime currentDateTime = LocalDateTime.now();
LocalDate currentDate = LocalDate.now();
String cutOff = "05:00 AM";
DateTimeFormatter timeParser = DateTimeFormatter.ofPattern("hh:mm a");
LocalTime cutOffTime = timeParser.parse(cutOff, LocalTime::from);
LocalDateTime cutOffDateTime = LocalDateTime.of(currentDate, cutOffTime);
//After
cutOffDateTime.isAfter(currentDateTime);
//Before
cutOffDateTime.isBefore(currentDateTime);
//Compare
cutOffDateTime.compareTo(currentDateTime);

【讨论】:

  • 感谢您的回复。为什么如果将AM 更改为PM,我会收到错误消息?
  • 如果您使用 12 小时格式,请将时间格式更改为“hh:mm a”。
【解决方案2】:

时区

Answer by Shiv V 正朝着正确的方向发展,但不是准确的。答案忽略了time zone 的关键问题。 Local… 类型故意丢失和忽略时区信息,这就是它们的目的。但我们很少希望丢失时区信息。

确定日期和时间取决于时区。对于任何给定的时刻,日期和时间在全球范围内可能会有所不同。巴黎午夜过后的几分钟是新的一天,而蒙特利尔仍是“昨天”。

Instant 类在UTC 中定义时间轴上的时刻,分辨率为nanoseconds

Instant now = Instant.now();

如果所需的截止日期是“明天下午 5 点”,则必须指定时区作为上下文。将ZoneId 应用于Instant 以获得ZonedDateTime

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );
ZonedDateTime zdtTomorrow = zdt.plusDays( 1 );

现在调整到下午 5 点。

LocalTime timeOfDayWhenDue = LocalTime.of( 5 , 0 );
ZonedDateTime zdtDeadline = zdtTomorrow.with( timeOfDayWhenDue );

您可以使用isEqualisBeforeisAfter 方法进行比较。

ZonedDateTime now = ZonedDateTime.now( zoneId );
boolean overdue = now.isAfter( zdtDeadline );

您还可以将分区日期时间转换回 UTC。 ZonedDateTime 对象和它们各自的 Instant 对象代表时间线上的同一时刻(历史上的同一时刻),但从不同时区的角度来看(America/MontrealUTC)。

Instant instantDeadline = zdtDeadline.toInstant();
Instant instantNow = now.toInstant();
boolean overdue = instantNow.isAfter( instantDeadline );

如果您想将截止日期告知印度客户,请调整到另一个时区。日期时间值将代表时间轴上的同一时刻,但将显示为对该客户有意义的 wall-clock time

ZoneId zoneId_Kolkata = ZoneId.of( "Asia/Kolkata" );
ZonedDateTime zdtDeadline_Kolkata = zdtDeadline.withZoneSameInstant( zoneId_Kolkata );

如果您不指定时区,JVM 的当前默认时区将被隐式、静默地应用。不好。一方面,隐含的假设使您的代码容易被误解,并使错误更难查明。更糟糕的是,默认值可以随时更改,当您部署到另一台计算机时,甚至在应用程序执行的任何时刻运行时!最好始终指定所需/预期的时区。顺便说一句,Locale 也是如此。

【讨论】:

  • 感谢您的详细解答。
猜你喜欢
  • 2020-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多