Java 日历/日期 : AM and PM not setting correctly

标签 java date

我有一个函数,它接受自定义字符串并将其转换为日期。我的目标是存储今天的日期,但使用字符串提供的自定义小时:分钟。

由于某种原因,调试器显示 AM/PM 在最后进行了切换(但流程是正确的)。当我传入 12:05am 时,Date 对象将存储为 PM 值,而如果我传入 12:05pm ,Date 对象将存储为 AM 值。应该是相反的。

代码:

public class DateUtils {

    private static final String AM_LOWERCASE = "am";
    private static final String AM_UPPERCASE = "AM";

    public static Date getDateFromTimeString(String timeStr) {

        Calendar calendar = Calendar.getInstance();

        if (StringUtils.hasText(timeStr)) {

            if (timeStr.indexOf(AM_LOWERCASE) != -1 || timeStr.indexOf(AM_UPPERCASE) != -1) {
                calendar.set(Calendar.AM_PM, Calendar.AM);
            } else {
                calendar.set(Calendar.AM_PM, Calendar.PM);
            }

            // Set custom Hours:Minutes on today's date, based on timeStr
            String[] timeStrParts = timeStr.replaceAll("[a-zA-Z]", "").split(":");
            calendar.set(Calendar.HOUR, Integer.valueOf(timeStrParts[0]));
            calendar.set(Calendar.MINUTE, Integer.valueOf(timeStrParts[1]));
            calendar.set(Calendar.SECOND, 0);
            calendar.set(Calendar.MILLISECOND, 0);
        }

        return calendar.getTime();

    }
}

调试器显示:

输入:12:05am -> 2017 年 12 月 17 日星期日 12:05:00 EST 2017

输入:12:05pm -> Mon Dec 18 00:05:00 EST 2017

应该是相反的。如果我使用 SimpleDateFormat 写回这些字符串,我会看到输入 1 在 12:05PM 返回,输入 2 在 12:05AM 返回。

此外,对于#2,日期不应向前循环一天。 两种情况下,应存储的日期都是今天的日期,即上午 12:05 或下午 12:05。

我错过了什么吗?目标:

12:05am   ->    Sun Dec 17 00:05:00 EST 2017
12:05pm   ->    Sun Dec 17 12:05:00 EST 2017

最佳答案

问题是 Calendar.HOUR 的值范围是 011,而不是 112。当您将小时设置为 12 时,日历会将其标准化为当天的另一半...也就是说,您“溢出”到了下一天的一半。

public static void main(String[] args)
{
    Calendar c1 = Calendar.getInstance();
    System.out.printf("Initial: %s\n",c1.getTime().toString());
    c1.set(Calendar.AM_PM, Calendar.AM);
    System.out.printf("Set(AM): %s\n",c1.getTime().toString());
    c1.set(Calendar.HOUR, 12);
    System.out.printf("Set(12): %s\n\n",c1.getTime().toString());

    Calendar c2 = Calendar.getInstance();
    System.out.printf("Initial: %s\n",c2.getTime().toString());
    c2.set(Calendar.AM_PM, Calendar.PM);
    System.out.printf("Set(PM): %s\n",c2.getTime().toString());
    c2.set(Calendar.HOUR, 12);
    System.out.printf("Set(12): %s\n\n",c2.getTime().toString());
}

输出

Initial: Sun Dec 17 17:53:52 PST 2017
Set(AM): Sun Dec 17 05:53:52 PST 2017
Set(12): Sun Dec 17 12:53:52 PST 2017

Initial: Sun Dec 17 17:53:52 PST 2017
Set(PM): Sun Dec 17 17:53:52 PST 2017
Set(12): Mon Dec 18 00:53:52 PST 2017

除此之外,您应该使用自 Java 8 以来已成为 Java 一部分的新 Time 类。它们取代了多年来一直被认为不是最佳的遗留类(即日历、日期等) .

根据@Andreas的建议,以下是如何以现代方式解析它:

LocalTime.parse(
    "12:05am", 
     new DateTimeFormatterBuilder().
         parseCaseInsensitive().
         appendPatt‌​‌​ern("hh:mma").
         toFo‌​rm‌​atter(Locale.US)‌​);

关于Java 日历/日期 : AM and PM not setting correctly,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47861076/

相关文章:

php - 时间戳检查是否为 10 分钟前

java - 拆分标签上的元素

java - 从字符串中解析带时区的日期

javascript - JavaScript 中特定时区的 new Date()

java - 无法对参数化类型 ArrayList<Foo> 执行 instanceof 检查

java - 为什么 "2012-30-03"用 DateFormat 解析为 June 3 2014?

使用 c 中的 mktime() 检查字符串是否为日期

JavaFX setOnScrollStarted 和 setOnScrollFinished 不起作用

java - 在 tomcat context.xml 中指定 Oracle DB/Schema 名称

java - 如何使用 Maven 基于 testng.xml 的测试标签运行测试?