The Answer by Adam is correct and should be accepted.
It mentions that you should be (really should be) using the modern java.time classes rather than the troublesome old legacy date-time classes. Here is a version of Adam's code adapted to the java.time classes.
Also, time zone is crucial in determining a date like first of month. For any given moment, the date varies around the globe by zone. For example, a new day dawns earlier in Auckland NZ than Montréal Québec. If omitted, your JVM implicitly applies its current default time zone. That default can change at any moment during runtime. Better to specify explicitly.
Instant
The Instant
class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).
ZonedDateTime
This Instant
class is a basic building-block class of java.time. You can think of OffsetDateTime
as an Instant
plus a ZoneOffset
. Likewise, you can think of ZonedDateTime
as an Instant
plus a ZoneId
.
If you care only about the date and not the time-of-day, use LocalDate
class.
TemporalAdjuster
The TemporalAdjuster
interface defines classes for manipulating date-time values such as getting first-of-month. The TemporalAdjusters
class (note the plural 's') provides implementations such as firstDayOfMonth
.
public static ZonedDateTime getFirstOfLastMonth( ZoneId z ) {
Instant instant = Instant.now();
return getFirstOfPreviousMonth( instant , z );
}
public static ZonedDateTime getFirstOfPreviousMonth( Instant instantArg , ZoneId zoneArg ) {
ZonedDateTime zdt = instantArg.atZone( zoneArg);
ZonedDateTime firstOfMonthZdt = zdt.with( TemporalAdjusters.firstDayOfMonth() );
ZonedDateTime firstOfMonthPriorZdt = firstOfMonthZdt.minusMonths( 1 );
return firstOfMonthPriorZdt;
}
Clock
You can pass a special Clock
implementation for testing rather than use by default the real-life-time clock implementation. That clock offers static methods to generate several such alternate implementations.
For example, the fixed
implementation always supplies the same frozen moment in time. Let's say you wanted the clock to always report the first moment of March 21, 2017 in Québec time.
LocalDate ld = LocalDate.of( 2017 , Month.MARCH , 21 );
ZoneId z = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ld.atStartOfDay( z ); // Let java.time determine first moment of the day. Not always `00:00:00`.
Instant instant = zdt.toInstant();
Clock c = Clock.fixed( instant , z );
// Pass this clock `c` in your calls to various java.time methods.
About java.time
The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date
, Calendar
, & SimpleDateFormat
.
The Joda-Time project, now in maintenance mode, advises migration to java.time.
To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.
Where to obtain the java.time classes?
- Java SE 8 and SE 9 and later
- Built-in.
- Part of the standard Java API with a bundled implementation.
- Java 9 adds some minor features and fixes.
- Java SE 6 and SE 7
- Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
- Android
The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval
, YearWeek
, YearQuarter
, and more.