【问题标题】:In joda time how to convert time zone without changing time在 joda time 如何在不更改时间的情况下转换时区
【发布时间】:2013-09-30 22:19:56
【问题描述】:

我正在从数据库中获取 UTC 时间戳,我将其设置为 JodaTime DateTime 实例

DateTime dt = new DateTime(timestamp.getTime());

它完美地存储了10:00 AM 的时间,但带有本地时区。例如,我在 IST 时区,距 UTC +5:30

我已经尝试了很多方法来更改时区,但每件事都会通过使用 +5:30 差异将时间从 10:00 AM 更改为其他时间

有什么方法可以在不影响当前时间的情况下更改 TimeZone

编辑: 如果我现在的时间是:

2013-09-25 11:27:34 AM      UTC

以下是我使用这个new DateTime(timestamp.getTime());时的结果

2013-09-25 11:27:34 AM  Asia/Kolkata

以下是我使用new DateTime(timestamp.getTime(), DateTimeZone.UTC)时的结果;

2013-09-25 05:57:34 AM  UTC

【问题讨论】:

  • 嗨。你能告诉我哪种方法适合你吗?
  • @ShajeelAfzal 当我不想玩时区时,我主要使用LocalDateTime

标签: java datetime jodatime


【解决方案1】:

你可以使用LocalDateTime类

LocalDateTime dt = new LocalDateTime(t.getTime()); 

并将LocalDateTime 转换为DateTime

DateTime dt = new LocalDateTime(timestamp.getTime()).toDateTime(DateTimeZone.UTC);  

Joda DateTime 将毫秒中的任何时间视为“当前时区自 1970 年以来的毫秒”。因此,当您创建 DateTime 实例时,它是使用当前时区创建的。

【讨论】:

  • 它使用 LocalDateTime 工作,但为什么 DateTime 会这样?有什么解决办法吗?
  • @Abhi timestamp 是什么? java.util.Date 或 java.sql.Timestamp?
  • DateTime 没有 getTime 方法。显然我错过了这个答案的相关性或正确性。
  • 不工作。与 getMillis 之间的转换失败。
  • @Abhi,我迟到了几年,但我在我的回答中解释了你在 DateTime 类中看到的行为。
【解决方案2】:

您可以使用DateTime 的withZoneRetainFields() 方法更改时区而不更改日期中的数字。

【讨论】:

  • 谨慎使用这种情况,因为如果您在夏令时配置环境中使用它,它可能会在时间转换时引发异常。如果您有文本中的日期,您可能更喜欢这样的解决方案stackoverflow.com/questions/5451152/…
【解决方案3】:

如果您的时间戳是: 2015-01-01T00:00:00.000-0500 (这是当地时间[对我来说])

试试这个:

DateTime localDt = new DateTime(timestamp.getTime())
    .withZoneRetainFields(DateTimeZone.UTC)
    .withZone(DateTimeZone.getDefault());

2014-12-31T19:00:00.000-05:00

分解: 这将为您提供与您的时间戳相对应的 DateTime,并指定它采用 UTC:

new DateTime(timestamp.getTime())
    .withZoneRetainFields(DateTimeZone.UTC)

2015-01-01T00:00:00.000Z

这会为您提供一个 DateTime,但时间会转换为您的本地时间:

new DateTime(timestamp.getTime())
    .withZoneRetainFields(DateTimeZone.UTC)
    .withZone(DateTimeZone.getDefault());

2014-12-31T19:00:00.000-05:00

【讨论】:

    【解决方案4】:

    我是这样做的:

    private DateTime convertLocalToUTC(DateTime eventDateTime) {
    
            // get your local timezone
            DateTimeZone localTZ = DateTimeZone.getDefault();
    
            // convert the input local datetime to utc  
            long eventMillsInUTCTimeZone = localTZ.convertLocalToUTC(eventDateTime.getMillis(), false);
    
            DateTime evenDateTimeInUTCTimeZone = new DateTime(eventMillsInUTCTimeZone);
    
            return evenDateTimeInUTCTimeZone.toDate();
    }
    

    【讨论】:

      【解决方案5】:

      给出的答案都没有真正解释问题。真正的问题是最初的假设是不正确的。数据库中的时间戳是使用本地 JVM 时区 Asia/Kolkata 而不是 UTC 创建的。这是 JDBC 的默认行为,因此仍建议将 JVM 时区设置为 UTC。

      如果数据库中的时间戳是真的:

      2013-09-25 11:27:34 AM UTC
      

      或采用 ISO-8601 格式:

      2013-09-25T11:27:34Z // The trailing 'Z' means UTC
      

      然后使用new DateTime(timestamp, DateTimeZone.UTC) 构造函数可以正常工作。自己看:

      Timestamp timestamp = new Timestamp(1380108454000L);
      DateTime dt = new DateTime(timestamp.getTime(), DateTimeZone.UTC);
      System.out.println(dt); // => 2013-09-25T11:27:34.000Z
      

      如果您想知道我是如何获得 1380108454000L 的,我只是使用了 Joda 解析类:

      ISODateTimeFormat.dateTimeParser().parseMillis("2013-09-25T11:27:34Z")
      

      或者有一些在线网站,您可以在其中输入日期、时间和时区,它会以毫秒为单位返回纪元值,反之亦然。有时它可以作为健全性检查。

      // https://www.epochconverter.com
      Input: 1380108454000  Click: "Timestamp to Human Date"
      Assuming that this timestamp is in milliseconds:
      GMT: Wednesday, September 25, 2013 11:27:34 AM
      

      另外,请记住 java.sql.Timestamp 类与 Joda/Java 8+ Instant 类大致相关。有时在等价类之间进行转换以更早地发现此类错误会更容易。

      【讨论】:

        【解决方案6】:

        我遇到了同样的问题。在阅读了这组有用的答案后,并考虑到我的特殊需求和可用对象,我通过使用另一个 DateTime 构造函数来解决它:

        new DateTime("2012-04-23T18:25:46.511Z", DateTimeZone.UTC)
        

        【讨论】:

        • 乔达时间怎么知道2012-04-23T18:25:46.511Z是什么时区?
        【解决方案7】:

        我还有另一种对我很有帮助的方法。 我想让我的工作流线程临时更改为特定的时区(节省时间),然后当我的代码完成时,我再次设置原始时区。 事实证明,当您使用 joda 库时,这样做:

        TimeZone.setDefault(TimeZone.getTimeZone(myTempTimeZone));
        TimeZone.setDefault(timeZone);
        

        这还不够。 我们还需要更改DateTimeZone中的TimeZone,如下:

        @Before
        public void setUp() throws Exception {
            timeZone = TimeZone.getDefault();
            dateTimeZone = DateTimeZone.getDefault();
        }
        
        @After
        public void tearDown() throws Exception {
            TimeZone.setDefault(timeZone);
            DateTimeZone.setDefault(dateTimeZone);
        }
        
        @Test
        public void myTest() throws Exception {
            TimeZone.setDefault(TimeZone.getTimeZone(myTempTimeZone));
            DateTimeZone.setDefault(DateTimeZone.forID(myTempTimeZone));
            //TODO
            // my code with an specific timezone conserving time
        }
        

        希望对其他人也有帮助。

        【讨论】:

          猜你喜欢
          • 2019-11-01
          • 2018-07-24
          • 1970-01-01
          • 1970-01-01
          • 2015-10-26
          • 2013-08-18
          • 2023-03-09
          • 2021-01-31
          • 1970-01-01
          相关资源
          最近更新 更多