2016-07-15 6 views
0

カレンダーオブジェクトインスタンスである時間の差を取得したいと考えています。何らかの理由で、この機能を使用するときに負数(-17666324.42)が表示されます。 ミリ秒の変換からの時間の表示が正しく表示されない

はovertimeHourLimitのために私は8

/*Date*/ 
Calendar mDateIn = Calendar.getInstance(); 
Calendar mDateOut = Calendar.getInstance(); 
mDateOut.set(mDateOut.YEAR, mDateOut.MONTH, mDateOut.DAY_OF_MONTH, mDateOut.HOUR_OF_DAY+10, mDateOut.MINUTE+25); 

public String getRegHours(float overtimeHourLimit) 
{ 
    DecimalFormat twoDecimal = new DecimalFormat("0.##"); 
    double totalHours = 0; 
    totalHours = (mDateOut.getTimeInMillis() - mDateIn.getTimeInMillis())/(3.6f * Math.pow(10, 6)); 
    if (totalHours <= overtimeHourLimit) 
     return twoDecimal.format(totalHours); 
    else return twoDecimal.format(overtimeHourLimit); 
} 

編集の値を使用する:mDateOut.set()メソッドにそれを絞り込みます。 @HarshPandeyは、代わりにmDateOut.add()メソッドを使用すると、時間に正しく追加されていることを発見しました。しかし、私はまだ.set()メソッドが最初にうまくいかなかった理由について、まだ悩まされています。

edit2:https://github.com/MienTommy/CalendarTestこの質問のコードスニペットに相当するサンプルコードをプッシュしました。唯一の違いは、YEAR、MONTH、DAY_OF_MONTHの定数はAndroidでは静的ではありませんが、同じインスタンスで初期化してから違いはありません。

tl; dr .set()メソッドが期待どおりに機能していません。

+0

負の数値(-17666324.42)を取得したときの入力は何ですか? –

+0

dateInとCalendar.getInstance()にCalendar.getInstance()を使用していて、dateOutに10時間25分を追加しています。 –

+0

あなたはカレンダー –

答えて

2

問題の理由はここにある1970年1月1日0時00分00秒

てからの時間:

getTimeInMillis()は、エポックを得ています

この方法:

mDateOut.set()...

カレンダーフィールドYEAR、MONTH、DAY_OF_MONTH、HOUR_OF_DAY、およびMINUTEの値を設定します。検討カレンダーのインスタンスで....

いますが、以前の値に日付を設定しているので、あなた00:00:00

1970年1月1にパラメータとしてクラスカレンダーの定数を渡していますこれを行うこと:

mDateOut.set(mDateOut.YEAR, mDateOut.MONTH, mDateOut.DAY_OF_MONTH, mDateOut.HOUR_OF_DAY + 10, 
     mDateOut.MINUTE + 25); 

これを行うことと同じです。

mDateOut.set(1, 2, 5, 21, 37); 

あなたが実行して、新しい値を確認することができます。

System.out.println(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(mDateOut.getTime())); 

を、あなたが出力として取得します:

0001-03-05 21:37:40

のでmDateOutが実際にwaaaaay戻って過去の日付です...

結果がマイナス:

+0

意味があるので、set()メソッドを使う正しい方法は何ですか? –

+0

実際の日付が必要な場合は、 dはカレンダーを使用する...ちょうどjava.utl.dateの新しいインスタンスを作成し、実際の時刻を取得する場合.... –

1

この試してみてください。私たちの議論から

long seconds = (mDateOut.getTimeInMillis() - mDateIn.getTimeInMillis())/1000; 
double totalHours = (int) (seconds/3600); 

を、それが正常に動作し

mDateOut.add(Calendar.HOUR, 10) 
mDateOut.add(Calendar.MINUTE, 25) 
のように思えます。

set()メソッドを使って時間を設定することはできますが、複雑な時間計算を行うことはできず、それを使って時間を設定することができます。その計算はadd()メソッドで完全に処理されます。説明のため

mDateOut.set(mDateOut.YEAR, mDateOut.MONTH, mDateOut.DAY_OF_MONTH, mDateOut.HOUR_OF_DAY + 10, 
    mDateOut.MINUTE + 25); 

+0

運がない、同じ出力(-17666324)が小数点が切り捨てられました。 –

+0

なぜ変数名が異なっていますか? 'dateIn'と' dateOut'を作成していますが、 'mDateOut'と' mDateIn'を使っています。あなたはそれらを別の方法に回していますか? –

+0

私は、必要な情報だけをスニペットで提供しようとしていました。 mDateInとdateInは、mDateOutとdateOutと同じにする必要があります。 –

0

他の回答は正しいです。しかし、この作業を混乱させ、必要以上に困難にする、時代遅れのクラスを使用しています。

java.time

java.timeフレームワークは、Java 8に内蔵以降れます。これらのクラスは、java.util.Date.Calendar、& java.text.SimpleDateFormatなどの古い面倒な日時クラスに取って代わります。

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

java.timeの機能の多くは、Java 6 & 7のThreeTen-Backportにバックポートされ、さらにThreeTenABPのAndroidに適合しています。

タイムゾーン

タイムゾーンが重要です。希望/期待時間帯を指定しないと、JVMのタイムゾーンが暗黙的に適用されます。そのデフォルトはいつでも変更される可能性があります。だから私はあなたが常に指定することをお勧めします。

Instant

代わりの.Calendar、あなたはUTCを必要とするときに、タイムゾーンとInstantを必要とするときZonedDateTimeを使用しています。一般的には、ほとんどのビジネスロジック、ストレージ、およびデータ交換にUTCを使用することをお勧めします。

Instant now = Instant.now(); 
Instant later = … ; 

Duration

Durationクラスは、時間、分、秒で経過時間をキャプチャします。

BigDecimal

Duration duration = Duration.between(now , later); 
Duration overtimeLimit = Duration.ofHours(8); 
Boolean overtime = (duration.compareTo(overtimeLimit) > 0); 

時間の小数を得るために、私は doubleを避けることをお勧めします。 floating-pointの番号では、そのタイプは速度の精度を犠牲にしています。

代わりに、小数点の右側の誤った余分な数字を避けるためにBigDecimalを使用してください。スケールは、小数点以下の桁数です。 RoundingModeは、あなたが小学校で教える可能性のある「スクールハウス」丸めなど、より大きな数字への偏りを持つような丸めアプローチの種類を決定します。“Bankers rounding”HALF_EVEN)等距離のときに偶数に丸めることでより公平です。

マジックナンバーをハードコードするのではなく、TimeUnitを使用してコードを自己文書化しながら計算します。

int scale = 2 ; // Decimal places to right of decimal point. 
BigDecimal minutesInAnHour = BigDecimal.valueOf(TimeUnit.HOURS.toMinutes(1) , scale) ; 
BigDecimal totalMinutes = BigDecimal.valueOf(duration.toMinutes() , scale) ; // Calling `toMinutes` truncates any seconds and fractions of second that might be in the duration. 
BigDecimal worked = totalMinutes.divide(minutesInAnHour , scale , RoundingMode.HALF_EVEN) ; 
関連する問題