Java中查看当前时间是否落在当天的特定时间范围内

发布于 2024-08-25 21:40:25 字数 1026 浏览 3 评论 0原文

我确信这已经在 1000 个不同的地方进行了 1000 次。问题是我想知道是否有更好/标准/更快的方法来检查当前“时间”是否在以 hh:mm:ss 格式给出的两个时间值之间。例如,我的大型业务逻辑不应在 18:00:00 和 18:30:00 之间运行。所以这就是我的想法:

 public static  boolean isCurrentTimeBetween(String starthhmmss, String endhhmmss) throws ParseException{
  DateFormat hhmmssFormat = new SimpleDateFormat("yyyyMMddhh:mm:ss");
  Date now = new Date();
  String yyyMMdd = hhmmssFormat.format(now).substring(0, 8);

  return(hhmmssFormat.parse(yyyMMdd+starthhmmss).before(now) &&
    hhmmssFormat.parse(yyyMMdd+endhhmmss).after(now));
 }

示例测试用例:

  String doNotRunBetween="18:00:00,18:30:00";//read from props file
  String[] hhmmss = downTime.split(",");
  if(isCurrentTimeBetween(hhmmss[0], hhmmss[1])){
   System.out.println("NOT OK TO RUN");
  }else{
   System.out.println("OK TO RUN");
  }

我正在寻找的是

  • 性能
  • 更好、外观
  • 正确的

代码我不是在寻找

  • 第三方库
  • 异常处理辩论
  • 变量命名约定
  • 方法修饰符问题

I am sure this was done 1000 times in 1000 different places. The question is I want to know if there is a better/standard/faster way to check if current "time" is between two time values given in hh:mm:ss format. For example, my big business logic should not run between 18:00:00 and 18:30:00. So here is what I had in mind:

 public static  boolean isCurrentTimeBetween(String starthhmmss, String endhhmmss) throws ParseException{
  DateFormat hhmmssFormat = new SimpleDateFormat("yyyyMMddhh:mm:ss");
  Date now = new Date();
  String yyyMMdd = hhmmssFormat.format(now).substring(0, 8);

  return(hhmmssFormat.parse(yyyMMdd+starthhmmss).before(now) &&
    hhmmssFormat.parse(yyyMMdd+endhhmmss).after(now));
 }

Example test case:

  String doNotRunBetween="18:00:00,18:30:00";//read from props file
  String[] hhmmss = downTime.split(",");
  if(isCurrentTimeBetween(hhmmss[0], hhmmss[1])){
   System.out.println("NOT OK TO RUN");
  }else{
   System.out.println("OK TO RUN");
  }

What I am looking for is code that is better

  • in performance
  • in looks
  • in correctness

What I am not looking for

  • third-party libraries
  • Exception handling debate
  • variable naming conventions
  • method modifier issues

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

失眠症患者 2024-09-01 21:40:25

这就是您需要做的全部,此方法与输入松散耦合且高度一致。

boolean isNowBetweenDateTime(final Date s, final Date e)
{
    final Date now = new Date();
    return now.after(s) && now.before(e);
}

如何获取开始和结束的 Date 对象与比较它们无关。通过传递 String 表示,您使事情变得比您需要的更加复杂。

这是获取开始日期和结束日期的更好方法,同样松散耦合且高度一致。

private Date dateFromHourMinSec(final String hhmmss)
{
    if (hhmmss.matches("^[0-2][0-9]:[0-5][0-9]:[0-5][0-9]$"))
    {
        final String[] hms = hhmmss.split(":");
        final GregorianCalendar gc = new GregorianCalendar();
        gc.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hms[0]));
        gc.set(Calendar.MINUTE, Integer.parseInt(hms[1]));
        gc.set(Calendar.SECOND, Integer.parseInt(hms[2]));
        gc.set(Calendar.MILLISECOND, 0);
        return gc.getTime();
    }
    else
    {
        throw new IllegalArgumentException(hhmmss + " is not a valid time, expecting HH:MM:SS format");
    }
}

现在您可以进行两个命名良好的方法调用,这将是非常自记录的。

this is all you should need to do, this method is loosely coupled from the input and highly coherent.

boolean isNowBetweenDateTime(final Date s, final Date e)
{
    final Date now = new Date();
    return now.after(s) && now.before(e);
}

how you get the Date objects for start and end is irrelevant to comparing them. You are making things way more complicated than you need to with passing String representations around.

Here is a better way to get the start and end dates, again loosely coupled and highly coherent.

private Date dateFromHourMinSec(final String hhmmss)
{
    if (hhmmss.matches("^[0-2][0-9]:[0-5][0-9]:[0-5][0-9]$"))
    {
        final String[] hms = hhmmss.split(":");
        final GregorianCalendar gc = new GregorianCalendar();
        gc.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hms[0]));
        gc.set(Calendar.MINUTE, Integer.parseInt(hms[1]));
        gc.set(Calendar.SECOND, Integer.parseInt(hms[2]));
        gc.set(Calendar.MILLISECOND, 0);
        return gc.getTime();
    }
    else
    {
        throw new IllegalArgumentException(hhmmss + " is not a valid time, expecting HH:MM:SS format");
    }
}

Now you can make two well named method calls that will be pretty self documenting.

╰つ倒转 2024-09-01 21:40:25

tl;dr

LocalTime now = 
    ZonedDateTime
        .now( ZoneId.of( "America/Montreal" ) )
        .toLocalTime() ;

Boolean isBetween = 
    ( ! now.isBefore( LocalTime.of( 18 , 0 ) )  // "not before" means "is equal to OR after".
    && 
    now.isBefore( LocalTime.of( 18 , 30 ) ) ;  // Half-Open, beginning is *inclusive* while ending is *exclusive*.
             

使用 java.time

您正在使用旧的日期时间类,这些类已被证明设计不佳、令人困惑且麻烦。它们现在是遗留,被 java.time 类取代。

LocalTime

不要仅传递表示时间值的字符串。我们现在有一个类型,即 LocalTime 类。

LocalTime start = LocalTime.of( 18 , 0 );
LocalTime stop = LocalTime.of( 18 , 30 );

将这些实例传递给您的实用程序方法。该方法不必执行任何解析,因此无需抛出解析异常。

public static  boolean isCurrentTimeBetween( LocalTime start , LocalTime stop ) {
…

ZonedDateTime

时区对于确定当前日期和时间至关重要。对于任何特定时刻,全球各地的日期都会因地区而异。例如,在法国巴黎午夜过后几分钟,又是新的一天“昨天”在魁北克蒙特利尔

大陆/地区格式指定正确的时区名称 ,例如 America/Montreal非洲/卡萨布兰卡,或太平洋/奥克兰 。切勿使用 3-4 个字母的缩写,例如 ESTIST,因为它们不是真正的时区,不是标准化的,甚至不是唯一的( !)。

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.now( z );

为了比较现在的时间,我们可以简单地从 ZonedDateTime 中提取 LocalTime。但我们面临着异常问题,例如夏令时 (DST) 和政客重新定义时区。特定日期可能没有下午 6 点。此难题的解决方案取决于您的业务环境和业务规则。您可以忽略这个难题,直接询问当前时间是否在目标起止时间之间。或者,您可以将时区应用于一天中的起止时间,并让 ZonedDateTime 类根据需要进行调整。让我们看看这两种方法。

忽略异常

首先,忽略任何异常。简单地按字面意思询问当前时间是否在目标开始时间和停止时间之间。

我们可以从分区日期时间对象中提取一天中的时间对象。

LocalTime localTimeNow = zdt.toLocalTime(); // Extract a time-of-day from the zoned date-time object.

将其与我们一天中的启停时间进行比较。请注意,我们在这里使用半开放方法来定义时间跨度。在这种方法中,开头是包含,而结尾是排除。这种方法在约会工作中很常见,通常是明智的选择。

Boolean isNowOnOrAfterStart = ( ! localTimeNow.isBefore( start ) ) ;  // A briefer way of asking "is equal to OR is after" is "is not before". 
Boolean isNowBeforeStop = localTimeNow.isBefore( stop );
Boolean isNowInTargetZone = ( isNowOnOrAfterStart && isNowBeforeStop ); // Half-Open: beginning is inclusive while ending is exclusive.

考虑异常

接下来我们考虑任何异常。我们将一天中的开始和停止时间应用于同一时区内的当前日期。我们从分区日期时间对象中提取仅日期。

LocalDate localDateToday = zdt.toLocalDate();
ZonedDateTime zdtStart = ZonedDateTime.of( localDateToday , start , z );
ZonedDateTime zdtStop = ZonedDateTime.of( localDateToday , stop , z );

研究类文档以了解 ZonedDateTime.of 解决无效的时间值。没有完美的方法来解决不存在的时间值,因此您必须确定此类的方法是否满足您的业务规则。

ZonedDateTime.of

public static ZonedDateTime of(LocalDate 日期、LocalTime 时间、ZoneId 区域)

从本地日期和时间获取 ZonedDateTime 的实例。
这将创建一个与输入的本地日期和时间尽可能匹配的分区日期时间。时区规则(例如夏令时)意味着并非每个本地日期时间都对指定区域有效,因此本地日期时间可能会进行调整。

首先将本地日期时间与本地日期时间结合起来形成本地日期时间。然后,本地日期时间被解析为时间线上的单个时刻。这是通过找到区域 ID 规则定义的本地日期时间与 UTC/格林威治的有效偏移量来实现的。

在大多数情况下,本地日期时间只有一个有效的偏移量。在重叠的情况下,当时钟被调回时,有两个有效的偏移。此方法使用通常对应于“夏天”的较早偏移量。

在有间隙的情况下,当时钟向前跳跃时,没有有效的偏移。相反,本地日期时间会根据间隙的长度调整为较晚的时间。对于典型的一小时夏令时更改,本地日期时间将移至一小时后,通常对应于“夏季”的偏移量中。

应用与我们上面看到的相同的比较逻辑。

Boolean isNowOnOrAfterStart = ( ! zdt.isBefore( zdtStart ) ) ;  // A briefer way of asking "is equal to OR is after" is "is not before". 
Boolean isNowBeforeStop = zdt.isBefore( zdtStop );
Boolean isNowInTargetZone = ( isNowOnOrAfterStart && isNowBeforeStop ); // Half-Open: beginning is inclusive while ending is exclusive.

进行比较的另一种方法是使用 ThreeTen-Extra 项目中方便的 Interval 类。该类需要使用 Instant 对象,您可以从 ZonedDateTime 对象中提取这些对象。 即时 类代表 UTC 中时间轴上的时刻,分辨率为 纳秒(最多九 (9) 位小数)。

Interval interval = Interval.of( zdtStart.toInstant() , zdtStop.toInstant() );
Boolean isNowInTargetZone = interval.contains( zdt.toInstant() );

关于 java.time

java.time 框架内置于 Java 8 及更高版本中。这些类取代了麻烦的旧遗留日期时间类,例如java.util.Date, 日历, & ; SimpleDateFormat

Joda-Time 项目,现已在 维护模式,建议迁移到 java.time 类。

要了解更多信息,请参阅 Oracle 教程。并在 Stack Overflow 上搜索许多示例和解释。规范为 JSR 310

从哪里获取 java.time 类?

ThreeTen-Extra 项目通过附加类扩展了 java.time。该项目是 java.time 未来可能添加的内容的试验场。您可能会在这里找到一些有用的类,例如 间隔YearWeek<代码>YearQuarter,以及更多

tl;dr

LocalTime now = 
    ZonedDateTime
        .now( ZoneId.of( "America/Montreal" ) )
        .toLocalTime() ;

Boolean isBetween = 
    ( ! now.isBefore( LocalTime.of( 18 , 0 ) )  // "not before" means "is equal to OR after".
    && 
    now.isBefore( LocalTime.of( 18 , 30 ) ) ;  // Half-Open, beginning is *inclusive* while ending is *exclusive*.
             

Using java.time

You are using old date-time classes that have proven to be poorly designed, confusing, and troublesome. They are now legacy, supplanted by the java.time classes.

LocalTime

Do not pass mere strings representing time-of-day values. We now have a type for that, the LocalTime class.

LocalTime start = LocalTime.of( 18 , 0 );
LocalTime stop = LocalTime.of( 18 , 30 );

Pass those instances to your utility method. That method should not have to do any parsing, so no need to throw the parsing exception.

public static  boolean isCurrentTimeBetween( LocalTime start , LocalTime stop ) {
…

ZonedDateTime

A time zone is crucial in determining the current date and time-of-day. For any given moment, the date varies around the globe by zone. For example, a few minutes after midnight in Paris France is a new day while still “yesterday” in Montréal Québec.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter abbreviation such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.now( z );

To compare the time-of-day of now, we could simply extract a LocalTime from that ZonedDateTime. But we have the problem of anomalies, such as Daylight Saving Time (DST) and politicians redefining time zones. There may not be any 6 PM hour on a particular date. The solution to this conundrum depends on your business context and your business rules. You could either ignore the conundrum and stick with literally asking if the current time is between your target start-stop time. Or you could apply the time zone to your start-stop times-of-day of day and let ZonedDateTime class make adjustments as it sees fit. Let's look at both approaches.

Ignore anomalies

First, ignore any anomalies. Ask simply and literally if the current time-of-day is between the target start and stop times-of-day.

We can extract a time-of-day object from the zoned date-time object.

LocalTime localTimeNow = zdt.toLocalTime(); // Extract a time-of-day from the zoned date-time object.

Compare that to our stop-start times-of-day. Note that we use here the Half-Open approach to defining a span of time. In this approach the beginning is inclusive while the ending is exclusive. This approach is common in date-time work and generally is the wise way to go.

Boolean isNowOnOrAfterStart = ( ! localTimeNow.isBefore( start ) ) ;  // A briefer way of asking "is equal to OR is after" is "is not before". 
Boolean isNowBeforeStop = localTimeNow.isBefore( stop );
Boolean isNowInTargetZone = ( isNowOnOrAfterStart && isNowBeforeStop ); // Half-Open: beginning is inclusive while ending is exclusive.

Consider anomalies

Next we consider any anomalies. We apply the start and stop times-of-day to the current date within the same time zone. We extract the date-only from the zoned date-time object.

LocalDate localDateToday = zdt.toLocalDate();
ZonedDateTime zdtStart = ZonedDateTime.of( localDateToday , start , z );
ZonedDateTime zdtStop = ZonedDateTime.of( localDateToday , stop , z );

Study the class documentation to understand the behavior of ZonedDateTime.of in resolving invalid time-of-day values. There is no perfect way to resolve nonexistent time-of-day values, so you must decide if this class’ way meets your business rules.

ZonedDateTime.of

public static ZonedDateTime of(LocalDate date, LocalTime time, ZoneId zone)

Obtains an instance of ZonedDateTime from a local date and time.
This creates a zoned date-time matching the input local date and time as closely as possible. Time-zone rules, such as daylight savings, mean that not every local date-time is valid for the specified zone, thus the local date-time may be adjusted.

The local date time and first combined to form a local date-time. The local date-time is then resolved to a single instant on the time-line. This is achieved by finding a valid offset from UTC/Greenwich for the local date-time as defined by the rules of the zone ID.

In most cases, there is only one valid offset for a local date-time. In the case of an overlap, when clocks are set back, there are two valid offsets. This method uses the earlier offset typically corresponding to "summer".

In the case of a gap, when clocks jump forward, there is no valid offset. Instead, the local date-time is adjusted to be later by the length of the gap. For a typical one hour daylight savings change, the local date-time will be moved one hour later into the offset typically corresponding to "summer".

Apply the same comparison logic as we saw above.

Boolean isNowOnOrAfterStart = ( ! zdt.isBefore( zdtStart ) ) ;  // A briefer way of asking "is equal to OR is after" is "is not before". 
Boolean isNowBeforeStop = zdt.isBefore( zdtStop );
Boolean isNowInTargetZone = ( isNowOnOrAfterStart && isNowBeforeStop ); // Half-Open: beginning is inclusive while ending is exclusive.

Alternative way to make the comparison is to use the handy Interval class from the ThreeTen-Extra project. That class takes a pain of Instant objects, which you can extract from your ZonedDateTime objects. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

Interval interval = Interval.of( zdtStart.toInstant() , zdtStop.toInstant() );
Boolean isNowInTargetZone = interval.contains( zdt.toInstant() );

About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

究竟谁懂我的在乎 2024-09-01 21:40:25

正如 Kevin 所指出的,Fuzzy Lollipop 的正则表达式不会获取 14:00 到 19:00 之间的时间。

要获得完整的 24 小时时钟,您可以使用以下命令:

if (hhmmss.matches("^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"))
{
    // Do stuff here
}

As pointed out by Kevin, Fuzzy Lollipop's Regex won't pick up times between 14:00 and 19:00.

To get match a full 24 hour clock, you can use this:

if (hhmmss.matches("^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"))
{
    // Do stuff here
}
妳是的陽光 2024-09-01 21:40:25

下面的类是我刚刚根据其他答案的一些代码创建的。它封装了“时间段”的行为,与特定日期无关。我们的系统使用此类来检查当前时间是否在我们指定的维护窗口之一内。即 05:00:00 - 07:00:00

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
*
* @author Adam Yocum
*/
public class ExclusionTimePeriod {
    private String timeStart;
    private String timeEnd;

    /**
    * @return the timeStart
    */
    public String getTimeStart() {
        return timeStart;
    }

    /**
    * @param timeStart the timeStart to set
    */
    public void setTimeStart(String timeStart) {
        if (timeStart.matches("^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"))
        {
            this.timeStart = timeStart;
        }
        else
        {
            throw new IllegalArgumentException(timeStart + " is not a valid time, expecting HH:MM:SS format");
        }

    }

    /**
    * @return the timeEnd
    */
    public String getTimeEnd() {
        return timeEnd;
    }

    /**
    * @param timeEnd the timeEnd to set
    */
    public void setTimeEnd(String timeEnd) {
        if (timeEnd.matches("^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"))
        {
            this.timeEnd = timeEnd;
        }
        else
        {
            throw new IllegalArgumentException(timeEnd + " is not a valid time, expecting HH:MM:SS format");
        }
    }

    private Date toDate(String hhmmss){
        final String[] hms = hhmmss.split(":");
        final GregorianCalendar gc = new GregorianCalendar();
        gc.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hms[0]));
        gc.set(Calendar.MINUTE, Integer.parseInt(hms[1]));
        gc.set(Calendar.SECOND, Integer.parseInt(hms[2]));
        gc.set(Calendar.MILLISECOND, 0);
        Date date = gc.getTime();
        return date;
    }

    public boolean isNowInPeriod()
    {
        final Date now = new Date();
        return now.after(toDate(getTimeStart())) && now.before(toDate(getTimeEnd()));
    }

    public static void main(String[] args){

        //Test All possible hours
        for(int hour=0;hour<=23;hour++){

            String hourStr = "";
            if(hour<=9){
                hourStr = "0"+hour;
            }else{
                hourStr = ""+hour;
            }

            for(int min=0;min<60;min++){
                String minStr = "";
                if(min<=9){
                    minStr = "0"+min;
                }else{
                    minStr = ""+min;
                }

                for(int sec=0;sec<60;sec++){
                    String secStr = "";
                    if(sec<=9){
                        secStr = "0"+sec;
                    }else{
                        secStr = ""+sec;
                    }

                    String hhmmss = hourStr+":"+minStr+":"+secStr;

                    ExclusionTimePeriod period = new ExclusionTimePeriod();
                    period.setTimeStart(hhmmss);
                    period.setTimeEnd(hhmmss);

                    System.out.println(hhmmss+" Ok");
                }
            }
        }


        //Test isInPeriod functionality
        ExclusionTimePeriod isInTest = new ExclusionTimePeriod();
        isInTest.setTimeStart("10:00:00");
        isInTest.setTimeEnd("10:43:00");

        System.out.println((new Date())+" is between "+isInTest.getTimeStart()+" and "+isInTest.getTimeEnd()+" = "+isInTest.isNowInPeriod());

    }
}

The following Class is something I just created out of some of the code from other answers. It encapsulates the behavior of a 'time period' without relating to specific days. Our system is using this Class to check if the current time is within one of our designated maintenance windows. i.e. 05:00:00 - 07:00:00

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

/**
*
* @author Adam Yocum
*/
public class ExclusionTimePeriod {
    private String timeStart;
    private String timeEnd;

    /**
    * @return the timeStart
    */
    public String getTimeStart() {
        return timeStart;
    }

    /**
    * @param timeStart the timeStart to set
    */
    public void setTimeStart(String timeStart) {
        if (timeStart.matches("^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"))
        {
            this.timeStart = timeStart;
        }
        else
        {
            throw new IllegalArgumentException(timeStart + " is not a valid time, expecting HH:MM:SS format");
        }

    }

    /**
    * @return the timeEnd
    */
    public String getTimeEnd() {
        return timeEnd;
    }

    /**
    * @param timeEnd the timeEnd to set
    */
    public void setTimeEnd(String timeEnd) {
        if (timeEnd.matches("^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$"))
        {
            this.timeEnd = timeEnd;
        }
        else
        {
            throw new IllegalArgumentException(timeEnd + " is not a valid time, expecting HH:MM:SS format");
        }
    }

    private Date toDate(String hhmmss){
        final String[] hms = hhmmss.split(":");
        final GregorianCalendar gc = new GregorianCalendar();
        gc.set(Calendar.HOUR_OF_DAY, Integer.parseInt(hms[0]));
        gc.set(Calendar.MINUTE, Integer.parseInt(hms[1]));
        gc.set(Calendar.SECOND, Integer.parseInt(hms[2]));
        gc.set(Calendar.MILLISECOND, 0);
        Date date = gc.getTime();
        return date;
    }

    public boolean isNowInPeriod()
    {
        final Date now = new Date();
        return now.after(toDate(getTimeStart())) && now.before(toDate(getTimeEnd()));
    }

    public static void main(String[] args){

        //Test All possible hours
        for(int hour=0;hour<=23;hour++){

            String hourStr = "";
            if(hour<=9){
                hourStr = "0"+hour;
            }else{
                hourStr = ""+hour;
            }

            for(int min=0;min<60;min++){
                String minStr = "";
                if(min<=9){
                    minStr = "0"+min;
                }else{
                    minStr = ""+min;
                }

                for(int sec=0;sec<60;sec++){
                    String secStr = "";
                    if(sec<=9){
                        secStr = "0"+sec;
                    }else{
                        secStr = ""+sec;
                    }

                    String hhmmss = hourStr+":"+minStr+":"+secStr;

                    ExclusionTimePeriod period = new ExclusionTimePeriod();
                    period.setTimeStart(hhmmss);
                    period.setTimeEnd(hhmmss);

                    System.out.println(hhmmss+" Ok");
                }
            }
        }


        //Test isInPeriod functionality
        ExclusionTimePeriod isInTest = new ExclusionTimePeriod();
        isInTest.setTimeStart("10:00:00");
        isInTest.setTimeEnd("10:43:00");

        System.out.println((new Date())+" is between "+isInTest.getTimeStart()+" and "+isInTest.getTimeEnd()+" = "+isInTest.isNowInPeriod());

    }
}
一曲爱恨情仇 2024-09-01 21:40:25

午夜问题

其他答案没有提到它 - 并且OP也没有问 - 但你应该真正考虑间隔跨越午夜

时间很困难。我故意留下了代码的“长”版本,并且没有缩写逻辑条件,以尽可能清楚地说明是什么和为什么。

/**
 * Takes into consideration that the interval may span accross midnight
 *
 * @param clock to make unit testing easier, just replace for Clock.systemUTC() in your code 
 * @param start the interval start
 * @param end the interval end
 * @return true if "now" is inside the specified interval
 */
static boolean isNowBetweenLocalTime(Clock clock, final LocalTime start, final LocalTime end) {
    LocalTime now = LocalTime.now(clock);

    // if interval crosses midnight
    if (end.isBefore(start)) {
        if (now.isAfter(start) && now.isAfter(end)) {
            return true;
        }
        if (now.isBefore(start) && now.isBefore(end)) {
            return true;
        }
        return false;
    }

    // if interval does not cross midnight
    if (end.isAfter(start)) {
        if (now.isAfter(start) && now.isBefore(end)) {
            return true;
        }
        return false;
    }

    return false; // interval is 0 so start and end always outside interval
}

冗长并不总是错误的。这个方法将被隐藏在一个实用程序类中,两年后你会感谢自己理解它的作用!

The Midnight Problem

Other answers fail to mention it - and the OP doesn't ask - but you should really consider when the interval spans across midnight.

Time is difficult. I purposely left the "long" version of the code and didn't abbreviate logical conditions to make it as clear as possible the what's and the why's.

/**
 * Takes into consideration that the interval may span accross midnight
 *
 * @param clock to make unit testing easier, just replace for Clock.systemUTC() in your code 
 * @param start the interval start
 * @param end the interval end
 * @return true if "now" is inside the specified interval
 */
static boolean isNowBetweenLocalTime(Clock clock, final LocalTime start, final LocalTime end) {
    LocalTime now = LocalTime.now(clock);

    // if interval crosses midnight
    if (end.isBefore(start)) {
        if (now.isAfter(start) && now.isAfter(end)) {
            return true;
        }
        if (now.isBefore(start) && now.isBefore(end)) {
            return true;
        }
        return false;
    }

    // if interval does not cross midnight
    if (end.isAfter(start)) {
        if (now.isAfter(start) && now.isBefore(end)) {
            return true;
        }
        return false;
    }

    return false; // interval is 0 so start and end always outside interval
}

Verbosity is not always wrong. This method will be buried in a utility class and two years from now you'll thank yourself for understanding what it does!

卸妝后依然美 2024-09-01 21:40:25

dateFromHourMinSec 方法如所写的那样存在缺陷。它不允许第二位数字大于 3 的任何时间,例如 18:00:00。如果将其更改为允许 [0-2][0-9],它将允许 29:00:00 等时间。
有解决办法吗?

The dateFromHourMinSec method is flawed as written. It won't allow any hours where the seconde digit is greater than 3, e.g. 18:00:00. If you change it to allow [0-2][0-9] it will allow times such as 29:00:00.
Have a fix for that?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文