面对日历对象的问题

Facing issue with Calendar object

我有一个任务,我需要以编程方式为日历对象设置小时、分钟、子午线,并且需要以 hh:mm 格式显示时间下面是我到目前为止的代码。

Calendar calendar = (Calendar)dateNtime.clone();
        calendar.set(Calendar.HOUR, 12);
        calendar.set(Calendar.MINUTE, 0);
        calendar.set(Calendar.AM_PM, 1);

SimpleDateFormat dateFormat = new SimpleDateFormat("hh:mm a");
    String str = dateFormat.format(calendar.getTimeInMillis());

其中 dateNTime 是我在构建新日历对象时必须使用的现有日历对象。

一切正常,只有在我设置为中午 12 点时发生的情况除外。它总是格式 hh:mm a 和结果 12:00AM 而它应该是 12:00PM.

如果有人对 Calendar 对象有很好的体验并且它是已知问题,请提供帮助,或者如果有好的教程,请提供给我 link。

HOUR 字段是 documented 为:

Field number for get and set indicating the hour of the morning or afternoon. HOUR is used for the 12-hour clock (0 - 11).

因此,与其将其设置为 12,不如将其设置为 0。

就我个人而言,我只是设置了 HOUR_OF_DAY 字段,如果您想在下午添加 12 小时 - 并且根本不设置 AM_PM 字段。

java.time

java.util 日期时间 API 及其格式 API、SimpleDateFormat 已过时且容易出错。建议完全停止使用它们并切换到 modern Date-Time API*.

解决方案使用java.time,现代API:

import java.time.LocalTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        // Replace JVM's default timezone, ZoneId.systemDefault() with the applicable
        // timezone e.g. ZoneId.of("America/New_York")
        ZonedDateTime zdt = ZonedDateTime.now(ZoneId.systemDefault())
                            .withHour(12)
                            .withMinute(0);
        System.out.println(zdt);

        // Get and display just time in default format
        LocalTime time = zdt.toLocalTime();
        System.out.println(time);

        // Display just time in a custom format
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("hh:mm a", Locale.ENGLISH);
        // Alternatively, dtf.format(time);
        String formatted = dtf.format(zdt);
        System.out.println(formatted);
    }
}

输出:

2021-06-06T12:00:15.855986+01:00[Europe/London]
12:00:15.855986
12:00 PM

ONLINE DEMO

如何将Calendar类型转换为java.time类型?

Instant instant = calendar.toInstant();
// Replace JVM's default timezone, ZoneId.systemDefault() with the applicable
// timezone e.g. ZoneId.of("America/New_York")
ZonedDateTime zdt = instant.atZone(ZoneId.systemDefault());

如果我需要 java.time 类型的 Calendar 对象怎么办?

出于任何原因,如果您需要将 ZonedDateTime 的这个对象转换为 java.util.Calendar 的对象,您可以按如下方式进行:

Calendar calendar = Calendar.getInstance();
calendar.setTime(Date.from(zdt.toInstant()));

了解更多关于 java.timemodern Date-Time API* 来自 Trail: Date Time.

有时,评论会被删除,因此在下面引用 Ole V.V.:

的宝贵评论

For a more accurate conversion to Calendar you may use GregorianCalendar.from(zdt)


* 无论出于何种原因,如果您必须坚持Java 6 或Java 7,您可以使用ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and