2016-10-05 13 views
0

私は、Androidのアプリケーション用に、イベント登録が次の時間にあるかどうかをチェックするコードを書いています。これを行うために、私は現在の時間を得て、それに60分を追加して、時間スロットの終了時間を取得します。このコードはうまく動作しますが、開始時刻が23:11で終了時刻が00:11の場合は、60分のタイムスロットが翌日にラップすると動作しません。私の日付オブジェクトを調べると、私はAndroidスタジオが私のDateオブジェクトに何らかの日付情報(1月1日)があると言いました。時間情報だけを持つように私の時間形式を指定したので、これは奇妙です。現在の時間がタイムスロットの間であるかどうかをチェック

DateFormat timeFormat = new SimpleDateFormat("hh:mm aa", Locale.ENGLISH); 
    DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss"); 
    DateFormat scanDateFormat = new SimpleDateFormat("yyyy/MM/dd"); 
    //Some logic has been cut out 
    if (currentEventRegistrations.size() > 0) { 
    //We need to check for the earliest events 
    Event earliestEvent = null; //Keep a reference to the earlist event 
    for (int a = 0; a < currentEvents.size(); a++) { 
     Event thisEvent = currentEvents.get(a); 
     if (a == 0) { 
     earliestEvent = thisEvent; 
     } else { 
     Date nextEventDate = timeFormat.parse(thisEvent.getTime()); 
     Date currentEventDate = timeFormat.parse(earliestEvent.getTime()); 
     if (nextEventDate.compareTo(currentEventDate) <= 0) { 
      earliestEvent = thisEvent; 
     } 
     } 
    } 
    //Now that we have the earliest event happening today, we need to check if it is within 30 minutes 
    earliestEvent.setTime(earliestEvent.getTime().toUpperCase()); 
    Date earlyEventDate = timeFormat.parse(earliestEvent.getTime()); 
    Calendar now = Calendar.getInstance(); 
    Date later = now.getTime(); 
    String time = timeFormat.format(later); 
    now.add(Calendar.MINUTE, 60); 
    String timeEnd = timeFormat.format(now.getTime()); 
    Date laterStart = timeFormat.parse(time); 
    Date laterEnd = timeFormat.parse(timeEnd); 
    if (earlyEventDate.compareTo(laterStart) >= 0 && earlyEventDate.compareTo(laterEnd) <= 0) 
    { //If the event is in the next 30 minute time frame, save all the event data 
     finalEvent = earliestEvent; 
     finalEventRegistration = getEventRegistration(earliestEvent.getEventId()); 
     finalRoute = getRoute(finalEventRegistration.getSelectedRoute()); 
     if (finalEvent!= null && finalEventRegistration != null && finalRoute != null) { 
     return true; 
     } else { 
     return false; 
     } 
    } 

時間文字列を時間オブジェクトに変換するにはどうすればよいでしょうか?また、次の日に重複する可能性のある時間枠を扱う最善の方法は何でしょうか?

+1

申し訳ありませんが、単純なタイムスタンプを使用していない理由は何ですか? – user3621165

答えて

1

簡単な方法は、時間を常にミリ秒で保存することです。 (あなたはカレンダーを使用している場合)、すなわち、

long now = System.currentTimeMillis()); 

やイベントを使用して、現在の時刻を取得し、

long eventTime = calendar.getTimeInMillis(); 

を使用し、now + 60*60*1000l > eventTimeかどうかを確認します。

+1

**警告**:このようにすると、夏時間(時間が不足または追加されている場合)の移行中にイベントをスケジュールする際に問題が発生します。これを適切に行うには、ロケールのタイムゾーンとDSTの移行と分をロールインする「カレンダー」を使用して行う必要があります(https://docs.oracle.com/javase/7/docs/api /java/util/GregorianCalendar.html#roll(int,%20int))、タイムスロットの境界線を取得します。 –

1

あなたはあまりにも頑張っているようです。そして、あなたは、古くなった悪名高い古い日時クラスを、java.timeクラスに置き換えて使用しています。

java.timeクラスはjava.time機能の組み込みのJava 8の一部多くは、Java 6 & 7に戻って、移植されたように、第1 ThreeTen-Backportに到着し、さらにThreeTenABPAndroidに適合(How to use…を参照) 。

コードが畳み込まれています。しかし、基本的には、ユーザーからテキストを介して目標日時を収集し、その土地が次の時間内に収まるかどうかを確認したいと考えています。

データ収集

データを収集するための最も簡単な方法は、標準ISO 8601形式で入力するユーザーに確認しています。

String dateInput = "2016-01-23"; 
String timeInput = "20:05:00"; 

java.timeクラスは、日付/時刻値を表す文字列を解析/生成するときにデフォルトで標準形式を使用します。他の形式を使用するには、Java DateTimeFormatterのスタックオーバーフローを検索してください。

はとして「ローカル...」

Local…タイプはに関する情報が不足しているオブジェクトの解析オフセットから、UTCタイムゾーン。

LocalDate ld = LocalDate.parse(dateInput); 
LocalDate lt = LocalTime.parse(timeInput); 
LocalDateTime ldt = LocalDateTime.of(ld , lt); 

このLocalDateTimeオブジェクトは、ない実際の瞬間ではなく、タイムライン上の点です。 UTCからのオフセットまたはタイムゾーンのコンテキストがない場合、この値は実際の意味を持ちません。

ゾーン型

また、その日付と時刻の基準として、ユーザーのタイムゾーンに依頼する必要があります。また、ゾーンを想定したり、JVMの現在のデフォルトタイムゾーンを使用することもできます。詳細については、Java ZoneIdのStack Overflowを検索してください。

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

このゾーンを適用して、LocalDateTimeの意味を理解してください。 ZoneIdを適用して、ZonedDateTime(タイムライン上の実際の瞬間)を取得します。

ZonedDateTime zdt = ldt.atZone(z); 

UTC

は、単純なUTC値にそのZonedDateTimeオブジェクトに変換します。

Instantクラスは、nanoseconds(小数点以下9桁まで)の解像度を持つUTCのタイムライン上の瞬間を表します。

Instant instant = zdt.toInstant(); 

現在の瞬間を取得します。

Instant now = Instant.now(); 

時間後に取得します。あなたは彼らの希望/期待の時間帯でユーザにその制限時間を表示する必要がある場合は、あなたがZoneIdを適用することにより、InstantからZonedDateTimeに変換することができます

Instant later = now.plus(1 , ChronoUnit.HOURS); 

toStringに電話するか、またはDateTimeFormatterを使用してプレゼンテーション用の文字列を生成します。

ZonedDateTime zdtNow = now.atZone(z); 
ZonedDateTime zdtLater = later.atZone(z); 

が半開きのアプローチを使用して

を比較、あなたの目標時間( instantが)への以降エンディング( later)より始まり( now)以前よりも等しいかどうか尋ねます。 「等しいかそれより後ろ」という短い方法は「前にない」ことです。

Boolean isTargetWithinTimeFrame = 
    (! instant.isBefore(now)) 
    && 
    instant.isBefore(later) 
; 

ハーフオープンアプローチのロジックについては、search Stack Overflow for java time Half-Openを参照してください。

ThreeTen-Extraプロジェクトで提供されているIntervalクラスを使用するとさらに簡単です。 java.timeについて

Interval interval = Interval.of(now , later); 
Boolean isTargetWithinTimeFrame = interval.contains(instant); 

java.timeフレームワークは、Java 8に組み込まれており、後にされています。これらのクラスは、このようなjava.util.Date.Calendar、& java.text.SimpleDateFormatなど面倒な古い日付時刻クラスに取って代わります。

Joda-Timeプロジェクトは、今maintenance modeで、java.timeへの移行をアドバイスします。

詳しくはOracle Tutorialをご覧ください。そして、多くの例と説明のためにStack Overflowを検索してください。

ここで、java.timeクラスを取得するには?

  • Java SE 8SE 9以降
    • 内蔵しています。
    • バンドルされた実装の標準Java APIの一部です。
    • Java 9には、いくつかのマイナーな機能と修正が加えられています。
  • Java SE 6SE 7
    • java.time機能の多くは、ThreeTen-BackportのJava 6 & 7に戻って、移植されます。
  • Android
    • ThreeTenABPプロジェクトは、具体的にはAndroid用(上記)ThreeTen-バックポートを適応させます。
    • How to use…を参照してください。

ThreeTen-Extraプロジェクトでは、追加のクラスでjava.timeを拡張します。このプロジェクトは、将来のjava.timeへの追加の可能性を証明する土台です。ここでは、IntervalYearWeekYearQuartermoreなどの便利なクラスがあります。

+1

良いとダンディ、しかし...あなたは質問に "アンドロイド"タグが気づいたのですか?現在のところ、[Android API](https://developer.android.com/reference/packages.html)に 'java.time'のサポートはありません –

+0

@AdrianColomitchi私の中で最後から2番目の段落に気がつきましたか?回答? –

+0

明らかに、私はしませんでした。それを調整し、それをあなたの答えの最初の段落として動かすことをお勧めしますか? –

関連する問題