【问题标题】:Facing issue with Calendar object面临日历对象的问题
【发布时间】:2026-01-25 04:15:02
【问题描述】:

我有一个任务,我需要以编程方式将小时、分钟、子午线设置为日历对象,并且需要以 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 对象有很好的经验并且它是已知问题,请提供帮助,或者如果有很好的教程链接,请提供给我。

【问题讨论】:

  • 请提供一个简短但完整的程序来说明问题。就我个人而言,我认为我只是将 HOUR 设置为您的目标时间,如果您尝试将其设置为 PM,则添加 12...
  • 请注意,如果您将小时设置为 0,然后将 AM_PM 设置为 1,您将获得所需的结果。

标签: java android date time calendar


【解决方案1】:

java.time

java.util 日期时间 API 及其格式化 API SimpleDateFormat 已过时且容易出错。建议完全停止使用,改用modern Date-Time API*

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

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()));

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

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

要更准确地转换为Calendar,您可以使用 GregorianCalendar.from(zdt)


* 出于任何原因,如果您必须坚持使用 Java 6 或 Java 7,您可以使用 ThreeTen-Backport,它将大部分 java.time 功能向后移植到 Java 6 和 7 . 如果您正在为一个 Android 项目工作并且您的 Android API 级别仍然不符合 Java-8,请检查 Java 8+ APIs available through desugaringHow to use ThreeTenABP in Android Project

【讨论】:

    【解决方案2】:

    HOUR 字段为 documented

    get 和 set 的字段编号,指示上午或下午的时间。 HOUR 用于 12 小时制 (0 - 11)。

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

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

    【讨论】: