12

私はこれが1000の異なる場所で1000回行われたと確信しています。問題は、現在の「時間」が形式で指定された2つの時間値の間にあるかどうかを確認するためのより良い/標準/より速い方法があるかどうかを知りたいということ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");
  }

私が探しているのは、より優れたコードです

  • パフォーマンス
  • ルックスで
  • 正確に

私が探していないもの

  • サードパーティのライブラリ
  • 例外処理の議論
  • 変数の命名規則
  • メソッド修飾子の問題
4

6 に答える 6

23

これがあなたがする必要があるすべてです、この方法は入力から緩く結合されており、非常にコヒーレントです。

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");
    }
}

これで、かなり自己文書化される2つの適切な名前のメソッド呼び出しを行うことができます。

于 2010-03-18T20:15:55.810 に答える
4

Kevinが指摘したように、FuzzyLollipopの正規表現は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
}
于 2010-11-04T13:10:42.303 に答える
4
于 2017-02-13T20:36:18.430 に答える
1

次のクラスは、他の回答のコードの一部から作成したものです。特定の日とは関係なく、「期間」の動作をカプセル化します。私たちのシステムはこのクラスを使用して、現在の時刻が指定されたメンテナンスウィンドウの1つ内にあるかどうかを確認しています。すなわち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());

    }
}
于 2012-04-10T14:56:06.907 に答える
1

真夜中の問題

他の回答はそれについて言及していません-そして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
}

冗長性は必ずしも間違っているわけではありません。このメソッドはユーティリティクラスに埋め込まれ、2年後には、それが何をするのかを理解してくれたことに感謝します。

于 2020-11-20T19:07:32.877 に答える
0

dateFromHourMinSecメソッドには、記述どおりの欠陥があります。2桁目が3より大きい時間、たとえば18:00:00は許可されません。[0-2] [0-9]を許可するように変更すると、29:00:00などの時間が許可されます。その修正はありますか?

于 2010-11-04T12:14:36.793 に答える