tl;dr
GregorianCalendar // Terrible legacy class that should no longer be used.
.from( // Convert from modern *java.time* object to legacy `Calendar` object.
LocalDate // Represent a date only, without time-of-day and without time zone or offset.
.of( 1949 , Month.JANUARY , 24 ) // Instantiate a `LocalDate` for a specific date.
.atStartOfDay( // Determine the first moment of the day. Not necessarily 00:00.
ZoneId.of( "America/Chicago" ) // Specify your desired/expected time zone.
) // Return a modern `ZonedDateTime` object.
.plusDays( 1 ) // Move to the next day, accounting for any adjustments in the time-of-day because of changes to the offset for that time zone such as Daylight Saving Time (DST).
) // Return a legacy `Calendar` object, specifically a `GregorianCalendar` object.
Time zone issue likely
I imagine your issue is due to time zones. A java.util.Date
is a moment in UTC, while a Calendar
object carries a time zone. If you do not specify a time zone, the JVM’s current default time zone is applied implicitly.
java.time
But the issue is moot. You should not be using these terrible date-time classes. They were supplanted years ago by the modern java.time classes defined in JSR 310.
Apparently you want to loop days from 1949-01-24 to 1951-03-24.
LocalDate
For a date-only value, without time-of-day and without time zone, use LocalDate
. Notice the sane year numbers, no subtracting 1900.
LocalDate start = LocalDate.of( 1949 , Month.JANUARY , 24 ) ;
LocalDate stop = LocalDate.of( 1951 , Month.MARCH , 24 ) ;
Use Java streams to get a series of LocalDate
objects.
Stream < LocalDate > dates = start.datesUntil( stop ) ; // Generate a series of `LocalDate` objects.
dates.forEach( System.out::println ) ; // For each `LocalDate` object, call its `println` method to generate text in standard ISO 8601 format for display on the console.
ZonedDateTime
If you meant to include the first moment of the day as a time-of-day as seen in the wall-clock time used by the people of a certain region, specify a time zone to get a ZonedDateTime
.
Do not assume the day starts at 00:00. Some dates in some zones may start at another time such as 01:00. Let java.time determine the first moment by calling LocalDate::atStartOfDay
.
ZoneId z = ZoneId.of( "America/Montreal" ) ;
ZonedDateTime zdtStart = start.atStartOfDay( z ) ;
ZonedDateTime zdtStop = stop.atStartOfDay( z ) ;
Loop, adding a day at a time.
ZonedDateTime zdt = zdtStart ;
while ( zdt.isBefore( zdtStop ) )
{
System.out.println( zdt ) ;
zdt = zdt.plusDays( 1 ) ; // Increment to the next day, taking into account changes in the offset-from-UTC such as Daylight Saving Time (DST).
}
LocalDateTime
cannot represent a moment
If you are trying to track moments, specific points on the timeline, then do not use LocalDateTime
.
java.util.Calendar
If you must use java.util.Calendar
, to interoperate with old code or crusty instructors not yet updated to java.time, convert. To convert, call the new conversion methods added to the old classes.
A ZonedDateTime
object maps to a GregorianCalendar
object, a concrete subclass of the abstract Calendar
.
ZonedDateTime zdt = zdtStart ;
while ( zdt.isBefore( zdtStop ) )
{
Calendar c = GregorianCalendar.from( zdt ) ; // Convert to obsolete terrible legacy class.
zdt = zdt.plusDays( 1 ) ; // Increment to the next day, taking into account changes in the offset-from-UTC such as Daylight Saving Time (DST).
}