2016-12-03 11 views
0

次のように私は方法があります:同じ日内の時間間隔の適切な検証

public void storeAppointment(int year, 
    int monthOfYear, 
    int dayOfMonth, 
    int hourOfDayFrom, 
    int minuteFrom, 
    int hourOfDayUntil, int minuteUntil) { 

    Calendar appointmentCalendar = Calendar.getInstance(); 
    appointmentCalendar.set(year, monthOfYear, dayOfMonth); 
    TimeZone tz = appointmentCalendar.getTimeZone(); 
    DateTimeZone jodaTz = DateTimeZone.forID(tz.getID()); 
    DateTime appointmentDateTime = new DateTime(appointmentCalendar.getTimeInMillis(), jodaTz); 
    LocalDate localDate = appointmentDateTime.toLocalDate(); 

    // At this point I have the appointment date. 

    // Should e.g. throw an exception for invalid time interval 
    validate(hourOfDayFrom, minuteFrom, hourOfDayUntil, minuteUntil); 

    // set proper times for calendar 
    appointmentCalendar.set(Calendar.HOUR, hourOfDay); 
    appointmentCalendar.set(Calendar.MINUTE, minute); 
    // store date and times 
    // Should I update the localDate instead of the appointmentCalendar? 
}  

質問:

  1. 私は時間/分を検証する必要がありますどのように?実際の日付を含めるべきか、それとも関連しないのか?

  2. appointmentCalendarの代わりにlocalDateを更新する必要がありますか?

答えて

2

ここでは非常に難しい作業です。

避けレガシー日時クラス面倒古い日時のクラスを使用して

避け、などDate & Calendar。今や、レガシーはjava.timeクラスに取って代わられています。

は異なる日時のライブラリを混在させないでください日時ライブラリ

を混在させないでください。 Joda-Timeを使用している場合、java.util.Dateの必要はなく、java.util.Calendarの必要はありません。また、java.timeクラスを使用する場合は、Joda-Timeが不要で、java.util.Date/.Calendarの必要はありません。

maintenance modeJoda-Timeプロジェクトは、現在java.timeへの移行を推奨しています。

ビジネスルール

は、実際の日付が含まれるかは関係ないということであるべきか?

日付を考慮するかどうかはわかりません。それはあなたのビジネスルールに依存します。

たとえば、ビジネスが昼休みから午後13時までの昼休みを常に取る場合、その時間帯の時間帯がマークされているビジネスレコードは無効でなければなりません。あなたが毎日同じ昼食を取る場合、ここでは日付は無関係です。

しかし、あなたのシナリオが働いている労働者の期間を記録するようなものなら、同日にの2つの期間は重複しないようにしてください。この場合、日付を考慮する必要があります。

ZonedDateTime

私の代わりにappointmentCalendarのLOCALDATEを更新する必要がありますか?

a)上記のように、これらのクラスを混合しないでください。

b)Joda-Timeとjava.timeの両方で、LocalDateクラスは、時間帯のない日付のみの値を表します。そして、兄弟のLocal…クラスのように、意図的にタイムゾーンの概念がありません。あなたの目的に合ったものではありません。

ZonedDateTimeを使用して、目的のタイムゾーン内で意味を持つ日付と時刻を表す必要があります。

は、America/MontrealAfrica/Casablanca、又はPacific/Aucklandとして、continent/regionの形式でproper time zone nameを指定します。 ESTまたはISTのような3〜4文字の略語は、ではなく、のように、標準化されておらず、ユニークではない(!)と使用しないでください。

ZoneId z = ZoneId.of("America/Montreal"); 
LocalDate ld = LocalDate.of(2016 , 1 , 23); 
LocalTime lt = LocalTime.of(12 , 30); 
ZonedDateTime zdt = ZonedDateTime.of(ld , lt , z); 

現在の瞬間を取得するには、次のショートカットとして...

ZonedDateTime zdt = ZonedDateTime.now(z); 

はまた、java.timeクラスはimmutable objectsあり、

Instant instant = Instant.now(); // UTC. 
ZonedDateTime zdt = instant.atZone(z); 

を...か。だから、彼らの値を変更( "変更")しないでください。代わりに元の値に基づいて新しいオブジェクトをインスタンス化します。

間隔

あなたはここに役立つことがThreeTen-ExtrasプロジェクトでIntervalクラスを見つけることができます。

Interval a = Interval.of(zdtStart.toInstant() , zdtStop.toInstant()); 

あなたは、このようなcontainsoverlapsenclosesisBefore、およびisAfterような方法で間隔を比較することができます。

Boolean overlaps = a.overlaps(b); 

パスが周り

オブジェクトではなく断片的なデータの単なるプリミティブの周りに渡し、オブジェクトを渡します。

月、日、時の整数などのプリミティブを渡す代わりに、Instant,OffsetDateTimeZonedDateTimeなどのjava.timeオブジェクトを渡します。日付または唯一の時刻がある場合は、LocalDateまたはLocalTimeを渡します。

デフォルトのタイムゾーン

JVMの現在のデフォルトのタイムゾーンを取得するには、ZoneId.systemDefaultを呼び出します。

重要な場合は、ユーザーに希望/予想されるタイムゾーンを問い合わせる必要があります。そのデフォルトは、そのJVMで実行されている任意のアプリケーションの任意のスレッドのコードによっていつでも変更できます。

+0

本当に役に立ちました! Calendar.getInstance()。getTimeZone()を使ってジェネリックにしようとしたときに、特定のタイムゾーンをハードコーディングしています。これを置き換えてカレンダーを完全に削除するにはどうすればよいですか? – Jim

+0

@Jim既定のタイムゾーンについては、前のセクションを参照してください。 –