Java.util.Date(カレンダーやグレゴリオ暦などではない)のみを認識するJasper Reportsで作成されたレポートがあります。
現在の日付の7日前に日付を作成する方法はありますか?
理想的には、次のようになります。
new Date(New Date() - 7)
更新:これを十分に強調することはできません:JasperReportsは認識できませんJava Calendarオブジェクト。
まさに今から:
long DAY_IN_MS = 1000 * 60 * 60 * 24;
new Date(System.currentTimeMillis() - (7 * DAY_IN_MS))
任意のDate date
から:
new Date(date.getTime() - (7 * DAY_IN_MS))
編集:他の回答で指摘したように、それが要因である場合、夏時間を考慮しません。
私が話していたその制限を明確にするために:
夏時間の影響を受ける人々の場合、7 days earlier
の場合、今が12pm noon on 14 Mar 2010
、7 days earlier
の計算結果が12pm on 7 Mar 2010
になるようにするには、注意してください。
このソリューションは、正確に24時間* 7日= 168時間前の日付/時刻を検出します。
ただし、一部の人々は驚いたこのソリューションがそれを見つけたとき、たとえば(14 Mar 2010 1:00pm) - 7 * DAY_IN_MS
may結果を返す_(7 Mar 2010 12:00pm)
ここで、タイムゾーンのwall-clock timeは同じではありません2つの日付/時刻の間(1pm
vs 12pm
)。これは、その夜に開始または終了する夏時間と、1時間を増減する「壁時計時間」によるものです。
DSTがあなたにとっての要因ではない場合、または(168 hours)
が本当に必要な場合(実時間のシフトに関係なく)、この解決策はうまく機能します。
それ以外の場合、7 days earlier
が実際に正確に168時間を意味しない場合(その期間内にDSTが開始または終了するため)を補正する必要があります。
カレンダーの機能を使用して、getTime()
を使用して新しいDateオブジェクトを作成します。
import Java.util.GregorianCalendar;
import Java.util.Date;
Calendar cal = new GregorianCalendar();
cal.add(Calendar.DAY_OF_MONTH, -7);
Date sevenDaysAgo = cal.getTime();
試してみる
Date sevenDay = new Date(System.currentTimeMillis() - 7L * 24 * 3600 * 1000));
もう1つの方法は、カレンダーを使用することですが、自分で使用するのは好きではありません。
まだ誰もTimeUnit
に言及していないので:
new Date(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7))
これを試して:
Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_MONTH, -7);
return c.getTime();
彼らがこれらをいつ追加したかはわかりませんが、JasperReportsには日付を操作できる独自の「関数」のセットがあります。完全にテストしていない例を次に示します。
_DATE(YEAR(TODAY()), MONTH(TODAY()), DAY(TODAY()) - 7)
_
これにより、今日から7日後に日付が設定された_Java.util.Date
_が作成されます。別の「アンカー」日付を使用する場合は、TODAY()
を使用する日付に置き換えてください。
「日」を決定するには、タイムゾーンが必要です。タイムゾーンは、「日」がいつ始まるかを定義します。タイムゾーンには、夏時間やその他の異常を処理するためのルールが含まれています。タイムゾーンを無関係にする魔法はありません。問題を無視すると、JVMのデフォルトのタイムゾーンが適用されます。これは混乱と痛みにつながる傾向があります。
Java.util.Dateおよび.Calendarクラスは厄介なことで有名です。それらを避けてください。それらは非常に悪いため、Sun/Oracleは新しい Java.timeパッケージ in Java 8.を使用するか、または Joda-Time 。
Joda-Time 2.3のサンプルコード。
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Paris" ); // Specify or else the JVM's default will apply.
DateTime dateTime = new DateTime( new Java.util.Date(), timeZone ); // Simulate passing a Date.
DateTime weekAgo = dateTime.minusDays( 7 );
または、時刻を1日の最初の瞬間に合わせて、1日分の時間をキャプチャすることもできます。メソッドwithTimeAtStartOfDay
を呼び出します。これは通常00:00:00
しかしいつもではない。
Joda-Timeの「真夜中」のメソッドとクラスを避けてください。それらは誤った概念に基づいており、現在では非推奨です。
DateTime dateTimeStart = new DateTime( new Java.util.Date(), timeZone ).withTimeAtStartOfDay(); // Not necessarily the time "00:00:00".
DateTime weekAgo = dateTime.minusDays( 7 ).withTimeAtStartOfDay();
上記のように、Java.util.DateからJoda-Timeに変換するには、DateオブジェクトをDateTimeのコンストラクターに渡すだけです。 j.u.Dateにはタイムゾーンがないこと、DateTimeにはあることを理解してください。そのため、「日」が何であり、いつ開始するかを決定するために、適切なタイムゾーンを割り当てます。
逆に、DateTimeをj.u.Dateにするには、toDate
メソッドを呼び出します。
Java.util.Date date = dateTime.toDate();
白熱した議論のため:
質問には、指定されたタイムゾーンなしで適切な回答がない場合があります。
以下は、デフォルトのタイムゾーン夏時間を考慮に入れたデフォルトのタイムゾーンで動作するコードです。
Date date= new Date();
date.setDate(date.getDate()-7);//date works as calendar w/ negatives
解決策は機能しますが、タイムゾーンを仮定するという点でまったく同じです。
new Date(System.currentTimeMillis() - 10080*60000);//a week has 10080 minutes
答えに投票しないでください。
Java 8ベースのソリューション:
new Date(Instant.now().minus(7, ChronoUnit.DAYS).toEpochMilli()))
私はこのようにやっています:
Date oneWeekAgo = DateUtils.addDays(DateUtils.truncate(new Date(), Java.util.Calendar.DAY_OF_MONTH), -7);
これを試すことができます、
Calendar c = Calendar.getInstance();
c.add(Calendar.DAY_OF_MONTH, -7);
System.out.println(new Java.sql.Date(c.getTimeInMillis()));