【问题标题】:Convert a date of 6 months ago from now, into a String从现在开始将 6 个月前的日期转换为字符串
【发布时间】:2019-02-04 11:24:54
【问题描述】:

我已经接受了 SOF 和其他网站上给出的所有答案,并尝试这样做:

String fromDateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sssX").format(new DateTime().plusMonths(-6));

但我得到了例外:

线程“main”java.lang.IllegalArgumentException 中的异常:无法将给定对象格式化为日期

我做错了什么?

【问题讨论】:

  • 你使用的是什么DateTime 类?
  • 使用 Joda-Time?然后坚持使用它并使用它的格式化程序(不是SimpleDateFormat,这是出了名的麻烦,Joda-Time 已经有了替代品)。或者跳过两者并完全使用java.time, the modern Java date and time API
  • 或者使用新的java日期时间类:ZonedDateTime.now().minusMonths(6).toString().
  • @Arnaud 这确实是问题所在。一个 toDate 做对了。实际的问题是我没有任何编译错误。有点奇怪,因为 Date 和 DateTime (多态性)之间没有联系。我想知道它怎么不能给我任何提示甚至错误。
  • @Marco DateDateTime 来自不相关的框架,因此没有多态关系。恰恰相反,第二个来自 Joda-Time(显然),旨在替换第一个而不是补充。 Joda-Time 的创建者继续创建其继任者 JSR 310 和内置于 Java 8 及更高版本的 java.time 类。因此,没有理由再接触可怕的可恶的 DateCalendarSimpleDateFormat 类。仅使用 java.time 包中的类。

标签: java date format jodatime simpledateformat


【解决方案1】:

java.time

    String fromDateTime = OffsetDateTime.now(ZoneId.systemDefault()).minusMonths(6).toString();
    System.out.println(fromDateTime);

刚刚在我的电脑上运行时的输出:

2018-08-04T12:45:34.087966+01:00

java.time 是现代 Java 日期和时间 API,已有效取代 Joda-Time。从主页:

请注意,Joda-Time 被认为是一个基本上“已完成”的项目。 没有计划进行重大改进。如果使用 Java SE 8,请迁移 到java.time (JSR-310)。

在代码中,我利用了 java.time 类的 toString 方法生成 ISO 8601 格式的事实,即您要求的格式。我发现秒上的额外小数不太可能造成任何问题,因为标准允许。

乔达时间

    String fromDateTime = new DateTime().minusMonths(6).toString();

示例输出:

2018-08-04T12:50:36.071+02:00

new DateTime() 只有毫秒精度。秒数总是精确到小数点后 3 位。

我必须使用旧的 java 库,因为我在一家使用 java 版本 的公司工作

java.time 在 Java 6 和 7 上也能很好地工作,在所有条件相同的情况下,我推荐它而不是 Joda-Time。只有强制使用 Java 5,Joda-Time 无疑是不错的选择。

  • 在 Java 8 及更高版本以及更新的 Android 设备(从 API 级别 26 起)中内置了 java.time。
  • 在 Java 6 和 7 中获得 ThreeTen Backport,这是现代类的后向端口(JSR 310 的 ThreeTen;请参阅底部的链接)。
  • 在(较旧的)Android 上使用 ThreeTen Backport 的 Android 版本。它被称为 ThreeTenABP。并确保从 org.threeten.bp 导入日期和时间类以及子包。

你的代码出了什么问题?

您的代码可以在没有错误迹象的情况下编译,但在运行时会发出java.lang.IllegalArgumentException: Cannot format given Object as a Date。这是因为 SimpleDateFormat 无法格式化 Joda-Time DateTime 对象。我们当然希望这会在编译时报告。但除了SimpleDateFormat.format(Date) 之外,还有一个从Format 继承的覆盖format(Object)。它适用于格式化DateNumber(自纪元以来的毫秒数)。此方法是编译器在您传递DateTime 时选择的方法。这就是没有编译时错误消息的原因。

提示:如果您没有立即理解错误消息,请将其粘贴到您的搜索引擎中。它通常会引导您找到解释和解决方案。在这种情况下也是如此。

链接

【讨论】:

  • 您在所有方面都不能再具体了。谢谢你,你真的教会了我很多!你应该得到绿色检查。
【解决方案2】:

尝试以下方法:

String fromDateTime = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sssX").format(new DateTime().minusMonths(6).toDate());

您必须在格式化之前将DateTime 转换为Date,使用toDate() 方法就可以了。

API for toDate()API for minusMonths,我建议您检查 API 以了解新方法

【讨论】:

  • 可以,但不是推荐的方式。你正在从好的库(Joda-Time)进入坏库(DateSimpleDateFormat)。
  • 这确实解决了我的问题。但我想知道:你谈论好的和坏的图书馆。如果最终我能正常工作,那又有什么意义呢?
  • 在某些情况下您可能会遇到使用多个库的不兼容问题、转换错误等...
  • @ngueno 是的,你是对的,但在我的情况下,我认为没有任何问题 :p 感谢大家的 (date_) 时间!
  • 你应该考虑使用Joda DateTimeFormatter重写格式化程序,它是线程安全的并且在Joda包中可用
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2018-05-26
  • 1970-01-01
  • 2021-07-14
  • 2020-08-26
  • 2013-07-22
  • 2015-04-27
  • 1970-01-01
相关资源
最近更新 更多