繁体   English   中英

无论日期如何,检查给定时间是否介于两次之间

[英]Check if a given time lies between two times regardless of date

我有时间跨度:

字符串时间 1 = 01:00:00

字符串时间 2 = 05:00:00

我想检查time1time2是否都位于20:11:13 and 14:49:00之间。

实际上,考虑到20:11:13总是小于14:49:0001:00:00大于20:11:13并且小于14:49:00 这是先决条件。

所以我想要的是20:11:13 < 01:00:00 < 14:49:00

所以我需要这样的东西:

 public void getTimeSpans()
{
    boolean firstTime = false, secondTime = false;
    
    if(time1 > "20:11:13" && time1 < "14:49:00")
    {
       firstTime = true;
    }
    
    if(time2 > "20:11:13" && time2 < "14:49:00")
    {
       secondTime = true;
    }
 }

我知道这段代码在比较字符串对象时没有给出正确的结果。

如何做到这一点,因为它们是时间跨度而不是要比较的字符串?

您可以使用Calendar类进行检查。

例如:

try {
    String string1 = "20:11:13";
    Date time1 = new SimpleDateFormat("HH:mm:ss").parse(string1);
    Calendar calendar1 = Calendar.getInstance();
    calendar1.setTime(time1);
    calendar1.add(Calendar.DATE, 1);


    String string2 = "14:49:00";
    Date time2 = new SimpleDateFormat("HH:mm:ss").parse(string2);
    Calendar calendar2 = Calendar.getInstance();
    calendar2.setTime(time2);
    calendar2.add(Calendar.DATE, 1);

    String someRandomTime = "01:00:00";
    Date d = new SimpleDateFormat("HH:mm:ss").parse(someRandomTime);
    Calendar calendar3 = Calendar.getInstance();
    calendar3.setTime(d);
    calendar3.add(Calendar.DATE, 1);

    Date x = calendar3.getTime();
    if (x.after(calendar1.getTime()) && x.before(calendar2.getTime())) {
        //checkes whether the current time is between 14:49:00 and 20:11:13.
        System.out.println(true);
    }
} catch (ParseException e) {
    e.printStackTrace();
}

tl;博士

20:11:13 < 01:00:00 < 14:49:00

LocalTime target = LocalTime.parse( "01:00:00" ) ;
Boolean targetInZone = ( 
    target.isAfter( LocalTime.parse( "20:11:13" ) ) 
    && 
    target.isBefore( LocalTime.parse( "14:49:00" ) ) 
) ; 

java.time.LocalTime

该java.time类包括LocalTime来表示时间的天只没有日期,没有一个时区。

所以我想要的是,20:11:13 < 01:00:00 < 14:49:00。

首先我们定义边界。 您的输入字符串恰好符合标准ISO 8601格式。 java.time 类默认使用 ISO 8601 格式,因此无需指定格式模式。

LocalTime start = LocalTime.parse( "20:11:13" );
LocalTime stop = LocalTime.parse( "14:49:00" );

并定义我们的测试用例,目标01:00:00

LocalTime target = LocalTime.parse( "01:00:00" );

现在我们准备比较这些LocalTime对象。 我们想看看目标是否在较晚的时间之后但在较早的时间之前。 在这种情况下,这意味着半夜,大约在晚上 8 点到第二天早上 3 点之间。

Boolean isTargetAfterStartAndBeforeStop = ( target.isAfter( start ) && target.isBefore( stop ) ) ;

该测试可以更简单地表述为“不在凌晨 3 点到晚上 8 点之间”。 然后,我们可以推广到任何一对LocalTime对象,我们测试了,如果一开始配备了24小时时钟停止前,并没有如开始来停止后(如本题的情况下)之间

此外,时间跨度通常使用半开方法处理,其中开始是包容性的,而结束是独占性的 因此,严格来说,“介于”比较将是“目标是否等于或晚于开始且目标在停止之前”,或者更简单地说,“目标不在开始之前且在停止之前”。

Boolean isBetweenStartAndStopStrictlySpeaking = 
    ( ( ! target.isBefore( start ) && target.isBefore( stop ) ) ;

如果开始是在停止之后,在 24 小时时钟内,那么假设我们想要问题中建议的逻辑(在晚上 8 点之后但在凌晨 3 点之前)。

if( start.isAfter( stop ) ) {
    return ! isBetweenStartAndStopStrictlySpeaking ;
} else {
    return isBetweenStartAndStopStrictlySpeaking ;
}

关于java.time

java.time框架内置于 Java 8 及更高版本中。 这些类取代麻烦的老传统日期时间类,如java.util.DateCalendar ,和SimpleDateFormat

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

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

您可以直接与您的数据库交换java.time对象。 使用符合JDBC 4.2或更高版本的JDBC 驱动程序 不需要字符串,不需要java.sql.*类。 Hibernate 5 & JPA 2.2 支持java.time

从哪里获得 java.time 类?

@kocko 给出的答案仅在同一天有效。
如果开始时间“23:00:00”和结束“02:00:00” [第二天]并且当前时间是“01:30:00”那么结果将是假的...
我修改了@kocko 的答案以完美地工作

public static boolean isTimeBetweenTwoTime(String initialTime, String finalTime, 
    String currentTime) throws ParseException {

    String reg = "^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";
    if (initialTime.matches(reg) && finalTime.matches(reg) && 
        currentTime.matches(reg)) 
    {
        boolean valid = false;
        //Start Time
        //all times are from java.util.Date
        Date inTime = new SimpleDateFormat("HH:mm:ss").parse(initialTime);
        Calendar calendar1 = Calendar.getInstance();
        calendar1.setTime(inTime);

        //Current Time
        Date checkTime = new SimpleDateFormat("HH:mm:ss").parse(currentTime);
        Calendar calendar3 = Calendar.getInstance();
        calendar3.setTime(checkTime);

        //End Time
        Date finTime = new SimpleDateFormat("HH:mm:ss").parse(finalTime);
        Calendar calendar2 = Calendar.getInstance();
        calendar2.setTime(finTime);

        if (finalTime.compareTo(initialTime) < 0) 
        {
            calendar2.add(Calendar.DATE, 1);
            calendar3.add(Calendar.DATE, 1);
        }

        java.util.Date actualTime = calendar3.getTime();
        if ((actualTime.after(calendar1.getTime()) || 
             actualTime.compareTo(calendar1.getTime()) == 0) && 
             actualTime.before(calendar2.getTime())) 
        {
            valid = true;
            return valid;
        } else {
            throw new IllegalArgumentException("Not a valid time, expecting 
            HH:MM:SS format");
        }
    }
}

输出

"07:00:00" - "17:30:00" - "15:30:00" [current] - true
"17:00:00" - "21:30:00" - "16:30:00" [current] - false
"23:00:00" - "04:00:00" - "02:00:00" [current] - true
"00:30:00" - "06:00:00" - "06:00:00" [current] - false 

(我在[上限值-1]中包含了下限值)

修改了@Surendra Jnawali 的代码。 它失败了

如果当前时间是 23:40:00,即大于开始时间且小于等于 23:59:59。

所有功劳归于真正的所有者

这应该是这样的:这很完美

public static boolean isTimeBetweenTwoTime(String argStartTime,
            String argEndTime, String argCurrentTime) throws ParseException {
        String reg = "^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";
        //
        if (argStartTime.matches(reg) && argEndTime.matches(reg)
                && argCurrentTime.matches(reg)) {
            boolean valid = false;
            // Start Time
            java.util.Date startTime = new SimpleDateFormat("HH:mm:ss")
                    .parse(argStartTime);
            Calendar startCalendar = Calendar.getInstance();
            startCalendar.setTime(startTime);

            // Current Time
            java.util.Date currentTime = new SimpleDateFormat("HH:mm:ss")
                    .parse(argCurrentTime);
            Calendar currentCalendar = Calendar.getInstance();
            currentCalendar.setTime(currentTime);

            // End Time
            java.util.Date endTime = new SimpleDateFormat("HH:mm:ss")
                    .parse(argEndTime);
            Calendar endCalendar = Calendar.getInstance();
            endCalendar.setTime(endTime);

            //
            if (currentTime.compareTo(endTime) < 0) {

                currentCalendar.add(Calendar.DATE, 1);
                currentTime = currentCalendar.getTime();

            }

            if (startTime.compareTo(endTime) < 0) {

                startCalendar.add(Calendar.DATE, 1);
                startTime = startCalendar.getTime();

            }
            //
            if (currentTime.before(startTime)) {

                System.out.println(" Time is Lesser ");

                valid = false;
            } else {

                if (currentTime.after(endTime)) {
                    endCalendar.add(Calendar.DATE, 1);
                    endTime = endCalendar.getTime();

                }

                System.out.println("Comparing , Start Time /n " + startTime);
                System.out.println("Comparing , End Time /n " + endTime);
                System.out
                        .println("Comparing , Current Time /n " + currentTime);

                if (currentTime.before(endTime)) {
                    System.out.println("RESULT, Time lies b/w");
                    valid = true;
                } else {
                    valid = false;
                    System.out.println("RESULT, Time does not lies b/w");
                }

            }
            return valid;

        } else {
            throw new IllegalArgumentException(
                    "Not a valid time, expecting HH:MM:SS format");
        }

    }

结果

Comparing , Start Time /n    Thu Jan 01 23:00:00 IST 1970
Comparing , End Time /n      Fri Jan 02 02:00:00 IST 1970
Comparing , Current Time /n  Fri Jan 02 01:50:00 IST 1970
RESULT, Time lies b/w
 Calendar now = Calendar.getInstance();

 int hour = now.get(Calendar.HOUR_OF_DAY); // Get hour in 24 hour format
 int minute = now.get(Calendar.MINUTE);

 Date date = parseDate(hour + ":" + minute);
 Date dateCompareOne = parseDate("08:00");
 Date dateCompareTwo = parseDate("20:00");

 if (dateCompareOne.before( date ) && dateCompareTwo.after(date)) {
    //your logic
 }

 private Date parseDate(String date) {

    final String inputFormat = "HH:mm";
    SimpleDateFormat inputParser = new SimpleDateFormat(inputFormat, Locale.US);
    try {
         return inputParser.parse(date);
    } catch (java.text.ParseException e) {
         return new Date(0);
    }
 }

此外,更准确地说,如果您比较当天的 00:00 到 24:00 之间的时间间隔,则还需要解析当天。

这里有很多答案,但我想提供一个新的答案,它与Basil Bourque 的答案相似,但有一个完整的代码示例。 所以请看下面的方法:

private static void checkTime(String startTime, String endTime, String checkTime) {
    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm:ss", Locale.US);
    LocalTime startLocalTime = LocalTime.parse(startTime, formatter);
    LocalTime endLocalTime = LocalTime.parse(endTime, formatter);
    LocalTime checkLocalTime = LocalTime.parse(checkTime, formatter);

    boolean isInBetween = false;
    if (endLocalTime.isAfter(startLocalTime)) {
      if (startLocalTime.isBefore(checkLocalTime) && endLocalTime.isAfter(checkLocalTime)) {
          isInBetween = true;
      }
    } else if (checkLocalTime.isAfter(startLocalTime) || checkLocalTime.isBefore(endLocalTime)) {
        isInBetween = true;
    }

    if (isInBetween) {
        System.out.println("Is in between!");
    } else {
        System.out.println("Is not in between!");
    }
}

如果您使用以下方法调用此方法:

checkTime("20:11:13", "14:49:00", "01:00:00");

或使用:

checkTime("20:11:13", "14:49:00", "05:00:00");

结果将是:

Is in between!

以下方法检查“validateTime”是否在“startTime”和“endTime”之间,同时考虑“endTime”可能是第二天的可能性。 要正确使用它,请在“HH:mm”共振峰中解析您的日期。

 public static final boolean isBetweenValidTime(Date startTime, Date endTime, Date validateTime)
 {
        boolean validTimeFlag = false;

        if(endTime.compareTo(startTime) <= 0)
        {
            if(validateTime.compareTo(endTime) < 0 || validateTime.compareTo(startTime) >= 0)
            {
                 validTimeFlag = true;
            }
        }
        else if(validateTime.compareTo(endTime) < 0 && validateTime.compareTo(startTime) >= 0)
        {
             validTimeFlag = true;  
        }

        return validTimeFlag;
 }

看了几个回复,感觉写的太复杂了。 试试我的代码

 public static boolean compare(String system_time, String currentTime, String endtimes) {
    try {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("HH:mm:ss");

        Date startime = simpleDateFormat.parse("19:25:00");
        Date endtime = simpleDateFormat.parse("20:30:00");

        //current time
        Date current_time = simpleDateFormat.parse("20:00:00");

    if (current_time.after(startime) && current_time.before(endtime)) {
            System.out.println("Yes");
            return true;
      }
    else if (current_time.after(startime) && current_time.after(endtime)) {
         return true; //overlap condition check
      }
     else {
            System.out.println("No");
            return false;
        }
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return false;
 } 

在@kocko 的帮助下,完整的工作代码如下:

try{
Date time11 = new SimpleDateFormat("HH:mm:ss").parse("20:11:13");
Calendar calendar1 = Calendar.getInstance();
calendar1.setTime(time11);

Date time22 = new SimpleDateFormat("HH:mm:ss").parse("14:49:00");
Calendar calendar2 = Calendar.getInstance();
calendar2.setTime(time22);

Date currentTime = new SimpleDateFormat("HH:mm:ss").parse("00:00:00");
Calendar startingCalendar = Calendar.getInstance();
startingCalendar.setTime(currentTime);
startingCalendar.add(Calendar.DATE, 1);



//let's say we have to check about 01:00:00
String someRandomTime = time1;
Date d = new SimpleDateFormat("HH:mm:ss").parse(someRandomTime);
Calendar calendar3 = Calendar.getInstance();
calendar3.setTime(d);

if(startingCalendar.getTime().after(calendar1.getTime()))
{
calendar2.add(Calendar.DATE, 1);

    calendar3.add(Calendar.DATE, 1);
}

Date x = calendar3.getTime();

if (x.after(calendar1.getTime()) && x.before(calendar2.getTime())) 
{
System.out.println("Time is in between..");
}
else
{
System.out.println("Time is not in between..");
}

} catch (ParseException e) 
{
e.printStackTrace();
}

在我看来,您的问题是 OR 情况...您想检查 time1 > 20:11:13 OR time1 < 14:49:00。

永远不会有超过 20:11:13 的时间超过另一端 (14:49:00) 的范围,反之亦然。 把它想象成你正在检查时间不在正确排序的几个时间戳之间。

Java 8 - 本地日期时间

那这个呢?

final LocalDateTime now = LocalDateTime.now();
final LocalDateTime minRange = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), 22, 30); //Today, 10:30pm
LocalDateTime maxRange = LocalDateTime.of(now.getYear(), now.getMonth(), now.getDayOfMonth(), 6, 30); //Tomorrow, 6:30am
maxRange = maxRange.plusDays(1); //Ensures that you don't run into an exception if minRange is the last day in the month.
if (now.isAfter(minRange) && now.isBefore(maxRange)) {
    //Action
}

使用LocalTime只会忽略日期值:

public class TimeIntervalChecker {

static final LocalTime time1 = LocalTime.parse( "20:11:13"  ) ;
static final LocalTime time2 = LocalTime.parse( "14:49:00" ) ;

    public static void main(String[] args) throws java.lang.Exception {

        LocalTime nowUtcTime = LocalTime.now(Clock.systemUTC());

        if (nowUtcTime.isAfter(time1) && nowUtcTime.isBefore(time2)){
              System.out.println(nowUtcTime+" is after: "+ time1+" and before: "+ time2);
        } 

}

实际工作功能如下

public static boolean isTimeBetweenTwoTime(Date startTime, Date stopTime, Date currentTime) {
    //Start Time
    Calendar StartTime = Calendar.getInstance();
    StartTime.setTime(startTime);
    //Current Time
    Calendar CurrentTime = Calendar.getInstance();
    CurrentTime.setTime(currentTime);
    //Stop Time
    Calendar StopTime = Calendar.getInstance();
    StopTime.setTime(stopTime);

    if (stopTime.compareTo(startTime) < 0) {
        if (CurrentTime.compareTo(StopTime) < 0) {
            CurrentTime.add(Calendar.DATE, 1);
        }
        StopTime.add(Calendar.DATE, 1);
    }
    return CurrentTime.compareTo(StartTime) >= 0 && CurrentTime.compareTo(StopTime) < 0;
}

在您的情况下,开始时间 (20:11:13) 大于结束时间 (14:49:00)。 一个合理的假设是,您可以通过在结束时间添加一天或从开始时间减去一天来解决问题。 如果这样做,您将被困,因为您不知道测试时间是哪一天。

您可以通过检查您的测试时间是否在结束时间和开始时间之间来避免此陷阱。 如果为真,则结果“不在两者之间”; 否则结果是“介于两者之间”。

这是我一直在使用的JAVA中的功能。 到目前为止它对我有用。 祝你好运。

boolean IsTimeInBetween(Calendar startC, Calendar endC, Calendar testC){
    // assume year, month and day of month are all equal.
    startC.set(1,1,1);
    endC.set(1,1,1);
    testC.set(1,1,1);

    if (endC.compareTo(startC) > 0) {
        if ((testC.compareTo(startC)>=0) && (testC.compareTo(endC)<=0)) {
            return true;
        }else {
            return false;
        }
    }else if  (endC.compareTo(startC) < 0) {
        if ((testC.compareTo(endC) >= 0) && (testC.compareTo(startC) <= 0)) {
            return false;
        } else {
            return true;
        }
    } else{ // when endC.compareTo(startC)==0, I return a ture value. Change it if you have different application. 
        return true;
    }
}

要创建日历实例,您可以使用:

Calendar startC = Calendar.getInstance();
startC.set(Calendar.HOUR_OF_DAY, 20);
startC.set(Calendar.MINUTE,11);
startC.set(Calendar.SECOND,13);

在下面的代码片段中,正在验证当前时间(可以是任何时间)是否存在于开始时间和结束时间之间:

        Calendar startTimeCal = Calendar.getInstance();
        startTimeCal.setTime(startTime);

        int startTimeHour = startTimeCal.get(Calendar.HOUR_OF_DAY);

        if (startTimeHour == 0){
            startTimeHour = 24;
        }

        int startTimeMinutes = startTimeCal.get(Calendar.MINUTE);

        Calendar curTimeCal = Calendar.getInstance();
        curTimeCal.setTime(currentTime);

        int curTimeHour = curTimeCal.get(Calendar.HOUR_OF_DAY);
        int curTimeMinutes = curTimeCal.get(Calendar.MINUTE);

        Calendar endTimeCal = Calendar.getInstance();
        endTimeCal.setTime(endTime);

        int endTimeHour = endTimeCal.get(Calendar.HOUR_OF_DAY);

        if (endTimeHour == 0) {
            endTimeHour = 24;
        }

        int endTimeMinutes = endTimeCal.get(Calendar.MINUTE);

        if (((curTimeHour > startTimeHour) || (curTimeHour == startTimeHour && curTimeMinutes >= startTimeMinutes)) &&
                ((curTimeHour < endTimeHour) || (curTimeHour == endTimeHour && curTimeMinutes <= endTimeHour))) {
          //time exists between start and end time
        } else {
              //time doesn't exist between start and end time
        }

我是这样做的:

LocalTime time = LocalTime.now();
if (time.isAfter(LocalTime.of(02, 00)) && (time.isBefore(LocalTime.of(04, 00))))
{
    log.info("Checking after 2AM, before 4AM!");                    
}

编辑:

String time1 = "01:00:00";  
String time2 = "15:00:00";  
LocalTime time = LocalTime.parse(time2);  
if ((time.isAfter(LocalTime.of(20,11,13))) || (time.isBefore(LocalTime.of(14,49,0))))  
{  
    System.out.println("true");  
}  
else  
{  
    System.out.println("false");  
}    

这是一个使用新的 Java 8 类的解决方案,它很紧凑,不需要正则表达式或手动算术运算。 我的解决方案编码为包含 startTime 和专有 endTime,但可以根据您的需要轻松修改。

private boolean isTimeBetween(String timeToTest, String startTime, String endTime) {

    LocalTime timeToTestDt = LocalTime.parse(timeToTest, DateTimeFormatter.ISO_LOCAL_TIME);
    LocalTime startTimeDt = LocalTime.parse(startTime, DateTimeFormatter.ISO_LOCAL_TIME);
    LocalTime endTimeDt = LocalTime.parse(endTime, DateTimeFormatter.ISO_LOCAL_TIME);

    if(startTime.equals(endTime)) {
        return false;
    }
    else if(startTimeDt.isBefore(endTimeDt)) {  // Period does not cross the day boundary
        return (timeToTest.equals(startTime) || timeToTestDt.isAfter(startTimeDt)) 
                && timeToTestDt.isBefore(endTimeDt);
    } else {  // Time period spans two days, e.g. 23:00 to 2:00
        return (!((timeToTestDt.isAfter(endTimeDt) || timeToTest.equals(endTime)) 
                && timeToTestDt.isBefore(startTimeDt)));
    }
}

// getTimeSpans() from the original question would then look like this
public void getTimeSpans()
{
    boolean firstTime = isTimeBetween("01:00:00", "20:11:13", "14:49:00");
    boolean secondTime = isTimeBetween("05:00:00", "20:11:13", "14:49:00");
 }

所有差距的简单解决方案:

    public boolean isNowTimeBetween(String startTime, String endTime) {
        LocalTime start = LocalTime.parse(startTime);//"22:00"
        LocalTime end = LocalTime.parse(endTime);//"10:00"
        LocalTime now = LocalTime.now();

        if (start.isBefore(end))
            return now.isAfter(start) && now.isBefore(end);

        return now.isBefore(start)
                ? now.isBefore(start) && now.isBefore(end)
                : now.isAfter(start) && now.isAfter(end);
}

在我的情况下,我对约会时间一点也不感兴趣。 所以这是我的解决方案,它仅适用于整数小时:

boolean isInTimeRange(int startingHour, int endingHour, int hourOfDayToCheck) {
    if (endingHour > startingHour) {
        return hourOfDayToCheck >= startingHour && hourOfDayToCheck < endingHour;
    } else {
        return hourOfDayToCheck >= startingHour || hourOfDayToCheck < endingHour;
    }
}

从 $time、$to 和 $from 字符串中去除冒号,转换为 int,然后使用以下条件检查时间是否在 from 和 to 之间。 示例在 php 中,但应该无关紧要。

if(($to < $from && ($time >= $from || $time <= $to)) ||
    ($time >= $from && $time <= $to)) {
    return true;
}

从逻辑上讲,如果您执行以下操作,您应该总是可以的,因为我们使用军事时间......

如果开始时间大于结束时间,则将 24 添加到结束时间,否则按原样使用时间

比较当前时间在开始时间和结束时间之间。

正如许多人所注意到的,这不是日期问题,而是逻辑问题。 让我们假设一天被分成两个时间间隔:一个在 20:11:13 和 14:49:00 之间,而另一个在 14:49:00 和 20:11:13 之间(极端所属的时间间隔是你)。 如果您想检查某个时间是否包含在您感兴趣的 20:11:13/14:49:00 中,只需检查它是否包含在另一个 14:49:00/ 20:11:13,这要容易得多,因为数字的自然顺序,然后取反结果。

基于这里大多数作者的想法和解决方案,我想用一个大概更清晰的代码来分享我改进的解决方案:

    /**
 * Checks if some date is within a time window given by start and end dates
 *
 * @param checkDate - date to check if its hours and minutes is between the startDate and endDate
 * @param startDate - startDate of the time window
 * @param endDate - endDate of the time window
 * @return - returns true if hours and minutes of checkDate is between startDate and endDate
 */
public static boolean isDateBetweenStartAndEndHoursAndMinutes(Date checkDate, Date startDate, Date endDate) {
    if (startDate == null || endDate == null)
        return false;

    LocalDateTime checkLdt = LocalDateTime.ofInstant(Instant.ofEpochMilli(checkDate.getTime()), ZoneId.systemDefault());
    LocalDateTime startLdt = LocalDateTime.ofInstant(Instant.ofEpochMilli(startDate.getTime()), ZoneId.systemDefault());
    LocalDateTime endLdt = LocalDateTime.ofInstant(Instant.ofEpochMilli(endDate.getTime()), ZoneId.systemDefault());

    // Table of situations:
    // Input dates: start (a), end (b), check (c)
    // Interpretations:
    // t(x) = time of point x on timeline; v(x) = nominal value of x

    // Situation A - crossing midnight:
    // c INSIDE
    //      1) t(a) < t(c) < t(b) | v(b) < v(a) < v(c) // e.g. a=22:00, b=03:00, c=23:00 (before midnight)
    //      2) t(a) < t(c) < t(b) | v(c) < v(b) < v(a) // e.g. a=22:00, b=03:00, c=01:00 (after midnight)
    // c OUTSIDE
    //      3) t(c) < t(a) < t(b) | v(b) < v(c) < v(a) // e.g. a=22:00, b=03:00, c=21:00
    //      4) t(a) < t(b) < t(c) | v(b) < v(c) < v(a) // e.g. a=22:00, b=03:00, c=04:00

    //                              ^--- v(b) < v(a) always when shift spans around midnight!

    // Situation B - after/before midnight:
    // c INSIDE
    //      1) t(a) = t(c) < t(b) | v(a) = v(c) < v(b) // e.g. a=06:00, b=14:00, c=06:00
    //      2) t(a) < t(c) < t(b) | v(a) < v(c) < v(b) // e.g. a=06:00, b=14:00, c=08:00
    // c OUTSIDE
    //      3) t(c) < t(a) < t(b) | v(c) < v(a) < v(b) // e.g. a=06:00, b=14:00, c=05:00
    //      4) t(a) < t(b) = t(c) | v(a) < v(b) = v(c) // e.g. a=06:00, b=14:00, c=14:00
    //      5) t(a) < t(b) < t(c) | v(a) < v(b) < v(c) // e.g. a=06:00, b=14:00, c=15:00

    //                              ^--- v(a) < v(b) if shift starts after midnight and ends before midnight!

    // Check for situation A - crossing midnight?
    boolean crossingMidnight = endLdt.isBefore(startLdt);

    if (crossingMidnight) {
        // A.1
        if ((startLdt.isBefore(checkLdt) || startLdt.isEqual(checkLdt))  // t(a) < t(c)
                && checkLdt.isBefore(endLdt.plusDays(1))) // t(c) < t(b+1D)
            return true;

        // A.2
        if (startLdt.isBefore(checkLdt.plusDays(1))   // t(a) < t(c+1D)
                && checkLdt.isBefore(endLdt)) // t(c) < t(b)
            return true;

        // A.3
        if (startLdt.isBefore(endLdt.plusDays(1))   // t(a) < t(b+1D)
                && checkLdt.isBefore(startLdt)) // t(c) < t(a)
            return false;

        // A.4
        if (startLdt.isBefore(endLdt.plusDays(1))   // t(a) < t(b+1D)
                && checkLdt.isAfter(endLdt)) // t(b) < t(c)
            return false;
    } else {
        // B.1 + B.2
        if ((startLdt.isEqual(checkLdt) || startLdt.isBefore(checkLdt))  // t(a) = t(c) || t(a) < t(c)
                && checkLdt.isBefore(endLdt)) // t(c) < t(b)
            return true;
    }

    return false;
}

为完整起见,我添加了 A.3 和 A.4 的条件,但在生产代码中,您可以将其省略。

现在您可以简单地创建您的开始和结束日期,以及您想要检查和调用此静态方法的时间。 代码将如下所示:

Date check = new SimpleDateFormat("HH:mm:ss").parse("01:00:00");
Date start = new SimpleDateFormat("HH:mm:ss").parse("20:11:13");
Date end = new SimpleDateFormat("HH:mm:ss").parse("14:49:00");

if (isDateBetweenStartAndEndHoursAndMinutes(check, start, end)) {
    Print("checkDate is within start and End date!"); // adjust this true condition to your needs
}

对于 TDD 方面,我为上面给出的场景 A 和 B 添加了单元测试。 如果您发现任何错误或优化点,请随时检查并报告。

import org.junit.jupiter.api.Test;

import java.time.LocalDateTime;
import java.time.ZoneId;
import java.util.Date;

import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;

class LogiqDateUtilsTest  {

    private LocalDateTime startShiftSituationALdt = LocalDateTime.of(0, 1, 1, 22, 0);
    private Date startOfShiftSituationA = Date.from(startShiftSituationALdt.atZone(ZoneId.systemDefault()).toInstant());

    private LocalDateTime endShiftSituationALdt = LocalDateTime.of(0, 1, 1, 3, 0);
    private Date endOfShiftSituationA = Date.from(endShiftSituationALdt.atZone(ZoneId.systemDefault()).toInstant());

    private LocalDateTime startShiftSituationBLdt = LocalDateTime.of(0, 1, 1, 6, 0);
    private Date startOfShiftSituationB = Date.from(startShiftSituationBLdt.atZone(ZoneId.systemDefault()).toInstant());

    private LocalDateTime endShiftSituationBLdt = LocalDateTime.of(0, 1, 1, 14, 0);
    private Date endOfShiftSituationB = Date.from(endShiftSituationBLdt.atZone(ZoneId.systemDefault()).toInstant());

    @Test
    void testSituationA1() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 23, 0);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertTrue(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationA, endOfShiftSituationA));
    }

    @Test
    void testSituationA2() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 1, 0);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertTrue(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationA, endOfShiftSituationA));
    }

    @Test
    void testSituationA3() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 21, 1);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertFalse(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationA, endOfShiftSituationA));
    }

    @Test
    void testSituationA4() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 4, 1);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertFalse(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationA, endOfShiftSituationA));
    }

    @Test
    void testSituationB1() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 6, 0);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertTrue(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationB, endOfShiftSituationB));
    }

    @Test
    void testSituationB2() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 8, 0);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertTrue(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationB, endOfShiftSituationB));
    }

    @Test
    void testSituationB3() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 5, 0);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertFalse(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationB, endOfShiftSituationB));
    }

    @Test
    void testSituationB4() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 14, 0);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertFalse(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationB, endOfShiftSituationB));
    }

    @Test
    void testSituationB5() {
        LocalDateTime checkLdt = LocalDateTime.of(0, 1, 1, 15, 0);
        Date checkBetween = Date.from(checkLdt.atZone(ZoneId.systemDefault()).toInstant());

        assertFalse(isDateBetweenStartAndEndHoursAndMinutes(checkBetween, startOfShiftSituationB, endOfShiftSituationB));
    }
}

干杯!

/**
 * @param initialTime - in format HH:mm:ss
 * @param finalTime   - in format HH:mm:ss
 * @param timeToCheck - in format HH:mm:ss
 * @return initialTime <= timeToCheck < finalTime
 * @throws IllegalArgumentException if passed date with wrong format
 */
public static boolean isTimeBetweenTwoTime(String initialTime, String finalTime, String timeToCheck) throws IllegalArgumentException {
    String reg = "^([0-1][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$";
    if (initialTime.matches(reg) && finalTime.matches(reg) && timeToCheck.matches(reg)) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss", Locale.getDefault());
        Date inTime = parseDate(dateFormat, initialTime);
        Date finTime = parseDate(dateFormat, finalTime);
        Date checkedTime = parseDate(dateFormat, timeToCheck);

        if (finalTime.compareTo(initialTime) < 0) {
            Calendar calendar = Calendar.getInstance();
            calendar.setTime(finTime);
            calendar.add(Calendar.DAY_OF_YEAR, 1);
            finTime = calendar.getTime();
            if (timeToCheck.compareTo(initialTime) < 0) {
                calendar.setTime(checkedTime);
                calendar.add(Calendar.DAY_OF_YEAR, 1);
                checkedTime = calendar.getTime();
            }
        }

        return (checkedTime.after(inTime) || checkedTime.compareTo(inTime) == 0) && checkedTime.before(finTime);
    } else {
        throw new IllegalArgumentException("Not a valid time, expecting HH:MM:SS format");
    }
}

/**
 * @param initialTime - in format HH:mm:ss
 * @param finalTime   - in format HH:mm:ss
 * @return initialTime <= now < finalTime
 * @throws IllegalArgumentException if passed date with wrong format
 */
public static boolean isNowBetweenTwoTime(String initialTime, String finalTime) throws IllegalArgumentException {
    return isTimeBetweenTwoTime(initialTime, finalTime,
            String.valueOf(DateFormat.format("HH:mm:ss", new Date()))
    );
}

private static Date parseDate(SimpleDateFormat dateFormat, String data) {
    try {
        return dateFormat.parse(data);
    } catch (ParseException e) {
        throw new IllegalArgumentException("Not a valid time");
    }
}

这对我有用:

fun timeBetweenInterval(
    openTime: String,
    closeTime: String
): Boolean {
    try {
        val dateFormat = SimpleDateFormat(TIME_FORMAT)
        val afterCalendar = Calendar.getInstance().apply {
            time = dateFormat.parse(openTime)
            add(Calendar.DATE, 1)
        }
        val beforeCalendar = Calendar.getInstance().apply {
            time = dateFormat.parse(closeTime)
            add(Calendar.DATE, 1)
        }

        val current = Calendar.getInstance().apply {
            val localTime = dateFormat.format(timeInMillis)
            time = dateFormat.parse(localTime)
            add(Calendar.DATE, 1)
        }
        return current.time.after(afterCalendar.time) && current.time.before(beforeCalendar.time)
    } catch (e: ParseException) {
        e.printStackTrace()
        return false
    }
}

基于 Konstantin_Yovkov 的回答,我想分享我的实现,它检查当前时间是否在给定的 START 和 END 时间之间。

此实现假设如果给定的 END 时间在 START 时间“之前”,则 END 必须是明天:

public static boolean currentTimeInBetween(String start, String end)
        throws ParseException {
    // start = "15:25";
    java.util.Date starttime = new SimpleDateFormat("HH:mm").parse(start);
    Calendar startcal = Calendar.getInstance();
    startcal.setTime(starttime);

    // end = "14:00";
    java.util.Date endtime = new SimpleDateFormat("HH:mm").parse(end);
    Calendar endcal = Calendar.getInstance();
    endcal.setTime(endtime);

    DateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
    java.util.Date currenttime = dateFormat
            .parse(dateFormat.format(new java.util.Date()));
    Calendar currentcal = Calendar.getInstance();
    currentcal.setTime(currenttime);

    // If endTime < startTime, assume that endTime is 'tomorrow'
    if (startcal.after(endcal)) {
        endcal.add(Calendar.DATE, 1);
    }

    //            System.out.println("START" + " System Date: " + startcal.getTime());
    //            System.out.println("END" + " System Date: " + endcal.getTime());
    //            System.out.println("Current" + " System Date: " + currentcal.getTime());

    java.util.Date current = currentcal.getTime();
    if (current.after(startcal.getTime())
            && current.before(endcal.getTime())) {
        return true;
    } else {
        return false;
    }
}

用 Kotlin 编写的求解函数

/**
  * @param currentTime : Time to compare
  * @param startTime: Start Hour in format like 10:00:00
  * @param endTime: End Hour in format like 15:45:00
  */
fun isTimeInBetweenHours(currentDate: Date, startTime: String, endTime: String): Boolean {
        val simpleDateFormat = SimpleDateFormat("HH:mm:ss", Locale.US)
        try {
            val startTimeCalendar = Calendar.getInstance()
            startTimeCalendar.time = simpleDateFormat.parse(startTime)
            startTimeCalendar.add(Calendar.DATE, 1)
            val endTimeCalendar = Calendar.getInstance()
            endTimeCalendar.time = simpleDateFormat.parse(endTime)
            endTimeCalendar.add(Calendar.DATE, 1)
            val currentTime = simpleDateFormat.format(currentDate) //"01:00:00"
            val currentTimeCalendar = Calendar.getInstance()
            currentTimeCalendar.time = simpleDateFormat.parse(currentTime)
            currentTimeCalendar.add(Calendar.DATE, 1)
            val x = currentTimeCalendar.time
            return x.after(startTimeCalendar.time) && x.before(endTimeCalendar.time)
        } catch (e: ParseException) {
            return false
        }
    }

格式化程序只需要 HH:mm:ss,所以它与日期无关。 所有日期都计算为 1970 年 1 月 1 日作为纪元开始日期。 因此,时间的比较只发生在时间,因为这里所有案例的日期都是 1970 年 1 月 1 日。

注意:使用旧的 Java API 而不是较新的 API(LocalTime 和 DateTimeFormatter),因为这些较新的 API 在旧设备(如 Oreo 版本以下的 Android)上不受支持。 如果您使用其他平台可以获得更新的 API,请使用它们,因为它们更优化且错误更少。

我已经在 kotlin 中实现了它,它按预期工作:

fun isInBetween(startTime: String, endTime: String, checkTime: String, timeFormat: String = "HH:mm:ss"): Boolean {

    val calendar1 = Calendar.getInstance().apply {
        time = SimpleDateFormat(timeFormat, Locale.ENGLISH).parse(startTime)!!
        add(Calendar.DATE, 1)
    }

    val calendar2 = Calendar.getInstance().apply {
        time = SimpleDateFormat(timeFormat, Locale.ENGLISH).parse(endTime)!!
        add(Calendar.DATE, 1)
    }

    val calendar3 = Calendar.getInstance().apply {
        time = SimpleDateFormat(timeFormat, Locale.ENGLISH).parse(checkTime)!!
        add(Calendar.DATE, 1)
    }

    if(calendar1.time > calendar2.time) {
        calendar2.add(Calendar.DATE, 2)
        calendar3.add(Calendar.DATE, 2)
    }

    val x = calendar3.time

    return (x.after(calendar1.time) && x.before(calendar2.time))
}

结果如下:

Log.d("TAG", "08:00, 22:00, 13:40: ${isInBetween("08:00", "22:00", "13:40")}") // true
Log.d("TAG", "22:00, 08:00, 13:40: ${isInBetween("22:00", "08:00", "13:40")}") // false
Log.d("TAG", "22:00, 08:00, 05:40: ${isInBetween("22:00", "08:00", "05:40")}") // true
Log.d("TAG", "22:00, 08:00, 10:40: ${isInBetween("22:00", "08:00", "10:40")}") // false
Log.d("TAG", "22:00, 22:00, 22:10: ${isInBetween("22:00", "22:00", "22:10")}") // false

没有花哨的库的 Kotlin 代码,从午夜计算开始只有几分钟。

    private fun isInBetween(
        startTime: String,
        endTime: String,
        currentTime: String
    ): Boolean {
        val startMinutesSinceMidnight = calculateMinutesSinceMidnight(startTime)
        val endMinutesSinceMidnight = calculateMinutesSinceMidnight(endTime)
        val currentMinutesSinceMidnight = calculateMinutesSinceMidnight(currentTime)
        if (startMinutesSinceMidnight < endMinutesSinceMidnight) {
            return (currentMinutesSinceMidnight >= startMinutesSinceMidnight) && (currentMinutesSinceMidnight < endMinutesSinceMidnight)
        } else {
            return !((currentMinutesSinceMidnight >= endMinutesSinceMidnight) && (currentMinutesSinceMidnight < startMinutesSinceMidnight))
        }
    }

    private fun calculateMinutesSinceMidnight(time_hh_mm: String): Int {
        val timeStrArray = time_hh_mm.split(":")
        var minutes = timeStrArray[1].toInt()
        minutes += 60 * timeStrArray[0].toInt()
        return minutes
    }

这是我的解决方案,适用于 API 21+ 并且我计划将其包含在我的 Google Play 应用程序中:

@SuppressLint("SimpleDateFormat")
public static boolean currentTimeInBetween(long start, long finish) throws ParseException {
    Calendar startTime = Calendar.getInstance();
    startTime.setTimeInMillis(start);

    Calendar finishTime = Calendar.getInstance();
    finishTime.setTimeInMillis(finish);

    // Lets say it's 14:00 now
    Date currentTime = Calendar.getInstance().getTime();

    if (startTime.after(finishTime)) {
        startTime.add(Calendar.DATE, -1);

        if (currentTime.after(startTime.getTime()) && currentTime.before(finishTime.getTime())) {
            // Example: startTime = 23:00, finishTime = 16:00
            Log.d("Utils", "currentTimeInBetween: 1st scenario: startTime was yesterday\n"
                    + "[startTime] " + startTime.getTime() + " >>>>> [currentTime] " + currentTime + " >>>>> [finishTime] " + finishTime.getTime());

            return true;
        }
    }

    if (currentTime.after(startTime.getTime()) && currentTime.before(finishTime.getTime())) {
        // Example: startTime = 10:00, finishTime = 16:00
        Log.d("Utils", "currentTimeInBetween: 2nd scenario: startTime and finishTime are today\n"
                + "[startTime] " + startTime.getTime() + " >>>>> [currentTime] " + currentTime + " >>>>> [finishTime] " + finishTime.getTime());

        return true;
    }

    startTime.add(Calendar.DATE, 1);
    finishTime.add(Calendar.DATE, 1);

    if (currentTime.after(startTime.getTime()) && currentTime.before(finishTime.getTime())) {
        // Example: startTime = 10:00, finishTime = 8:00
        Log.d("Utils", "currentTimeInBetween: 3rd scenario: finishTime is tomorrow\n"
                + "[startTime] " + startTime.getTime() + " >>>>> [currentTime] " + currentTime + " >>>>> [finishTime] " + finishTime.getTime());

        return true;
    } else {
        // Example: startTime = 10:00, finishTime = 12:00
        Log.d("Utils", "currentTimeInBetween: current time is NOT between startTime & finishTime\n"
                + "[startTime] " + startTime.getTime() + " ||||| [currentTime] " + currentTime + " ||||| [finishTime] " + finishTime.getTime());

        return false;
    }
}
LocalTime now = LocalTime.now();
LocalTime startTime = LocalTime.parse("23:00:00");
LocalTime endTime = LocalTime.parse("05:00:00");

        if (startTime.isAfter(endTime)) {
             return !(now.isAfter(endTime) && now.isBefore(startTime));

        } else {
            return (now.isAfter(startTime) && now.isBefore(endTime));
        }

如果 StartTime 来自前一天,EndTime 来自第二天,并且您想要检查两者之间的内容,以下解决方案应该会有所帮助。

    boolean isInBetween = false;
    if (endLocalTime.isAfter(startLocalTime)) {
        if (!startLocalTime.isAfter(checkLocalTime) && endLocalTime.isAfter(checkLocalTime)) {
            isInBetween = true;
        }
    } else if (checkLocalTime.isAfter(startLocalTime) || !checkLocalTime.isAfter(endLocalTime)) {
        isInBetween = true;
    }

    return isInBetween;

}

这是有效的,但需要一些改进。

long timeToSeconds(String time){
    long ret=0;
    String[] ar = time.split("\\:");
    for(int i=0;i < ar.length ; i++){
        ret+= Long.valueOf(ar[i])* Math.pow(60,(2-i)); // (60^(2-i));
    }
    return ret;
}
boolean isTimeBetween(String startTime, String endTime,String currentTime) {
    long lCurrentTime = timeToSeconds(currentTime);
    long lstartTime = timeToSeconds(startTime);
    long lEndTime = timeToSeconds(endTime);

    if(((lstartTime-lCurrentTime)*(lEndTime-lCurrentTime)*(lstartTime-lEndTime))>0){
        return true;
    }else{
        return false;
    }
}

像这样修改你的代码 -

 public void getTimeSpans(){
    boolean firstTime = false, secondTime = false;

    if(isTimeBetween("20:11:13" ,"14:49:00",time1)
    {
        firstTime = true;
    }

    if(isTimeBetween("20:11:13" ,"14:49:00",time2)
    {
        secondTime = true;
    }
}

对不起 sudo 代码..我在打电话。 ;)

between = (time < string2 && time > string1);
if (string1 > string2)  between = !between;

如果它们是时间戳或字符串,这有效。 只需更改变量名称以匹配

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM