如何在Java中以2022-10-03T19:45:47.844Z格式获取日期和时间

5

我需要在Java类中以2022-10-03T19:45:47.844Z格式获取当前系统日期和时间。

我尝试使用ZonedDateTime和SimpleDateFormat,但在网上找不到正确的语法或代码。我是Java的初学者,感谢任何帮助。


1
如果您不需要一个字符串,请省略.toString()。对于Instant.now().toString(),是这么简单的(是的,如果您接受无法控制小数位数,它确实如此)。 - Ole V.V.
1
@OleV.V. 那个问题和那个问题都不是这个问题的直接原始版本。两者都很复杂,都没有直接要求以 ISO 8601 格式提供今天的日期,并且都是针对 Android 的。我期望有一个现有的原始问题来标记这个问题为重复,但我找不到。因此,这就是我的答案。 - Basil Bourque
你确定你需要精确到小数点后三位吗(例如.844)?问这个问题是因为你的格式是ISO 8601,而该标准并没有限制小数位数。 - Ole V.V.
这个回答解决了你的问题吗?如何在Java中以YYYY-MM-DD HH:MI:Sec.Millisecond格式获取当前时间? - Karl Knechtel
4个回答

4
我希望这能解决你的问题:
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;

public class Main {
    public static void main(String[] args) {
        ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("UTC"));
        DateTimeFormatter formatter =
                DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
        System.out.println(zdt.format(formatter));
    }
}

2
它能正常工作,并确保精确打印三位小数秒。这不是完美的解决方案,因为ZonedDateTime过于复杂,更糟糕的是,硬编码Z作为文字是错误的(尽管在这种特定情况下它恰好给出了正确的输出)。Z是零的UTC偏移量,应该格式化为偏移量。我会使用OffsetDateTimeZoneOffset.UTC和格式模式uuuu-MM-dd'T'HH:mm:ss.SSSX - Ole V.V.
'Z' 不等于 Z。 - Arvind Kumar Avinash

3

简而言之

Instant.now().toString()

查看这个在Ideone.com上运行的代码

2022-11-08T07:18:21.482293Z

Instant.now().toString()

Ole V.V.评论 所述,您可以使用java.time.Instant类,在UTC零小时-分钟-秒的偏移量下捕获当前时刻。

Instant instant = Instant.now() ;

ISO 8601

您可以通过调用Instant#toString()来生成标准的ISO 8601格式或您所需的格式的字符串。

String output = instant.toString() ;

当然,我们可以将它们结合起来:
Instant.now().toString()  

分辨率

Instant 表示一个以纳秒为精度的 UTC 时刻。

请注意,Instant#toString 使用一个格式化程序,将小数部分格式化为三位一组的数字,最多可以有九个数字表示纳秒。任何更细的全零组都会被省略。因此,如果您的 Instant 只有 毫秒,没有 微秒/纳秒,则会显示三位数字。如果只有微秒而没有纳秒,则显示六位数字。如果有纳秒,则显示九位数字。

您可能需要使用以下代码来获取当前时刻:

  • 在Java 8中,毫秒(小数点后3位)。
  • 由于Clock类在OpenJDK项目代码库中的全新实现,Java 9及更高版本可以表示微秒(6位数字)。

普通计算机硬件时钟精度不足以达到纳秒级别。因此,Instant可以表示带有纳秒值的时间,但你不太可能看到以这种精度捕获当前时刻。

如果你只需要毫秒,截取。通过ChronoUnit枚举来指定所需的粒度,并实现TemporalUnit
Instant.now().truncatedTo( ChronoUnit.MILLIS ).toString()

但是请记住,如果你的小数部分为零,那么在生成的String对象中将不会出现任何小数部分数字。

Z

你所需格式末尾的Z表示偏移量为零。发音为“祖鲁”,源自航空/军事历史,已在ISO 8601中标准化。
避免使用旧日期时间类
你说:

我尝试使用了zoneddatetime和simple date format

java.time.ZonedDateTime类用于表示特定时区下的时刻。你所需的格式没有时区,只有偏移量为零。因此,在这里不适合使用ZonedDateTime。应改用Instant,或者如果需要其他格式的更大灵活性,则使用OffsetDateTime
定义:
  • 偏移量仅是UTC时间的主子午线前后的小时-分钟-秒数。
  • 时区则不同。时区是一个名称,记录了过去、现在和未来政治决策下特定地区人们使用的偏移量的变化历史。

永远不要使用SimpleDateFormatDateCalendar等非常有缺陷的类。自Java 8+起,这些已经过时,被JSR 310定义的现代java.time类所取代。


1

ZonedDateTime.now().format(DateTimeFormatter.ISO_LOCAL_DATE_TIME)


虽然方向正确,但不完全正确。期望输出为:2022-11-08T08:16:24.715Z,但在我的时区观察到的输出为:2022-11-08T09:16:24.715128761。时间偏移了1小时,缺少尾随的 Z。由于根据 ISO 8601 标准,小数位数是自由的,因此多个小数位并不重要。 - Ole V.V.

1
您所拥有的是标准的ISO 8601格式的完全指定时间戳。虽然java.util.Date等方法使其变得困难,但您可以在类路径中包含joda并使用以下咒语来操纵它:

System.out.println(ISODateTimeFormat.dateTime().print(DateTime.now());

祝你好运!

2
Joda-Time 项目现在处于维护模式。它的继任者是内置于Java 8中、由JSR 310定义的 java.time 类。Joda-Time和JSR 310都由同一人Stephen Colebourne领导。 - Basil Bourque

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接