开发者

In Joda-Time, set DateTime to start of month

开发者 https://www.devze.com 2022-12-19 23:06 出处:网络
My API allows library client to pass Date: method(java.util.Date date) Working with Joda-Time, from this date I would like to extract the month and iterate over all days this month contains.

My API allows library client to pass Date:

method(java.util.Date date)

Working with Joda-Time, from this date I would like to extract the month and iterate over all days this month contains.

Now, the passed date is usually new Date(开发者_StackOverflow) - meaning current instant. My problem actually is setting the new DateMidnight(jdkDate) instance to be at the start of the month.

Could someone please demonstrates this use case with Joda-Time?


Midnight at the start of the first day of the current month is given by:

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

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

If starting from a java.util.Date, a different DateMidnight constructor is used:

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

Joda Time java doc - https://www.joda.org/joda-time/apidocs/overview-summary.html


An alternative way (without taking DateMidnight into account) to get the first day of the month would be to use:

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


First Moment Of The Day

The answer by ngeek is correct, but fails to put the time to the first moment of the day. To adjust the time, append a call to 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 );

When run in Seattle US…

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

Note the difference in those two lines of console output: -7 vs -8 because of Daylight Saving Time.


Generally one should always specify the time zone rather than rely on default. Omitted here for simplicity. One should add a line like this, and pass the time zone object to the constructors used in example above.

// 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

The above is correct but outdated. The Joda-Time library is now supplanted by the java.time framework built into Java 8 and later.

The LocalDate represents a date-only value without time-of-day and without time zone. A time zone is crucial in determine a date. For any given moment the date varies by zone around the globe.

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

Use one of the TemporalAdjusters to get first of month.

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

The LocalDate can generate a ZonedDateTime that represents the first moment of the day.

ZonedDateTime firstMomentOfCurrentMonth = firstOfMonth.atStartOfDay( zoneId );


Oh, I did not see that this was about jodatime. Anyway:

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());
}

Or using 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);
}


DateMidnight is now deprecated. Instead you can do:

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

If you know the time zone use new LocalDate(date, timeZone) instead for greater accuracy.

You can also do .dayOfMonth().withMinimumValue() instead of .withDayOfMonth(1)

EDIT:

This will give you 12/1/YYYY 00:00 and 12/31/YYYY 00:00. If you rather the last of the month be actually the first of the next month (because you are doing a between clause), then remove the minusDays(1) from the lastOfMonth calculation


You can get Start date and end date of month using this:

DateTime monthStartDate = new DateTime().dayOfMonth().withMinimumValue();
DateTime monthEndDate = new DateTime().dayOfMonth().withMaximumValue();
                        
0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号