使用 Java 将纪元时间和当前时刻之间经过的时间转换为 ISO 8601 持续时间

Convert elapsed time between epoch time and current moment to ISO 8601 duration with Java

我有自 1970 年 1 月 1 日 UTC(大纪元时间)以来的毫秒数。

1512431637067

我需要将其转换为类似(ISO-8601 持续时间)的格式。这将基于当前的今天日​​期。

P5M4D

知道如何使用 java 代码以简单的方式做到这一点吗?

试试这条线

import java.util.Date;
import java.text.SimpleDateFormat;
import java.text.DateFormat;
import java.util.Locale;

public class HelloWorld
{
  public static void main(String[] args)
  {
    Date date=new Date (1512431637067L);
    DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX", Locale.US);
    System.out.print(df.format(date));
  }
}

iso 8601 上的输出日期:

2017-12-04T23:53:57.067Z

严格来说,你不能,因为所谓的 "epoch time" 实际上是瞬间而不是持续时间。但是您可能希望将自该纪元(Unix 纪元)以来经过的时间建模为持续时间。所以给你:

System.out.println(Duration.of(1512431637067L, ChronoUnit.MILLIS));
// output: PT420119H53M57.067S

方法java.time.Duration.toString()自动将秒和纳秒归一化为HMS格式(否则我们必须声明新持续时间class的打印能力有限)。如果您希望更好地控制 ISO 格式,请考虑使用 toHours() 等方法来解决您自己的问题,或者使用第 3 方库进行持续时间打印。

另一件事:1512431637067 似乎以毫秒为单位,而不是像您所说的以秒为单位,否则您会在遥远的将来得到瞬间:

System.out.println(Instant.ofEpochMilli(1512431637067L));
// output: 2017-12-04T23:53:57.067Z

System.out.println(Instant.ofEpochSecond(1512431637067L));
// far future: +49897-01-18T19:11:07Z
ZoneId zone = ZoneId.of("Europe/Guernsey");  // Specify a time zone by proper name `Contintent/Region`, never by 3-4 letter codes such as `PST`, `CST`, or `IST`.
LocalDate then =                             // Represent a date-only value, without time zone and without time-of-day.
    Instant.ofEpochMilli(1_512_431_637_067L) // Parse your number of milliseconds since 1970-01-01T00:00Z as a value in UTC.
           .atZone(zone)                     // Adjust from UTC to some other zone. Same moment, different wall-clock time. Returns a `ZonedDateTime`.  
           .toLocalDate();                   // Extract a date-only value.
LocalDate today = LocalDate.now(zone);       // Get the current date as seen in the wall-clock time in use by the people of a particular region.
Period diff = Period.between(then, today);   // Determine the number of years-months-days elapsed.
System.out.println(diff);                    // Generate a String is standard ISO 8601 format: `PnYnMnDTnHnMnS`.

刚才运行时的输出正是你要求的:

P5M4D

结果取决于时区。对于任何给定的时刻,日期因地区而异。

因此,如果不是 Europe/Guernsey,请替换为您想要的时区。使用 ZoneOffset.UTC and OffsetDateTime class if you want the calculation to happen in UTC.

例如 运行 上面 Europe/Guernsey 的代码会生成 P5M4D,而切换到 Europe/Moscow 会生成 P5M3D,两者相差一天,具体取决于您指定的区域。

Period.between(then, LocalDate.now(ZoneId.of("Europe/Moscow")))

提问当天的输出应该是:

P5M3D

对于包含大于一天的单位的持续时间,您需要使用 Period class of java.time The Duration class 适用于更小的单位,天-小时-分钟-秒-纳秒。