我确信,这样做是1000倍于1000的不同的地方。问题是我想知道如果有一个更好的标准/更快的方式来检查,如果目前的"时间"之间两个时间给出的数值在 hh:mm:ss 格式。例如,我的大业务的逻辑不应该运行之间 18:00:00 and 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");
  }

我正在寻找是代码更好

  • 在绩效
  • 在看起来
  • 在正确性

我不是在寻找

  • 第三方图书馆
  • 例外处理的辩论
  • 变命名约定
  • 方法的改性剂问题
有帮助吗?

解决方案

这是所有你应该需要这样做,这种方法是松散耦合的输入和高度协调一致。

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

你怎么得到的日期的对象为开始和结束是不相关的比较。你做事情的方法复杂得多,需要与过往 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");
    }
}

现在你可以让两个好命名方法的呼吁,这将是相当记录。

其他提示

如指出的,凯文,模糊的棒棒糖的Regex不会挑时间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
}

以下类的东西我刚创建了一些码从其他的答案。它囊括了行为的一个时期没有涉及的具体天。我们的系统是使用这类检查,如果目前的时间内我们的一个指定的维护窗。即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());

    }
}

该dateFromHourMinSec方法是有缺陷的。它不会允许任何个小时,其中的松位数大于3,例如18:00:00.如果你改变它允许[0至2][0-9]它将允许时如29:00:00.有一个修复吗?

tl博士

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。时间

你正在使用的旧日时的课程已被证明是设计不当,造成混淆,并且麻烦。他们现在 遗产, 取代通过java。时间课程。

LocalTime

没有通过仅仅是串的代表每日时间值。我们现在有一种类型说, LocalTime 类。

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

通过这些情况下给你的实用方法。这方法不应该做任何分析,因此不需要把分析例外。

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

ZonedDateTime

一次区域至关重要的是在确定目前的日期和时间的一天。对于任何给定的时刻,日期不同世界各地的区域。例如,几分钟后在午夜 巴黎法国 是新的一天,同时仍然"昨天"在 蒙特利尔魁北克.

指定一个 适当时区名称 在格式 continent/region, 如 America/Montreal, Africa/Casablanca, 或 Pacific/Auckland.永远不会使用的3-4个字母的缩写如 ESTIST 因为他们是 真正的时区,未标准化,甚至不是唯一的(!).

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

比较的时间的日的现在,我们可以简单地提取 LocalTime 从那 ZonedDateTime.但是,我们有问题的异常现象,例如夏令时间(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.的

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

取得的一个实例ZonedDateTime从一个地方的日期和时间。这将创建一个划日期间的匹配输入当地的日期和时间尽可能的。时间-区域规则,如夏令,意思是,不是每个地方的日期时间是有效的指定区,因此当地的日期,时间可能进行调整。

该局的日期和时间的第一个组合,以形成一个当地的日期的时间。地方一日期时间是那么解决的一个即时在时间上线。这是通过找到一个有效的偏离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.

备选办法进行比较是以使用方便的 Interval 类从ThreeTen-额外的项目。这类需要的一个痛苦的 Instant 的对象,你可以从中提取你的 ZonedDateTime 对象。的 Instant 类表示一下时间线 UTC 与决议 毫微秒 (九(9)个数字的十进制分数)。

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

关于java。时间

java。时间 框架是建立成Java8和后。这些类别取代的麻烦老 遗产 日间课程,例如 java.util.Date, Calendar, & SimpleDateFormat.

乔达时 项目,现在 维护模式, 建议迁移到 java。时间 课程。

若要了解更多信息,请参见的 Oracle教程.和搜索堆溢出许多实例和解释。说明书 JSR310.

在那里获得java。时间上课?

ThreeTen-额外的 项目的延伸java。时与附加课程。这个项目是一个试验场于今后可能增加java。时间。你可以找一些有用的类在这里 Interval, YearWeek, YearQuarter, , 更多.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top