【问题标题】:Calendar.setTime sets the wrong dateCalendar.setTime 设置错误的日期
【发布时间】:2015-06-06 19:14:38
【问题描述】:

下面的代码将日期设置为 2015 年 6 月 7 日午夜。为什么?我的时区是 UTC-07:00

格雷格

           Calendar HuntStart = Calendar.getInstance();
            SimpleDateFormat sdf = new SimpleDateFormat("M/d/yyyy K:mm a", Locale.US);
            try {
                HuntStart.setTime(sdf.parse("6/6/2015 12:00 PM"));//AllLists.get(position).HuntStart));
            }
            catch (ParseException ex) {

            }

【问题讨论】:

  • 更具体...'午夜' 是 2015 年 6 月 6 日中午 12:00 还是 2015 年 6 月 7 日中午 12:00?
  • 在 HuntStart.setTime(sdf.parse("6/6/2015 12:00 PM")) 之后,如果我调用 HuntStart.getTime() 它返回 6/7/2015 00:00: 00.我希望 HuntStart.getTime() 返回 6/6/2015 12:00 PM
  • 中午 12:00。午夜是 12:00 AM。
  • 你说的很明显。为什么?

标签: java android datetime


【解决方案1】:

问题来自您在 SimpleDateFormat 构造函数中使用的小时字母。

请参阅 SimpleDateFormat JavaDoc SimpleDateFormat javaDoc

上午/下午的 K 小时 (0-11)
上午/下午小时 (1-12)

您正在使用字母 K 并且 javadoc 说此选项应与小时 (0-11) 一起使用,以便您使用 12 在您的字符串中。 我没有查看该类的实现,但毫无疑问这是一个副作用。您重叠了允许的时间范围,因此您进入第二天。 可惜构造函数如此放任。 IllegalArgumentException 或类似的会很有用。

总而言之,您有 2 个解决方案。

如果您想使用 12 小时作为源字符串进行解析,您应该在构造函数中使用 h 字母模式。 像这样:

    SimpleDateFormat sdf = new SimpleDateFormat("M/d/yyyy h:mm a", Locale.US);

如果你想保持你的小时模式 K,你不应该使用 12 而是 0 的 String 实例作为 parse 方法的输入 像这样:

    huntStart.setTime(sdf.parse("06/06/2015 00:00 PM"));// AllLists.get(position).HuntStart));

【讨论】:

  • 谢谢。当我去 Joda 时,我意识到了这一点,因为它在通过 12:00 并使用 K 时抛出了异常,正如预期的那样。我之前说过,但得到了很多反对票,但我再说一遍:DateTime 和 Calendar 对象在 Java 中简直令人难以置信。
  • 不客气。 DateTime 是一个 JodaTime 类。我认为您指的是日期和日历。我同意:日期和日历确实不是很方便的课程。大多数开发人员都知道。在新的 Date API 文档网站上,您可以阅读“Java 开发人员长期困扰的问题是普通开发人员对日期和时间用例的支持不足”。 Java 8 和新的 API 通过 JodaTime API 的启发解决了 Date 类的大部分缺点。
【解决方案2】:

放弃 Java 日历并改用 Joda Time。下面的代码按预期返回 HuntStart 的 2015-06-06T12:00:00.000-07:00。

            DateTime HuntStart = new DateTime();
            DateTimeFormatter fmt = DateTimeFormat.forPattern("M/d/yyyy h:mm a");
            HuntStart = fmt.parseDateTime("6/6/2015 12:00 PM");

【讨论】:

  • 有趣的是:您可以使用与SimpleDateFormatter. 相同的模式。 K 而不是 h 的用法不适合您的日期字符串。
  • 我去 Joda 时意识到了这一点,因为它抛出了异常。不使用 Java 日期时间的另一个原因。
【解决方案3】:

使用以下代码更新日历对象,而不是 SimpleDateFormat

HuntStart.set(Calendar.MONTH,Calendar.JUNE);
HuntStart.set(Calendar.DAY_OF_MONTH,6);
HuntStart.set(Calendar.YEAR,2015);
HuntStart.set(Calendar.HOUR,12);
HuntStart.set(Calendar.MINUTE,0);

【讨论】:

  • 实际代码是从 AllLists.get(position).HuntStart 中提取时间,这是一个字符串。我宁愿不必解析它。
猜你喜欢
  • 2017-07-07
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 2012-02-26
  • 1970-01-01
  • 2020-09-15
  • 2016-05-27
  • 1970-01-01
相关资源
最近更新 更多