Java 日历跳过第一个月
Java calender skipping first month
我目前正在尝试制作一个 Java 程序,它只打印一年中每一天的日期。除一月份外,它适用于一年中的每个月。谁能建议我可能做错了什么?请在下面找到代码。
String date;
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.DAY_OF_MONTH, 0);
int maxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
int maxMon = cal.getActualMaximum(Calendar.MONTH);
SimpleDateFormat df = new SimpleDateFormat("dd_MM_yy");
for (int j = 0; j < maxMon; j++){
for (int i = 0; i < maxDay; i++) {
cal.set(Calendar.DAY_OF_MONTH , i);
date = df.format(cal.getTime());
System.out.println(date);
}
}
首先,您需要在月循环中获取 int maxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
。
接下来,请记住 MONTH
和 DAY_OF_MONTH
有不同的基础:
MONTH
从 0 开始,因此 maxMon
将是 11。DAY_OF_MONTH
从 1 开始,因此 maxDay
将在 28-31 范围内。
因此,如果您相应地更改循环(从 j = 0
和 i = 1
开始并使用 j <= maxMon
和 i <= maxDay
),您的结果应该没问题。
日历的索引是...特别的。
DAY_OF_MONTH
从 1 开始,MONTH
从 0 开始。 getActualMaximum
returns 实际最大值,也需要包含在循环中。除此之外,您在遍历日历实例时没有更改月份字段。
我冒昧地使您的循环代码更易于理解。
String date;
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.DAY_OF_MONTH, 0);
SimpleDateFormat df = new SimpleDateFormat("dd_MM_yy");
for (int i = 0; i <= cal.getActualMaximum(Calendar.MONTH); i++) {
cal.set(Calendar.MONTH, i);
for (int j = 1; j <= cal.getActualMaximum(Calendar.DAY_OF_MONTH); j++) {
cal.set(Calendar.DAY_OF_MONTH , j);
date = df.format(cal.getTime());
System.out.println(date);
}
}
java.time
现代方法是使用 java.time classes。旧的日期时间 classes 是一团糟、设计不佳、令人困惑和麻烦。
LocalDate
LocalDate
class 表示没有时间和时区的仅日期值。
时区对于确定日期至关重要。对于任何给定时刻,日期在全球范围内因地区而异。例如,Paris France is a new day while still “yesterday” in Montréal Québec.
午夜后几分钟
ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
TemporalAdjuster
TemporalAdjuster
接口提供了 classes 来操作日期时间值。 TemporalAdjusters
class(注意复数 s
)提供了一些方便的实现。
LocalDate firstOfMonth = today.with( TemporalAdjusters.firstDayOfMonth() );
现在循环整个月。获取下个月的第一天作为循环的限制。生成自动本地化为魁北克省的缩写格式的字符串。
LocalDate firstOfNextMonth = today.with( TemporalAdjusters.firstDayOfNextMonth() );
LocalDate ld = firstOfMonth;
Locale locale = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( locale );
System.out.println( ld.getMonth().getDisplayName( TextStyle.FULL , locale ) ); // Print localized name of the month being reported.
do {
System.out.println( ld.format( f ) ); // Create String representing this date.
} while ( ld.isBefore( firstOfNextMonth ) );
octobre
16-10-01
16-10-02
…
参见 code in action。
我目前正在尝试制作一个 Java 程序,它只打印一年中每一天的日期。除一月份外,它适用于一年中的每个月。谁能建议我可能做错了什么?请在下面找到代码。
String date;
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.DAY_OF_MONTH, 0);
int maxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
int maxMon = cal.getActualMaximum(Calendar.MONTH);
SimpleDateFormat df = new SimpleDateFormat("dd_MM_yy");
for (int j = 0; j < maxMon; j++){
for (int i = 0; i < maxDay; i++) {
cal.set(Calendar.DAY_OF_MONTH , i);
date = df.format(cal.getTime());
System.out.println(date);
}
}
首先,您需要在月循环中获取 int maxDay = cal.getActualMaximum(Calendar.DAY_OF_MONTH);
。
接下来,请记住 MONTH
和 DAY_OF_MONTH
有不同的基础:
MONTH
从 0 开始,因此 maxMon
将是 11。DAY_OF_MONTH
从 1 开始,因此 maxDay
将在 28-31 范围内。
因此,如果您相应地更改循环(从 j = 0
和 i = 1
开始并使用 j <= maxMon
和 i <= maxDay
),您的结果应该没问题。
日历的索引是...特别的。
DAY_OF_MONTH
从 1 开始,MONTH
从 0 开始。 getActualMaximum
returns 实际最大值,也需要包含在循环中。除此之外,您在遍历日历实例时没有更改月份字段。
我冒昧地使您的循环代码更易于理解。
String date;
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, 0);
cal.set(Calendar.DAY_OF_MONTH, 0);
SimpleDateFormat df = new SimpleDateFormat("dd_MM_yy");
for (int i = 0; i <= cal.getActualMaximum(Calendar.MONTH); i++) {
cal.set(Calendar.MONTH, i);
for (int j = 1; j <= cal.getActualMaximum(Calendar.DAY_OF_MONTH); j++) {
cal.set(Calendar.DAY_OF_MONTH , j);
date = df.format(cal.getTime());
System.out.println(date);
}
}
java.time
现代方法是使用 java.time classes。旧的日期时间 classes 是一团糟、设计不佳、令人困惑和麻烦。
LocalDate
LocalDate
class 表示没有时间和时区的仅日期值。
时区对于确定日期至关重要。对于任何给定时刻,日期在全球范围内因地区而异。例如,Paris France is a new day while still “yesterday” in Montréal Québec.
午夜后几分钟ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );
TemporalAdjuster
TemporalAdjuster
接口提供了 classes 来操作日期时间值。 TemporalAdjusters
class(注意复数 s
)提供了一些方便的实现。
LocalDate firstOfMonth = today.with( TemporalAdjusters.firstDayOfMonth() );
现在循环整个月。获取下个月的第一天作为循环的限制。生成自动本地化为魁北克省的缩写格式的字符串。
LocalDate firstOfNextMonth = today.with( TemporalAdjusters.firstDayOfNextMonth() );
LocalDate ld = firstOfMonth;
Locale locale = Locale.CANADA_FRENCH ;
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.SHORT ).withLocale( locale );
System.out.println( ld.getMonth().getDisplayName( TextStyle.FULL , locale ) ); // Print localized name of the month being reported.
do {
System.out.println( ld.format( f ) ); // Create String representing this date.
} while ( ld.isBefore( firstOfNextMonth ) );
octobre
16-10-01
16-10-02
…
参见 code in action。