31

今日の日に30日を追加すると、今日の日が30になり、20を追加すると追加されるのはなぜですか?

ここにサンプルがあります

import java.text.DateFormat;
import java.util.Date;

public class DatePlus
{

    public static void main(String[] args)
    {
        Date now = new Date();
        Date now1 = new Date();
        Date now2 = new Date();
        DateFormat currentDate = DateFormat.getDateInstance();

        Date addedDate1 = addDays(now2, 20);
        Date addedDate2 = addDays(now1, 30);
        System.out.println(currentDate.format(now));
        System.out.println(currentDate.format(addedDate1));
        System.out.println(currentDate.format(addedDate2));
    }

    public static Date addDays(Date d, int days)
    {
        d.setTime(d.getTime() + days * 1000 * 60 * 60 * 24);
        return d;
    }
}

「これはコンソールです」

Jul 30, 2012
Aug 19, 2012
Jul 10, 2012
4

7 に答える 7

61

カレンダーを使用します。 http://docs.oracle.com/javase/6/docs/api/java/util/GregorianCalendar.html

擬似コード:

Calendar c= Calendar.getInstance();
c.add(Calendar.DATE, 30);
Date d=c.getTime();
于 2012-07-30T19:08:07.687 に答える
35

これは、30 * 1000 * 60 * 60 * 24オーバーフローInteger.MAX_VALUEするのに対し、オーバーフロー20 * 1000 * 60 * 60 * 24しないためです。

于 2012-07-30T19:12:40.173 に答える
20
  1. Date人間が使用するカレンダーシステムとは関係ありません。それは単に特定の時点を表しています。30日を追加しても意味がありません。これは、赤色Dateに20日を追加するようなものです。

  2. 追加の一般的なアプローチ1000 * 60 * 60 * 24は間違っています。86400秒を追加していますが、1日は必ずしも86400秒の長さではありません。により、1時間長くなったり短くなったりする場合があります。うるう秒のため、1秒長くなったり短くなったりする場合があります。

  3. あなたがすべきDateことは、Calendar(実際にはのようなカレンダーシステムを表す)に変換することGregorianCalendarです。次に、単に日を追加します。

    Calendar calendar = new GregorianCalendar(/* remember about timezone! */);
    calendar.setTime(date);
    calendar.add(Calendar.DATE, 30);
    date = calendar.getTime();
    
  4. DateUtils.addDays()Apache Commons Langからの使用:

    DateUtils.add(date, 30);
    

    これは上に書かれたものに違反せず、Calendar下に変換されます。

  5. または、この地獄を完全に避けて、 JodaTimeに行きましょう。

于 2012-07-30T19:09:28.593 に答える
5

daysは整数です。

30 * 1000 * 60 * 60 * 24は2,592,000,000であり、2,147,483,647(Javaで最大のint)よりも大きくなります。バッファオーバーフローが発生し、結果はかなり小さい負の数になります(2進数でチェックし、2の補数としてintに変換し直します)

簡単な修正は、式の結果がlongとして格納されるように、値の1つをキャストすることです。これにより、オーバーフローすることなくその値を保持できます。

 (long) days * 1000L * 60 * 60 * 24

常に推奨されるのは、カレンダーまたは他のAPI(JodaTimeについて聞いたことはありますが、使用していません)を使用して日付を操作することです。

于 2012-07-30T19:15:13.743 に答える
5
于 2016-06-04T08:45:24.900 に答える
4

計算で整数のオーバーフローが発生しています。日数*1000* 60 * 60 * 24の値は、日数= 30の場合は符号付き整数に許可される最大値よりも大きくなりますが、日数=20の場合は許可されません。可能な最大値にある符号付き整数をインクリメントする場合、値が増加する代わりに、符号が反転して負になります!これがあなたの日付が逆行する理由です-あなたはそれに負の数を追加しています。

これを解決するには、次のように、整数よりもはるかに大きい最大値を持つlongデータ型を使用できます。

long secondsToAdd = days;
secondsToAdd *= (1000*60*60*24);
d.setTime(d.getTime() + secondsToAdd);
于 2012-07-30T19:18:57.197 に答える
0

この関数を使用します:

public static String addToCurrentDate(String format,int day,int month,int year){

        DateFormat dateFormat = new SimpleDateFormat(format);

        Calendar calendarInstance = Calendar.getInstance();
        calendarInstance.add(Calendar.YEAR, year);
        calendarInstance.add(Calendar.MONTH, month);
        calendarInstance.add(Calendar.DATE, day);
        return dateFormat.format(calendarInstance.getTime());
    }
于 2019-03-10T15:28:45.977 に答える