3

こんにちは、私は何か奇妙なことが起こっています。単純に、カレンダー オブジェクトを取得し、それを個々の部分に変換して、カレンダーに戻します (変更の有無にかかわらず。この場合は変更しません)。つまり、これはカットアンドペーストする必要があります。また、 calendar = Calendar.getInstance() を使用してカレンダーを作成し、すべてを手動で設定しようとしました。calendar.set(Calendar.YEAR, mStartYear); すぐ。それでも間違った Calendar オブジェクトが返されます。ミリ秒も設定しようとしましたが、常にガベージミリ秒があるようです..しかし、何らかの方法で時間は完全にずれています。誰かが愚かな見落としに気付くかもしれませんが、私は困惑しています。

また、これは Android アプリケーションですが、基本的な Java ライブラリ オブジェクトには関係ありません。

注: Weekview は、私が使用しているライブラリの 1 つのデータラッパーです。開始カレンダーと終了カレンダーがあります。

デバッガーがメモリ内にリストするものは次のとおりです。

mEndDay = 19
mEndHour = 9

mEndMinute = 30
mEndMonth = 8
mEndYear = 2015
mSeekAmount = 0
mStartDay = 18
mStartHour = 23
mStartMinute = 0
mStartMonth = 8
mStartYear = 2015


            Calendar calendarStart = Calendar.getInstance();
            calendarStart.set(mStartYear,mStartMonth,mStartDay,mStartHour,mStartMinute);

            Calendar calendarEnd = Calendar.getInstance();
            calendarEnd.set(mEndYear,mEndMonth,mEndDay,mEndHour,mEndMinute);

私はで終わる

Start 1442363359161
End 1442363359161

calendarStart = {GregorianCalendar@20968} "java.util.GregorianCalendar[time=?,areFieldsSet=false,lenient=true,zone=America/Denver,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=8,WEEK_OF_YEAR=38,WEEK_OF_MONTH=3,DAY_OF_MONTH=18,DAY_OF_YEAR=258,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=6,HOUR_OF_DAY=23,MINUTE=0,SECOND=19,MILLISECOND=161,ZONE_OFFSET=-25200000,DST_OFFSET=3600000]"
calendarEnd = {GregorianCalendar@20969} "java.util.GregorianCalendar[time=?,areFieldsSet=false,lenient=true,zone=America/Denver,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=8,WEEK_OF_YEAR=38,WEEK_OF_MONTH=3,DAY_OF_MONTH=19,DAY_OF_YEAR=258,DAY_OF_WEEK=3,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=6,HOUR_OF_DAY=9,MINUTE=30,SECOND=19,MILLISECOND=161,ZONE_OFFSET=-25200000,DST_OFFSET=3600000]"

予想

Start 1442638800000
End 1442676600000

mEndTime = {GregorianCalendar@20990} "java.util.GregorianCalendar[time=1442676600000,areFieldsSet=true,lenient=true,zone=America/Denver,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=8,WEEK_OF_YEAR=38,WEEK_OF_MONTH=3,DAY_OF_MONTH=19,DAY_OF_YEAR=262,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=3,AM_PM=0,HOUR=9,HOUR_OF_DAY=9,MINUTE=30,SECOND=0,MILLISECOND=0,ZONE_OFFSET=-25200000,DST_OFFSET=3600000]"
mName = {String@20991} "sleep"
mStartTime = {GregorianCalendar@20992} "java.util.GregorianCalendar[time=1442638800000,areFieldsSet=true,lenient=true,zone=America/Denver,firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=8,WEEK_OF_YEAR=38,WEEK_OF_MONTH=3,DAY_OF_MONTH=18,DAY_OF_YEAR=261,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=11,HOUR_OF_DAY=23,MINUTE=0,SECOND=0,MILLISECOND=0,ZONE_OFFSET=-25200000,DST_OFFSET=3600000]"

最初に設定した場所はここです..

   WeekViewEvent weekViewEvent = dateWrapperParam.getWeekViewEvent();
    Calendar endCalendar = weekViewEvent.getEndTime();
    Calendar startCalendar = weekViewEvent.getStartTime();

    Date endDate = endCalendar.getTime();
    Date startDate = startCalendar.getTime();

    mStartHour = startCalendar.get(Calendar.HOUR_OF_DAY);
    mStartMinute = startCalendar.get(Calendar.MINUTE);
    mStartDay = startCalendar.get(Calendar.DAY_OF_MONTH);
    mStartMonth = startCalendar.get(Calendar.MONTH);
    mStartYear = startCalendar.get(Calendar.YEAR);

    mEndHour = endCalendar.get(Calendar.HOUR_OF_DAY);
    mEndMinute = endCalendar.get(Calendar.MINUTE);
    mEndDay = endCalendar.get(Calendar.DAY_OF_MONTH);
    mEndMonth = endCalendar.get(Calendar.MONTH);
    mEndYear = endCalendar.get(Calendar.YEAR);
4

4 に答える 4

0

Calendar オブジェクトを初期化すると、現在の秒とミリ秒を含む現在の時刻が取得されます。提供されたコードは時間と分を設定しますが、秒とミリ秒は設定せず、Calendar オブジェクトが初期化されたときのままにします。秒とナノ秒をゼロに設定するには、次を使用します。

StartCalendar.set(Year, Month, DayofMonth, Hour, Minute, 0,0);
于 2020-10-08T00:49:07.163 に答える
0

あなたの質問の下の私のコメントによると、値がリセットされていないため、時間startCalendarと時間の間には秒とミリ秒の違いしかありません。calendarStart

デモを見る

于 2015-09-18T23:08:01.110 に答える
0

java.time と ThreeTenABP

日付と時刻の作業には、Java の最新の日付と時刻 API である java.time を使用することをお勧めします。例えば:

    ZonedDateTime start = ZonedDateTime.now(ZoneId.systemDefault());
    ZonedDateTime end = start;
    
    System.out.println("Start: " + start);
    System.out.println("End:   " + end);

ちょうど今自分のタイムゾーンでコードを実行したときの出力:

Start: 2020-06-24T19:24:04.811+02:00[Europe/Copenhagen]
End:   2020-06-24T19:24:04.811+02:00[Europe/Copenhagen]

AZonedDateTimeは、あるタイム ゾーンの日付と時刻です。これは、(コードが提供しGregorianCalendarたサブクラス) に相当するものに最も近いものです。Calendarどの最新クラスを使用するかは、より正確な要件によって異なります。そのため、たとえばLocalDateや.OffsetDateTimeLocalTime

値を分単位で切り捨てるには (秒と秒の端数を 0 に設定):

    ZonedDateTime start = ZonedDateTime.now(ZoneId.systemDefault())
            .truncatedTo(ChronoUnit.MINUTES);
Start: 2020-06-24T19:24+02:00[Europe/Copenhagen]

ZonedDateTimeおよび java.time の他のクラスは、取得した値を変更する方法を多数提供しています。例えば:

    ZonedDateTime end = start.plusDays(2).withHour(13);
End:   2020-06-26T13:24+02:00[Europe/Copenhagen]

開始時刻から選択したフィールドのみを使用して手動で終了時刻を作成する場合:

    ZonedDateTime end = ZonedDateTime.of(
            2021, start.getMonthValue(), start.getDayOfMonth(),
            start.getHour(), 30, 0, 0, start.getZone());
End:   2021-06-24T19:30+02:00[Europe/Copenhagen]

コードで何が問題になったのですか?

答えの一部はすでに他の答えにあります。設定することを約束するフィールドのみを設定し、可能な限り他のフィールドを変更しないset方法。Calendarこれはおそらくメソッドから予想されますが、set​(int field, int value)メソッドで驚かされることが多く、とset​(int year, int month, int date)でさらに驚かされます。一般に、クラスとそのサブクラスは適切に意図されていますが、設計が不十分で混乱を招き、操作が面倒です。これが、上記の java.time を推奨する主な理由です。set​(int year, int month, int date, int hourOfDay, int minute)set​(int year, int month, int date, int hourOfDay, int minute, int second)Calendar

答えの他の部分は、Calendarそのフィールドを寛大に計算することです。Calendarそのため、を呼び出した後にデバッガーでオブジェクトを見るとset、大量のガベージ値が含まれています。を呼び出すと、そのフィールドを計算するようにgetTime()強制Calendarされるため、その後、デバッガーでの表示方法がより理にかなっているはずです。これも紛らわしい動作であり、デバッガを使用しなくても観察できる場合もあります。

質問: java.time は Android API レベル 26 を必要としませんか?

java.time は、古い Android デバイスでも新しい Android デバイスでもうまく機能します。少なくともJava 6が必要です。

  • Java 8 以降および新しい Android デバイス (API レベル 26 以降) では、最新の API が組み込まれています。
  • Android 以外の Java 6 および 7 では、最新のクラスのバックポートである ThreeTen Backport を取得します (JSR 310 用の ThreeTen。下部のリンクを参照してください)。
  • (古い) Android では、ThreeTen Backport の Android 版を使用します。それは ThreeTenABP と呼ばれます。org.threeten.bpまた、サブパッケージを使用して日付と時刻のクラスをインポートしてください。

リンク

于 2020-06-24T17:27:25.760 に答える