Java:如何处理系统的截止时间?

huangapple go评论79阅读模式
英文:

Java: How to deal with cutoff timing for a system?

问题

我有一个场景,一个系统在每个工作日的18:00到第二天07:00保持关闭(简言之,即 "周一至周五,18:00至07:00")。这意味着每个工作日的系统在18:00关闭,并在第二天早上07:00启动。在这个时间范围之外,系统是关闭的,例如从周五18:00到周一07:00。我需要存储这个时间并在我的Java应用程序中与当前时间进行匹配,以确定上述系统当前是否处于开启状态。

你能否建议我如何存储系统的关闭时间(可能是在一个变量中),并在我的应用程序中与当前时间匹配,以确定系统当前是否关闭?我需要使用Java来完成这个任务。

我尝试了多个关于日期和时间的Java文档,但在这种情况下找不到有用的信息。

英文:

I have a scenario where a system remains down each day from 18:00 to next day 07:00 for all working days (in short, "Mon - Fri, 18:00 to 07:00"). That means, each week day system is going down at 18:00 and getting up at 07:00 next day morning. Outside this time range, system is down e.g. from Friday 18:00 till Monday 07:00. I need to store this time and match in my java application against current time to see if the above system is up or not.

Can you please suggest how should I proceed storing the system down timing (may be in a variable) and match against current time in my application to find out if system is down at current time or not? I need to do this using Java.

I tried multiple Java documentation for date and time, but couldn't get anything useful in this situation.

答案1

得分: 3

您可以这样做

    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) {
            // 测试
            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("服务器现在应该是开启的。");
            } else {
                System.out.println("服务器现在应该是关闭的。");
            }
        }
    }

**对我现在的输出**

    服务器现在应该是开启的
    服务器现在应该是关闭的

**[教程日期时间](https://docs.oracle.com/javase/tutorial/datetime/index.html)** 了解更多现代日期时间 API 的信息。
英文:

You can do something like:

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&lt;DayOfWeek&gt; offDays, LocalTime startTime, LocalTime endTime) {
		LocalDateTime now = LocalDateTime.now();
		if (!offDays.contains(now.getDayOfWeek()) &amp;&amp; !now.toLocalTime().isBefore(startTime)
				&amp;&amp; !now.toLocalTime().isAfter(endTime)) {
			System.out.println(&quot;The server should be up now.&quot;);
		} else {
			System.out.println(&quot;The server should be down now.&quot;);
		}
	}
}

Output for me now:

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

Learn more about the modern date-time API from Trail: Date Time.

答案2

得分: 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点处于停机状态。
// 静态导入java.time.DayOfWeek.* 在这里
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()) 仍然可以检查系统是否正常运行。

英文:

I have written a class which is able to represent cutoff timings for systems (uptimes or downtimes).

The difficulty of the use case within the question is that the end time lies before the start time. That implies that the downtime starts at some day of the week, and ends the next day at a certain time.

So Monday until Friday, from 18:00 until 07:00, implies that the system is also down on Saturday, midnight until 7:00. If we want to handle this correctly, we need to take that into account.

Below the source code of the class. The constructor accepts a Set with the days of the week at which the cutoff times start, and the start and end times.

public class Uptime {

    private final Set&lt;DayOfWeek&gt; daysOfUptimeStart;

    private final LocalTime startTime;

    private final LocalTime endTime;

    public Uptime(Set&lt;DayOfWeek&gt; 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()) &amp;&amp; !time.isBefore(this.startTime) &amp;&amp; !time.isAfter(this.endTime);
        }
        else {
            if (time.isBefore(this.startTime) &amp;&amp; time.isAfter(this.endTime)) {
                return false;
            }
            else {
                return this.daysOfUptimeStart.contains(dateTime.getDayOfWeek().minus(!time.isBefore(this.startTime) ? 0 : 1));
            }
        }
    }
}

Test

In order to test this, I have generated some dates: all dates from 14 to 20 September 2020 (Monday to Sunday), combined with 4 AM, 8 AM, 1 PM, 5 PM, 7 PM and 11 PM.

The code prints the datetimes, along with whether the system is up or not. We expect that:

  • on Monday, the system is down at 7 PM and 11 PM;
  • on Tuesday until Friday, the system is down at 4 AM, 7 PM and 11 PM;
  • on Saturday, the system is down at 4 AM.
// 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&lt;LocalDateTime&gt; datetimes = IntStream.rangeClosed(14, 20) // September 2020, MONDAY till SUNDAY
    .mapToObj(ym::atDay)
    .flatMap(date -&gt; IntStream.of(4, 8, 13, 17, 19, 23)
        .mapToObj(hour -&gt; LocalTime.of(hour, 0))
        .map(date::atTime))
    .collect(Collectors.toList());

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

The output matches the expectation.


Update

A revision to the original post slightly changed the requirement. However,
you don't have to modify abovementioned code, as it'll still work if you modify your input. In fact, you are recording up-times instead of down-times. So instead, register your up-time times: Monday to Friday, 7:00 to 18:00.

Set&lt;DayOfWeek&gt; 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);

Now with uptime.isUp(LocalDateTime.now()) you can still check whether the system is up.

huangapple
  • 本文由 发表于 2020年9月17日 20:25:41
  • 转载请务必保留本文链接:https://go.coder-hub.com/63938001.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定