clj-time - 如何从不同时区的当前时间获取本地日期

clj-time - how to get local-date from curent time in a different timezone

我正坐在 America/Sao_Paulo(或其他一些随机时区),现在我想获取 Europe/London 中当前日期的 LocalDate。

我怎样才能做到这一点?

(我有一个我知道在伦敦的 localDate,我想使用 clj-time 检查它是否在当前日期之前。core/after?)

注意:

clj-time 库基于旧的 Joda Time 库。这两个都已被弃用,取而代之的是 java.time(自 JDK 8 起可用)。最好使用 Java 与 java.time 互操作而不是旧的 clj-time 库。

java.time 基本上是 Joda Time 2.0,但重写后更清晰并纠正了一些极端情况。两者都是由同一个人创建的。


答案:

在 Java 中,LocalDate 没有时区。这就是重点。

它用于生日之类的事情,例如 1999-12-31,我们认为您的生日没有时区。

出于同样的原因,LocalDate 没有任何关联的时间,就像您的生日被认为是一整天一样。

有关详细信息,请参阅 java.time 文档:https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html


来自 Java文档:

Dates and Times

Instant is essentially a numeric timestamp. The current Instant can be retrieved from a Clock. This is useful for logging and persistence of a point in time and has in the past been associated with storing the result from System.currentTimeMillis().

LocalDate stores a date without a time. This stores a date like '2010-12-03' and could be used to store a birthday.

LocalTime stores a time without a date. This stores a time like '11:30' and could be used to store an opening or closing time.

LocalDateTime stores a date and time. This stores a date-time like '2010-12-03T11:30'.

ZonedDateTime stores a date and time with a time-zone. This is useful if you want to perform accurate calculations of dates and times taking into account the ZoneId, such as 'Europe/Paris'. Where possible, it is recommended to use a simpler class without a time-zone. The widespread use of time-zones tends to add considerable complexity to an application.


辅助函数:

我添加了 some convenience functions 以帮助您使用 java.time,您可能会发现它很有用。

似乎没有从中获取 LocalDate 的函数 DateTimeclj-time 中的类似内容——但 Joda Time.toLocalDate。所以例如你可以这样做:

(defn date-at-zone
  [instant zone-id]    
  (.toLocalDate                                                                                                                                                         
   (t/to-time-zone                             
    instant                                                                   
    (t/time-zone-for-id zone-id))))                                        
                                                                  
 (let [instant (t/date-time 2020 12 12 1)                                  
       london-date (date-at-zone instant "Europe/London")
       sao-paulo-date (date-at-zone instant "America/Sao_Paulo")]
   (print (map str [instant london-date sao-paulo-date (t/after? london-date sao-paulo-date)])))       
; → (2020-12-12T01:00:00.000Z 2020-12-12 2020-12-11 true)

(例如,在 2020-12-12T01:00 祖鲁语中,圣保罗仍然是 2020-12-11 并且 因此,伦敦在只看 日期——或者在伦敦已经是“明天”了)

我不知道Clojure。所以我会使用 Java 语法,你可以翻译。

I'm sitting in the America/Sao_Paulo (or some other random timezone)

无关紧要。无论你的屁股是在东京、雷克雅未克还是圣保罗,这都与询问 Europe/London 时区的当前日期无关。

and now I want to get a LocalDate for the current date in Europe/London.

在经过感兴趣的时区时调用 LocalDate.now

ZoneId zoneId = ZoneId.of( "Europe/London" ) ;
LocalDate currentDateInLondon = LocalDate.now( zoneId ) ;

I've got a localDate that I know is in london, and I want to check if it's before the current date

您可以通过调用 isEqualisBeforeisAfter 来比较 LocalDate 个对象。

LocalDate localDate = LocalDate.of( 2021 , Month.JANUARY , 23 ) ;
boolean isCurrentDateInLondonBeforeThatDate = currentDateInLondon.isBefore( localDate ) ;