关于datetime:Java:检查当前日期是否在特定日期的范围内

Java: Check if current date is in range of specific days

本问题已经有最佳答案,请猛点这里访问。

我正在努力解决以下问题:

在我的应用程序中,我想检查来自LocalDateTime.now()的当前日期时间在一周中的某些特定日期范围内,比如说在星期五到星期日之间。

例子:

日期时间窗口是从星期五20:00到星期日20:00。当我在星期四22:00*检查当前日期时,答案应该是false,但当我在星期六8:00*检查时,答案应该是true

我可以通过java.timeAPI中的DayOfWeek类,使用compareTo()方法,分别比较小时和分钟来实现这一点,但我想知道是否有更好的方法,特别是当两周的时间跨度超过两周时(例如,下周的星期五到星期一)?

提前感谢您提供任何建议或帮助。


由于您想将LocalDateTimeDayOfWeekLocalTime进行比较,或者更确切地说,检查它是否在两个DayOfWeekLocalTime对之间,辅助类可能很好:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
public final class DayOfWeekTimeRange {
    private final DayOfWeek fromDay;
    private final LocalTime fromTime;
    private final DayOfWeek toDay;
    private final LocalTime toTime;
    private final boolean   inverted;
    public DayOfWeekTimeRange(DayOfWeek fromDay, LocalTime fromTime, DayOfWeek toDay, LocalTime toTime) {
        this.fromDay = fromDay;
        this.fromTime = fromTime;
        this.toDay = toDay;
        this.toTime = toTime;
        this.inverted = compare(this.fromDay, this.fromTime, this.toDay, this.toTime) > 0;
    }
    public boolean inRange(LocalDateTime dateTime) {
        return inRange(dateTime.getDayOfWeek(), dateTime.toLocalTime());
    }
    public boolean inRange(DayOfWeek day, LocalTime time) {
        boolean fromOk = compare(day, time, this.fromDay, this.fromTime) >= 0; // Lower-inclusive
        boolean toOk   = compare(day, time, this.toDay  , this.toTime  ) <  0; // Upper-exclusive
        return (this.inverted ? fromOk || toOk : fromOk && toOk);
    }
    private static int compare(DayOfWeek day1, LocalTime time1, DayOfWeek day2, LocalTime time2) {
        int cmp = day1.compareTo(day2);
        if (cmp == 0)
            cmp = time1.compareTo(time2);
        return cmp;
    }
}

试验

1
2
3
4
5
6
7
8
9
10
11
// Fri 10:00 PM  to  Sun 10:00 PM
DayOfWeekTimeRange range = new DayOfWeekTimeRange(DayOfWeek.FRIDAY, LocalTime.of(20,0), DayOfWeek.SUNDAY, LocalTime.of(20,0));
System.out.println(range.inRange(LocalDateTime.of(2015, 11, 12, 22, 0))); // Thu Nov. 12 2015 at 10:00 PM
System.out.println(range.inRange(LocalDateTime.of(2015, 11, 14,  8, 0))); // Sat Nov. 14 2015 at  8:00 AM
System.out.println(range.inRange(LocalDateTime.of(2015, 11, 16, 15, 0))); // Mon Nov. 16 2015 at  3:00 PM

// Fri 10:00 PM  to  Mon 10:00 PM
range = new DayOfWeekTimeRange(DayOfWeek.FRIDAY, LocalTime.of(20,0), DayOfWeek.MONDAY, LocalTime.of(20,0));
System.out.println(range.inRange(LocalDateTime.of(2015, 11, 12, 22, 0))); // Thu Nov. 12 2015 at 10:00 PM
System.out.println(range.inRange(LocalDateTime.of(2015, 11, 14,  8, 0))); // Sat Nov. 14 2015 at  8:00 AM
System.out.println(range.inRange(LocalDateTime.of(2015, 11, 16, 15, 0))); // Mon Nov. 16 2015 at  3:00 PM

产量

2

替代方案

当然,如果你用DayOfWeekLocalTime做了很多处理,你应该考虑实现你自己的LocalDayOfWeekTime类,把两者结合起来,就像LocalDateTime只是一个LocalDateLocalTime的组合(这是你自己检查)。


只有当我们也假设间隔总是小于一周时,这个问题才得到很好的定义。

然后你可以工作1周;例如,如果你用毫秒表示所有的事情,你将工作模块n=1000*60*60*24*7。

现在计算a=checkdate-start(mod n)和b=end-start(mod n)并测试a

您需要为开始和结束选择一个真正的日期,在您的示例中是一个真正的星期五20:00和一个真正的星期六20:00。因为模运算,哪一个不重要。

还要记住,Java%操作符不同于负数的数学模型。所以一定要把它应用到正数上。


我编写了一个测试程序,它需要两个日期时间(范围),然后测试一个日期时间,看它是否在该范围内。

我用了完整的日期,以便你可以跨越一个多星期,如果你想。

以下是测试结果:

1
2
3
4
Testing for the date range Fri, 13 Nov 2015 20:00 to Sun, 15 Nov 2015 20:00
12 Nov 2015 22:00: false
14 Nov 2015 08:00: true
16 Nov 2015 10:00: false

这是密码。我将日期时间作为字符串输入,以便于使用此代码,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
package com.ggl.testing;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

public class DateRangeTesting {

    private static final SimpleDateFormat inputDateFormat = new SimpleDateFormat(
           "d MMM yyyy H:mm");
    private static final SimpleDateFormat outputDateFormat = new SimpleDateFormat(
           "EEE, d MMM yyyy H:mm");

    private Calendar fromDate;
    private Calendar toDate;

    public static void main(String[] args) {
        DateRangeTesting drTesting = new DateRangeTesting("13 Nov 2015 20:00",
               "15 Nov 2015 20:00");
        printResult("12 Nov 2015 22:00", drTesting);
        printResult("14 Nov 2015 08:00", drTesting);
        printResult("16 Nov 2015 10:00", drTesting);
    }

    private static void printResult(String s, DateRangeTesting drTesting) {
        System.out.println(s +":" + drTesting.testDate(s));
    }

    public DateRangeTesting(String fromDateString, String toDateString) {
        this.fromDate = convertInputDate(fromDateString);
        this.toDate = convertInputDate(toDateString);
        System.out.println(displayRange());
    }

    private String displayRange() {
        StringBuilder builder = new StringBuilder();
        builder.append("Testing for the date range");
        builder.append(outputDateFormat.format(fromDate.getTime()));
        builder.append(" to");
        builder.append(outputDateFormat.format(toDate.getTime()));

        return builder.toString();
    }

    public boolean testDate(String dateString) {
        Calendar testDate = convertInputDate(dateString);
        boolean fromTest = fromDate.compareTo(testDate) <= 0;
        boolean toTest = testDate.compareTo(toDate) <= 0;
        return fromTest && toTest;
    }

    private Calendar convertInputDate(String dateString) {
        Calendar calendar = Calendar.getInstance();
        try {
            Date tempDate = inputDateFormat.parse(dateString);
            calendar.setTime(tempDate);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return calendar;
    }

}


首先,你需要让你的函数取一个日期时间参数,如果你在里面使用"now()",你将无法测试它。

您的基本想法似乎不错,可以将一周中的某一天用作数组的索引,或者检查范围,如果范围通过了一周的开始/结束时间,则将其设为两个范围或将其反转。