web-dev-qa-db-ja.com

Joda-Timeで、DateTimeを月初に設定します。

私のAPIでは、ライブラリクライアントが日付を渡すことができます。

method(Java.util.Date date)

Joda-Time を使用して、この日付から月を抽出し、今月のすべての日を繰り返し処理します。

現在、渡された日付は通常new Date()です-現在の瞬間を意味します。私の問題は実際には、新しいDateMidnight(jdkDate)インスタンスを月の初めに設定することです。

誰かがこのユースケースを Joda-Time で実証してくれませんか?

32
Maxim Veksler

当月の最初の日の真夜中は、次のように指定されます。

// first midnight in this month
DateMidnight first = new DateMidnight().withDayOfMonth(1);

// last midnight in this month
DateMidnight last = first.plusMonths(1).minusDays(1);

Java.util.Dateから開始する場合、別のDateMidnightコンストラクターが使用されます。

// first midnight in Java.util.Date's month
DateMidnight first = new DateMidnight( date ).withDayOfMonth(1);

ジョーダ時間Java doc- https://www.joda.org/joda-time/apidocs/overview-summary.html

44
Lachlan Roche

(DateMidnightを考慮せずに)月の最初の日を取得する別の方法は、次のものを使用することです。

  DateTime firstDayOfMonth = new DateTime().dayOfMonth().withMinimumValue();
31
ngeek

その日の最初の瞬間

answer by ngeek は正しいですが、時間をその日の最初の瞬間に置くことができません。時間を調整するには、 withTimeAtStartOfDay への呼び出しを追加します。

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.

org.joda.time.DateTime startOfThisMonth = new org.joda.time.DateTime().dayOfMonth().withMinimumValue().withTimeAtStartOfDay();
org.joda.time.DateTime startofNextMonth = startOfThisMonth.plusMonths( 1 ).dayOfMonth().withMinimumValue().withTimeAtStartOfDay();

System.out.println( "startOfThisMonth: " + startOfThisMonth );
System.out.println( "startofNextMonth: " + startofNextMonth );

米国シアトルで実行すると…

startOfThisMonth: 2013-11-01T00:00:00.000-07:00
startofNextMonth: 2013-12-01T00:00:00.000-08:00

夏時間 のため、コンソール出力のこれら2行の違いに注意してください:-7 vs -8。


一般に、デフォルトに依存するのではなく、常にタイムゾーンを指定する必要があります。簡略化のため、ここでは省略されています。このような行を追加し、上記の例で使用されているコンストラクターにタイムゾーンオブジェクトを渡す必要があります。

// Time Zone list: http://joda-time.sourceforge.net/timezones.html  (Possibly out-dated, read note on that page)
// UTC time zone (no offset) has a constant, so no need to construct: org.joda.time.DateTimeZone.UTC
org.joda.time.DateTimeZone kolkataTimeZone = org.joda.time.DateTimeZone.forID( "Asia/Kolkata" );

Java.time

上記は正しいですが時代遅れです。 Joda-Timeライブラリは、Java 8以降に組み込まれたJava.timeフレームワークに取って代わられました。

LocalDateは、時刻とタイムゾーンなしの日付のみの値を表します。日付を決定するには、タイムゾーンが重要です。特定の瞬間において、日付は世界中のゾーンによって異なります。

ZoneId zoneId = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( zoneId );

TemporalAdjusters のいずれかを使用して、月の最初を取得します。

LocalDate firstOfMonth = today.with( TemporalAdjusters.firstDayOfMonth() );

LocalDateは、その日の最初の瞬間を表すZonedDateTimeを生成できます。

ZonedDateTime firstMomentOfCurrentMonth = firstOfMonth.atStartOfDay( zoneId );
8
Basil Bourque

ああ、これがjodatimeについてだとは知りませんでした。とにかく:

Calendar c = Calendar.getInstance();
c.setTime(date);
c.set(Calendar.HOUR_OF_DAY, 0);
c.set(Calendar.MINUTE, 0);
c.set(Calendar.SECOND, 0);
c.set(Calendar.MILLISECOND, 0);

int min = c.getActualMinimum(Calendar.DAY_OF_MONTH);
int max = c.getActualMaximum(Calendar.DAY_OF_MONTH);
for (int i = min; i <= max; i++) {
    c.set(Calendar.DAY_OF_MONTH, i);
    System.out.println(c.getTime());
}

またはcommons-langを使用:

Date min = DateUtils.truncate(date, Calendar.MONTH);
Date max = DateUtils.addMonths(min, 1);
for (Date cur = min; cur.before(max); cur = DateUtils.addDays(cur, 1)) {
    System.out.println(cur);
}
5
andi5

DateMidnightは非推奨になりました。代わりに次のことができます:

_LocalDate firstOfMonth = new LocalDate(date).withDayOfMonth(1);
LocalDate lastOfMonth = firstOfMonth.plusMonths(1).minusDays(1);
_

タイムゾーンがわかっている場合は、精度を高めるために代わりにnew LocalDate(date, timeZone)を使用してください。

.dayOfMonth().withMinimumValue()の代わりに.withDayOfMonth(1)を実行することもできます

編集:

これにより、_12/1/YYYY 00:00_および_12/31/YYYY 00:00_が得られます。月末が実際に翌月の最初の月である場合(between句を使用しているため)、lastOfMonth計算からminusDays(1)を削除します

0
JustinKSU