【问题标题】:Get next Date that meets conditions in Java获取满足Java条件的下一个日期
【发布时间】:2021-05-25 20:56:48
【问题描述】:

我知道这应该很简单,但我在互联网上找不到任何东西。

鉴于某些条件,我想在满足它们时获得下一个Date。例如,如果条件是minute = 01second = 30,而现在时间是15:58:00,则函数应该在今天返回16:01:30。我如何在 Java 中实现这一点?

我需要能够设置至少秒、分钟和小时的条件,但我希望能够将一个条件设置为任何值(如上面的示例,它没有指定小时)。

感谢和抱歉我的英语不好。

编辑: 我看到有些事情可能需要澄清:我想得到一个日期(或其他)总是满足条件的当前时间之后。另外,这是一个 Minecraft Spigot 服务器,也许这些信息可以提供帮助。

【问题讨论】:

  • 如果 Date 你的意思是 java.util.Date,我建议你不要上课。它设计得很糟糕,而且已经过时了。而是使用ZonedDateTimejava.time, the modern Java date and time API 中的另一个适当的类。
  • 你真的用Java实现了cron的功能吗?已经有图书馆这样做了,所以你不需要重新发明轮子。
  • @OleV.V.我已经听说过 cron4j 库,这是我打算做的事情之一。但这仍然没有解决我想到的另一个项目:我想根据电子游戏的时间表制作一个火车“出发板”。该函数应返回火车出发的确切时间,即使时刻表仅显示“*:10:00”(在任何 10 点)。无论如何感谢您的建议。
  • @ArvindKumarAvinash 确切地说,我想得到第一次满足条件的时间当前时间之后。
  • 如果您将此检查 if (updated.isBefore(today)) { updated = updated.plusHours(1); } 放在我的第二个解决方案中,您将得到 2021-02-23T16:01:30。如果您认为它让您更近了一步,您应该进一步探索丰富的 java.time API。在我的回答中,我已经提供了 Oracle 精彩教程的链接。如果您需要任何进一步的说明,请随时发表评论。

标签: java time


【解决方案1】:

您可以为此使用流:

Optional<LocalDateTime> firstMatch = 
                         Stream.iterate(
                                  LocalDateTime.now(),
                                  ldt -> ldt.plusSeconds(1L))
                               .filter(
                                  // Insert your condition here
                                  ldt -> ldt.getSecond() == 0) 
                               .findFirst();

这段代码的作用是获取当前的LocalDateTime 并使用它来生成LocalDateTime 对象流(每次将时间提前1 秒)。一旦遇到与提供的条件匹配的LocalDateTime,它就会返回此对象并终止流。

请记住,如果条件变为真需要一段时间,使用这种方法会生成大量对象,因此效率不高。

如果您想去除纳秒,请将LocalDateTime.now() 替换为LocalDateTime.now().withNano(0)

【讨论】:

  • 感谢您的回答。我对语言的有限了解使我很难理解您的代码。这是否类似于有一个while 循环来检查条件并在不满足时增加一秒?使用你的方法有什么好处?
  • 恕我直言,它比while循环更漂亮,但这只是个人意见。稍微解释一下代码:Jeroen 创建了一个无穷无尽的对象流。他现在从一个日期对象开始,然后创建一个新对象,该对象是未来 1 秒。流负责其余的工作,因此从现在开始,您每秒都会获得 LocalDateTime 对象。在过滤器中,您定义了过滤流的条件,但是您获得了满足此条件的每个时间戳,因此您必须使用 findfirst。然后你得到第一个满足你条件的对象。如前所述,您会生成很多对象...
【解决方案2】:

您可以使用LocalDateTime#plus...添加持续时间以获取更新时间。

演示:

import java.time.LocalDateTime;
import java.time.LocalTime;

public class Main {
    public static void main(String[] args) {
        String strTime = "15:58:00";

        LocalTime time = LocalTime.parse(strTime);

        // Today at the specified time
        LocalDateTime today = LocalDateTime.now().with(time);
        System.out.println(today);

        // Today with the added minutes and seconds
        LocalDateTime updated = today.plusMinutes(1).plusSeconds(30);
        System.out.println(updated);
    }
}

输出:

2021-02-23T15:58
2021-02-23T15:59:30

如果你想切换到不同的时间,可以使用LocalDateTime#with...

import java.time.LocalDateTime;
import java.time.LocalTime;

public class Main {
    public static void main(String[] args) {
        String strTime = "15:58:00";

        LocalTime time = LocalTime.parse(strTime);

        // Today at the specified time
        LocalDateTime today = LocalDateTime.now().with(time);
        System.out.println(today);

        // Today with the updated minute and second
        LocalDateTime updated = today.withMinute(1).withSecond(30);
        System.out.println(updated);
    }
}

输出:

2021-02-23T15:58
2021-02-23T15:01:30

Learn more about the modern date-time API from **[Trail: Date Time](https://docs.oracle.com/javase/tutorial/datetime/index.html)**.

注意:java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,转用modern date-time API

【讨论】:

  • 作者不想加1分30秒,她喜欢用1分30秒跳到下一个时间戳;)
  • @Norbert - 问题不是很清楚。我已经为 OP 提供了两种解决方案。我会等待他/她的回复,然后根据需要更新答案。
  • @Norbert 确切地说,这不是我想做的。我想得到一个始终当前时间之后满足时间表中定义的条件的时间。检查我对这个问题的评论,以准确了解我想如何应用它。无论如何感谢您的回答。
【解决方案3】:

如果我猜对了,这应该可以解决你的问题

public String nextMeet(int minutes, int seconds) {
    LocalDateTime currentDate = LocalDateTime.now();
    if ((currentDate.getMinute()*60) + currentDate.getSecond() > (minutes*60) + seconds) {
        return (currentDate.getHour() + 1) + ":" + minutes + ":" + seconds;
    } else {
        return currentDate.getHour() + ":" + minutes + ":" + seconds;
    }
}

【讨论】:

  • 我想得到一个总是当前时间之后的时间。我已更新问题以包含此说明。
【解决方案4】:

我自己找到了另一个解决方案。 This library 可以解析一个 cron 表达式并在下次运行时返回,这解决了我的大部分问题。 (取自this question

感谢@OleV.V。为了这个想法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-04-30
    • 2023-02-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-09-06
    相关资源
    最近更新 更多