请在 2024 年 Clojure 调查问卷! 中分享您的想法。

欢迎!请参阅 关于 页面以获取更多有关本站如何运作的信息。

+2
打印
已关闭

更新

https://clojure.org/news/2024/05/23/clojure-1-12-alpha12

Alpha12 回滚了导致此问题的更改。因此,此讨论已过时。


我刚刚注意到 Clojure 1.12 alpha10 更改了创建旧 #inst 日期的方式。据我所知,Java 正在尝试在引入格里历之前调整旧日期。

In Clojure 1.11.3

user-> #inst "1582-02-24"
#inst "1582-02-24T00:00:00.000-00:00"

In Clojure 1.12-alpha10

user=> #inst "1582-02-24"
#inst "1582-03-06T00:00:00.000-00:00"

我在测试一个旧项目时发现了这个问题,该项目测试日期。我正在将我的测试更改只为当前世纪,这对我的应用程序来说没问题。我觉得 Clojure 不必必然为此更改做任何事情,我只是认为如果有其他人遇到这个问题,提一下是值得的。

已更新到 Clojure 1.12 alpha 11

user=> (use 'clojure.instant)
nil
user=> (read-instant-date "1582-02-24")
#inst "1582-03-06T00:00:00.000-00:00"
user=> (read-instant-calendar "1582-02-24")
#inst "1582-02-24T00:00:00.000+00:00"
user=> (read-instant-timestamp "1582-02-24")
#inst "1582-03-06T00:00:00.000000000-00:00"
关闭时的注释: 回滚了原始更改,今后会考虑同时更改解析器和格式化程序
我在学习关于从儒略历到格里历的过渡的历史,以及现代 Java 中如何处理前格里历日期。我正在考虑 #inst 应该完全避免前格里历日期,但我相信有人观点更权威。以下是一些有用的 StackOverflow 问题

https://stackoverflow.com/questions/23975205/why-does-converting-java-dates-before-1582-to-localdate-with-instant-give-a-diff

https://stackoverflow.com/questions/23457470/calendar-to-date-conversion-for-dates-before-15-oct-1582-gregorian-to-julian-ca
我认为正确的方法是将大部分 instant.clj 重新实现,以使用 java.time.Instant 作为基础。这对我的问题有解决办法。

1 答案

0

编辑

以下内容无需注意 - 我直接使用 clojure.instant/read-instant-date 进行测试,并发现它并没有在常规 REPL 中使用 #inst


这与 Java 没有关系,因为仅更改 Clojure 版本本身并不会改变你所使用的 Java 版本。

快速实验表明,两个版本都以相同的方式解析日期 - (.getTime ...) 调用返回相同的 -12238560000000

因此,不同之处似乎在于实例的打印方式。提交 213c50e7 通过切换到不同的打印方式修复了 CLJ-2803

通过使用 1.12.0-alpha10 手动使用旧打印方法,我们可以证实这个猜测

(let [fmt (java.text.SimpleDateFormat. "yyyy-MM-dd'T'HH:mm:ss.SSS-00:00")]
  (.setTimeZone fmt (java.util.TimeZone/getTimeZone "GMT"))
  (.format fmt d))
=> "1582-02-24T00:00:00.000-00:00"
如何在不打扰他人的情况下迅速让人精神崩溃

    用户=> (.getTime #inst "1582-02-24")
    -12237696000000
    用户=> (let [d #inst "1582-02-24"] (.getTime d))
    -12237696000000
    用户=> (def d #inst "1582-02-24")
    #'用户/d
    用户=> (.getTime d)
    -12238560000000  ;; 究竟是为什么?
...