如何使用带有 Calendar 对象的 AM PM 设置正确的时间?
How to set correct time with AM PM with Calendar object?
简单的问题,为什么这段代码的结果如下:
Calendar cal2 = Calendar.getInstance();
cal2.set(Calendar.HOUR, 12);
cal2.set(Calendar.AM_PM, Calendar.PM);
System.out.println(cal2.getTime().toString()); // Wed Jan 13 00:11:08 EET 2021
cal2.set(Calendar.AM_PM, Calendar.PM);
System.out.println(cal2.getTime().toString()); // Wed Jan 13 12:11:08 EET 2021
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR, 12);
cal.set(Calendar.AM_PM, Calendar.AM);
System.out.println(cal.getTime().toString()); // Tue Jan 12 12:11:08 EET 2021
cal.set(Calendar.AM_PM, Calendar.AM);
System.out.println(cal.getTime().toString()); // Tue Jan 12 00:11:08 EET 2021
第一个看起来是午夜 12 点,而不是下午。
第三个好像是中午12点,不是半夜
为什么多次设置日历AM或PM会改变结果?
如何正确设置时间?
Calendar.HOUR 接受 0-11 范围内的输入。它会将 12 环绕到 0。
使用 Calendar.HOUR_OF_DAY 来使用 0-23 之间的值。
日历非常混乱
您绝对不是第一个对 Calendar
class 的工作原理感到困惑的人。幸运的是 class 也早就过时了。你不应该使用它。
Why setting calendar AM or PM multiple times change the result? …
为了按要求回答您的问题,Andi80 在另一个答案和评论中是正确的:HOUR
从 0 到 11。文档说 HOUR
:
Field number for get
and set
indicating the hour of the morning or
afternoon. HOUR
is used for the 12-hour clock (0 - 11). Noon and
midnight are represented by 0, not by 12. E.g., at 10:04:15.250 PM the
HOUR
is 10.
当您第一次将小时设置为 12 并将 AM/PM 设置为下午时,应该预料到会出现异常,因为小时值超出了 运行ge。但是不,具有默认设置的 Calendar
对象不会给你那个。相反,它将时间设置为第二天凌晨 0 点; 1 月 13 日,当您 运行 1 月 12 日的代码时。根据 Calendar
逻辑,第 12 小时是第 11 小时之后的小时。
当你再次设置PM时,Calendar
从你已经得到的时间,也就是上午,改成下午,所以你得到12:11:08,还是1月13号,隔天
为什么会计算两次时间?当你三次调用 set()
时不是一次也不是三次?这是 Calendar
的另一个令人困惑的特征。它计算你调用 getTime()
的时间(以及一些指定的其他方法)。在那一点上,它会拾取从调用 set()
到那一点为止的所有更改,并尽其所能将它们组合起来,如果有冲突则丢弃一些,使用任何头脑正常的人都不会想要的规则理解。
AM 的情况类似,所以我将详细信息留给 reader。
java.time
… How to set the time correctly?
我建议您使用 java.time,现代 Java 日期和时间 API,作为您的时间工作。如果您只想要中午 12 点或午夜 12 点,它们将作为常量内置:
LocalTime t12Noon = LocalTime.NOON;
System.out.println(t12Noon);
LocalTime t12Midnight = LocalTime.MIDNIGHT;
System.out.println(t12Midnight);
输出为:
12:00
00:00
A LocalTime
是一天中没有日期的时间。
如果您已经有时间并且只想调整小时和AM/PM,请使用with()
:
LocalTime t12Noon = LocalTime.now(ZoneId.systemDefault())
.with(ChronoField.CLOCK_HOUR_OF_AMPM, 12)
.with(ChronoField.AMPM_OF_DAY, 1); // 1 = PM
System.out.println(t12Noon);
LocalTime t12Midnight = LocalTime.now(ZoneId.systemDefault())
.with(ChronoField.CLOCK_HOUR_OF_AMPM, 12)
.with(ChronoField.AMPM_OF_DAY, 0); // 0 = AM
System.out.println(t12Midnight);
12:47:00.665155
00:47:00.669248
如果您也需要日期,请使用 ZonedDateTime
或其他合适的 class。 java.time 的所有日期时间 class 包括一天中的时间都具有相同的 with
方法,因此代码将相同。
如果您不可或缺地需要一个 Calendar
对象用于遗留 API 而您现在无法负担升级到 java.time 的费用,请使用 [=87] 中的 ZonedDateTIme
=] 为你的时间数学。然后使用 GregorianCalendar.from(ZoendDateTIme)
转换为 Calendar
对象。
链接
- Documentation of
Calendar.HOUR
- Oracle tutorial: Date Time 解释如何使用 java.time。
简单的问题,为什么这段代码的结果如下:
Calendar cal2 = Calendar.getInstance();
cal2.set(Calendar.HOUR, 12);
cal2.set(Calendar.AM_PM, Calendar.PM);
System.out.println(cal2.getTime().toString()); // Wed Jan 13 00:11:08 EET 2021
cal2.set(Calendar.AM_PM, Calendar.PM);
System.out.println(cal2.getTime().toString()); // Wed Jan 13 12:11:08 EET 2021
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR, 12);
cal.set(Calendar.AM_PM, Calendar.AM);
System.out.println(cal.getTime().toString()); // Tue Jan 12 12:11:08 EET 2021
cal.set(Calendar.AM_PM, Calendar.AM);
System.out.println(cal.getTime().toString()); // Tue Jan 12 00:11:08 EET 2021
第一个看起来是午夜 12 点,而不是下午。 第三个好像是中午12点,不是半夜
为什么多次设置日历AM或PM会改变结果? 如何正确设置时间?
Calendar.HOUR 接受 0-11 范围内的输入。它会将 12 环绕到 0。
使用 Calendar.HOUR_OF_DAY 来使用 0-23 之间的值。
日历非常混乱
您绝对不是第一个对 Calendar
class 的工作原理感到困惑的人。幸运的是 class 也早就过时了。你不应该使用它。
Why setting calendar AM or PM multiple times change the result? …
为了按要求回答您的问题,Andi80 在另一个答案和评论中是正确的:HOUR
从 0 到 11。文档说 HOUR
:
Field number for
get
andset
indicating the hour of the morning or afternoon.HOUR
is used for the 12-hour clock (0 - 11). Noon and midnight are represented by 0, not by 12. E.g., at 10:04:15.250 PM theHOUR
is 10.
当您第一次将小时设置为 12 并将 AM/PM 设置为下午时,应该预料到会出现异常,因为小时值超出了 运行ge。但是不,具有默认设置的 Calendar
对象不会给你那个。相反,它将时间设置为第二天凌晨 0 点; 1 月 13 日,当您 运行 1 月 12 日的代码时。根据 Calendar
逻辑,第 12 小时是第 11 小时之后的小时。
当你再次设置PM时,Calendar
从你已经得到的时间,也就是上午,改成下午,所以你得到12:11:08,还是1月13号,隔天
为什么会计算两次时间?当你三次调用 set()
时不是一次也不是三次?这是 Calendar
的另一个令人困惑的特征。它计算你调用 getTime()
的时间(以及一些指定的其他方法)。在那一点上,它会拾取从调用 set()
到那一点为止的所有更改,并尽其所能将它们组合起来,如果有冲突则丢弃一些,使用任何头脑正常的人都不会想要的规则理解。
AM 的情况类似,所以我将详细信息留给 reader。
java.time
… How to set the time correctly?
我建议您使用 java.time,现代 Java 日期和时间 API,作为您的时间工作。如果您只想要中午 12 点或午夜 12 点,它们将作为常量内置:
LocalTime t12Noon = LocalTime.NOON;
System.out.println(t12Noon);
LocalTime t12Midnight = LocalTime.MIDNIGHT;
System.out.println(t12Midnight);
输出为:
12:00 00:00
A LocalTime
是一天中没有日期的时间。
如果您已经有时间并且只想调整小时和AM/PM,请使用with()
:
LocalTime t12Noon = LocalTime.now(ZoneId.systemDefault())
.with(ChronoField.CLOCK_HOUR_OF_AMPM, 12)
.with(ChronoField.AMPM_OF_DAY, 1); // 1 = PM
System.out.println(t12Noon);
LocalTime t12Midnight = LocalTime.now(ZoneId.systemDefault())
.with(ChronoField.CLOCK_HOUR_OF_AMPM, 12)
.with(ChronoField.AMPM_OF_DAY, 0); // 0 = AM
System.out.println(t12Midnight);
12:47:00.665155 00:47:00.669248
如果您也需要日期,请使用 ZonedDateTime
或其他合适的 class。 java.time 的所有日期时间 class 包括一天中的时间都具有相同的 with
方法,因此代码将相同。
如果您不可或缺地需要一个 Calendar
对象用于遗留 API 而您现在无法负担升级到 java.time 的费用,请使用 [=87] 中的 ZonedDateTIme
=] 为你的时间数学。然后使用 GregorianCalendar.from(ZoendDateTIme)
转换为 Calendar
对象。
链接
- Documentation of
Calendar.HOUR
- Oracle tutorial: Date Time 解释如何使用 java.time。