【问题标题】:Java: How to deal with cutoff timing for a system?Java:如何处理系统的截止时间?
【发布时间】:2020-09-17 12:25:41
【问题描述】:

我有一个场景,系统每天从 18:00 到第二天 07:00 在所有工作日(简而言之,“周一 - 周五,18:00 到 07: 00”)。这意味着,每个工作日系统在 18:00 关闭,并在第二天早上 07:00 起床。在此时间范围之外,系统已关闭,例如从周五 18:00 到周一 07:00。我需要存储这个时间并在我的 java 应用程序中与 当前时间 进行匹配,以查看上述系统是否启动。

您能否建议我应该如何继续存储系统停机时间(可能在一个变量中)并与我的应用程序中的当前时间相匹配,以确定系统是否在当前时间停机?我需要使用 Java 来做到这一点。

我尝试了多个 Java 文档的日期和时间,但在这种情况下无法获得任何有用的信息。

【问题讨论】:

  • 看起来像是为使用java.time 制作的场景...到目前为止您尝试过什么?至少能给我们展示一些代码或想法吗?
  • 您可能对这个涵盖 java.date/java.time API 的答案感兴趣:stackoverflow.com/a/35300229/2519307
  • 我有一个主要的阻止程序来存储系统停机时间的范围。如果我给出一个停止和开始日期时间,我可以找出当前时间是否在那个范围内。
  • 周一至周五,18:00 至 07:00?请注意,一周的最后七个停机时间实际上是在星期六。
  • @MCEmperor:没错。感谢您提前考虑并让我避免意外包含此内容。

标签: java date datetime java-8


【解决方案1】:

你可以这样做:

import java.time.DayOfWeek;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.util.List;

public class Main {
    public static void main(String[] args) {
        // Tests
        showServerStatus(List.of(DayOfWeek.SATURDAY, DayOfWeek.SUNDAY), LocalTime.of(7, 0), LocalTime.of(18, 0));
        showServerStatus(List.of(DayOfWeek.THURSDAY, DayOfWeek.SATURDAY), LocalTime.of(6, 0), LocalTime.of(20, 0));
    }

    static void showServerStatus(List<DayOfWeek> offDays, LocalTime startTime, LocalTime endTime) {
        LocalDateTime now = LocalDateTime.now();
        if (!offDays.contains(now.getDayOfWeek()) && !now.toLocalTime().isBefore(startTime)
                && !now.toLocalTime().isAfter(endTime)) {
            System.out.println("The server should be up now.");
        } else {
            System.out.println("The server should be down now.");
        }
    }
}

现在给我输出:

The server should be up now.
The server should be down now.

Trail: Date Time 了解有关现代日期时间 API 的更多信息。

【讨论】:

  • 感谢您的努力和编写这段代码。这很有帮助。但是让我们说,往前走,我得到了多个这样的系统,它们都有自己的截止时间,我不应该为所有这些添加条件。我正在寻找一个通用的解决方案,可以说“系统 A 在周一至周六 20:00 到 06:00 关闭,我是否能够继续并向其发送请求”。我想知道如何以通用方式让我的 java 程序知道这个范围。
  • @Sonu - 我已经更新了答案以使其通用。
【解决方案2】:

我编写了一个类,它能够表示系统的截止时间(正常运行时间或停机时间)。

问题中用例的难点在于结束时间在开始时间之前。这意味着停机时间从一周中的某一天开始,并在某个时间结束第二天

所以周一到周五,从 18:00 到 07:00,意味着系统也在周六,午夜到 7:00 关闭。如果我们想正确处理这个问题,我们需要考虑到这一点。

类的源代码下方。构造函数接受Set,其中包含截止时间开始的星期几,以及开始和结束时间。

public class Uptime {

    private final Set<DayOfWeek> daysOfUptimeStart;

    private final LocalTime startTime;

    private final LocalTime endTime;

    public Uptime(Set<DayOfWeek> daysOfUptimeStart, LocalTime startTime, LocalTime endTime) {
        this.daysOfUptimeStart = Collections.unmodifiableSet(daysOfUptimeStart);
        this.startTime = startTime;
        this.endTime = endTime;
    }

    public boolean isUp(LocalDateTime dateTime) {
        LocalTime time = dateTime.toLocalTime();
        if (!this.startTime.isAfter(this.endTime)) {
            return this.daysOfUptimeStart.contains(dateTime.getDayOfWeek()) && !time.isBefore(this.startTime) && !time.isAfter(this.endTime);
        }
        else {
            if (time.isBefore(this.startTime) && time.isAfter(this.endTime)) {
                return false;
            }
            else {
                return this.daysOfUptimeStart.contains(dateTime.getDayOfWeek().minus(!time.isBefore(this.startTime) ? 0 : 1));
            }
        }
    }
}

测试

为了对此进行测试,我生成了一些日期:2020 年 9 月 14 日至 20 日(周一至周日)的所有日期,加上凌晨 4 点、上午 8 点、下午 1 点、下午 5 点、晚上 7 点和晚上 11 点。

代码打印日期时间,以及系统是否启动。我们期望:

  • 周一晚上 7 点和 11 点系统停机;
  • 周二至周五,系统在凌晨 4 点、晚上 7 点和晚上 11 点关闭;
  • 周六凌晨 4 点系统停机。
// Static importing java.time.DayOfWeek.* here
Uptime uptime = new Uptime(Set.of(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY), LocalTime.of(18, 0), LocalTime.of(7, 0));

YearMonth ym = YearMonth.of(2020, Month.SEPTEMBER);
List<LocalDateTime> datetimes = IntStream.rangeClosed(14, 20) // September 2020, MONDAY till SUNDAY
    .mapToObj(ym::atDay)
    .flatMap(date -> IntStream.of(4, 8, 13, 17, 19, 23)
        .mapToObj(hour -> LocalTime.of(hour, 0))
        .map(date::atTime))
    .collect(Collectors.toList());

datetimes.forEach(datetime -> System.out.printf("%s %-12s %s\n", datetime, "(" + datetime.getDayOfWeek() + "):", !uptime.isUp(datetime)));

输出符合预期。


更新

对原始帖子的修订略微改变了要求。然而, 您不必修改上述代码,因为如果您修改您的输入,它仍然可以工作。事实上,您记录的是正常运行时间,而不是停机时间。因此,请注册您的正常运行时间:周一至周五,7:00 至 18:00。

Set<DayOfWeek> daysOfWeek = Set.of(MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY);
LocalTime start = LocalTime.of(7, 0);
LocalTime end = LocalTime.of(18, 0);
Uptime uptime = new Uptime(daysOfWeek, start, end);

现在使用uptime.isUp(LocalDateTime.now()),您仍然可以检查系统是否已启动。

【讨论】:

  • 感谢您为写下这段代码付出了这么多努力。这很有帮助。我很感激。这对于工作日的情况非常有效,但是在周末,当系统关闭时,它显示系统已启动......我将修改代码并根据我的需要让它工作。再次感谢。
  • @Sonu 那是因为在您的问题(修订版 1)中,您描述的停机时间仅发生在星期一到星期五——这意味着在星期六和星期日,系统不会停机。但是,无需更改代码,只需修改您的输入即可。我已经更新了答案。
  • 感谢@MC Emperor。是的,这就是为什么编辑问题以明确提及它的原因。但是非常感谢,您的代码很棒。它让我在处理此类场景时有了很多理解。再次感谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-21
  • 1970-01-01
  • 2017-09-05
  • 1970-01-01
  • 2011-09-06
相关资源
最近更新 更多