当前位置: 首页 > 知识库问答 >
问题:

Java8:将文件时间(1970年的毫秒)转换为RFC 1123格式

穆俊杰
2023-03-14

这看起来应该很简单,但到目前为止,我尝试的方法都不管用。基本上,我想将一个文件时间(以毫秒为单位)从1970年(通常)转换为一个临时的Accessor,然后再转换为一个RFC1123格式的字符串。然而,虽然我可以得到编译的示例,但也会出现运行时错误。例如:

// Just using 0 milliseconds time for quick and easy test
System.out.println(java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME.format(
                FileTime.from(0, TimeUnit.MILLISECONDS).toInstant()));

结果

线程“main”java中出现异常。时间世俗的UnsupportedTemporalTypeException:不支持的字段:DayOfMonth

我使用不同的类(Instant、LocalTime、Date)尝试了一些变体,但我得到了相同的结果。

正确的html" target="_blank">方法是什么?

更新:最初的问题已经得到了技术上的回答,我意识到我需要更具体一些。我自己已经“成功地”将毫秒转换成了一个临时的Accessor,但是这个对象似乎没有处于可用状态。当我试图用它来做我真正需要的事情时,我遇到了一个运行时错误,这让我相信我没有正确地创建它。有些东西不见了。要么是这样,要么RFC 1123格式化程序中存在错误。

更新2:感谢Sleafar发布了一个有效的答案。

以他的例子来说,我的做法略有不同,因为出于某种原因,我真的希望有一个“完整的”临时助理来处理这些事情。以下是一个有效的例子:

TemporalAccessor time = ZonedDateTime.ofInstant(Instant.ofEpochMilli(0),
ZoneId.systemDefault());
System.out.println(
        java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME.format(time));

共有3个答案

丁良骏
2023-03-14

到Instant的转换成功,没有问题。问题在于格式化程序。使用ISO_INSTANT formatter而不是RFC_1123_DATE_TIME,然后您应该:

        inst = Instant.now();
        System.out.println(java.time.format.DateTimeFormatter.ISO_INSTANT
                           .format( inst ) );

--

如果您真的想要RFC_1123格式,您必须声明一个时区。

将其附加到格式化程序:

        System.out.println(java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME
                           .withZone( ZoneOffset.UTC )
                           .format( inst ) );

或将Instant转换为ZonedDateTime:

        ZonedDateTime zdt = ZonedDateTime.ofInstant( inst, ZoneOffset.UTC );
        System.out.println(java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME
                           .format( zdt ) );

--

汝宏伯
2023-03-14

自1970年以来的毫秒被称为“大纪元时间”,Instant使用静态方法Instant。ofEpochMilli(long)支持从毫秒数创建。从概念上讲,Instant表示“标准Java时代”中的一个瞬间(longsecondsintnanoseconds),因此将文件时间表示为一个瞬间是正确的JSR-310方法。

FileTime还有一个fromMillis(long)静态方法,用于相同的目的。

在这种情况下,转换不是问题,而是缺少Sleafar首先确定的时区,这反映在您编辑的问题中。

谭飞掣
2023-03-14

Instant类型不包含时区信息。您可以像这样为格式化程序定义时区:

System.out.println(java.time.format.DateTimeFormatter.RFC_1123_DATE_TIME
    .withZone(ZoneId.systemDefault()).format( FileTime.from(0, TimeUnit.MILLISECONDS).toInstant()));

编辑:

实际上,有理由使用没有分配时区的格式化程序,以及表示类的日期/时间。考虑以下示例:

ZoneId ect = ZoneId.of(ZoneId.SHORT_IDS.get("ECT"));

DateTimeFormatter f1 = DateTimeFormatter.RFC_1123_DATE_TIME;
DateTimeFormatter f2 = f1.withZone(ect);
DateTimeFormatter f3 = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
DateTimeFormatter f4 = f3.withZone(ect);

LocalDateTime ldt = LocalDateTime.of(2015, 07, 21, 0, 0, 0, 0);
ZonedDateTime zdt = ZonedDateTime.of(ldt, ect);
Instant ins = zdt.toInstant();

System.out.println(f1.format(ins)); // throws exception (1)
System.out.println(f2.format(ins)); // Tue, 21 Jul 2015 00:00:00 +0200
System.out.println(f3.format(ins)); // throws exception (2)
System.out.println(f4.format(ins)); // 2015-07-21T00:00:00

System.out.println(f1.format(zdt)); // Tue, 21 Jul 2015 00:00:00 +0200
System.out.println(f2.format(zdt)); // Tue, 21 Jul 2015 00:00:00 +0200
System.out.println(f3.format(zdt)); // 2015-07-21T00:00:00
System.out.println(f4.format(zdt)); // 2015-07-21T00:00:00

System.out.println(f1.format(ldt)); // throws exception (3)
System.out.println(f2.format(ldt)); // throws exception (4)
System.out.println(f3.format(ldt)); // 2015-07-21T00:00:00
System.out.println(f4.format(ldt)); // 2015-07-21T00:00:00

ZoneId hst = ZoneId.of(ZoneId.SHORT_IDS.get("HST"));
ZonedDateTime zdt2 = ZonedDateTime.of(ldt, hst);

System.out.println(f1.format(zdt2)); // Tue, 21 Jul 2015 00:00:00 -1000
System.out.println(f2.format(zdt2)); // Tue, 21 Jul 2015 12:00:00 +0200
System.out.println(f3.format(zdt2)); // 2015-07-21T00:00:00
System.out.println(f4.format(zdt2)); // 2015-07-21T12:00:00
  • Instant表示一个实际的时间点,不涉及特定的位置,因此没有时区。提出异常(1)和(2)是因为为了表示特定的时间点,格式化程序需要一个时区,以使输出对人类可读
  • ZoneDateTime表示也分配给特定时区的实际时间点。格式化它们一点问题都没有,但考虑最后一个例子。如果在格式化程序中设置时区,可能会得到不同的结果
  • LocalDateTime不代表实际的时间点。你甚至可以指定一个在某些时区无效的值,比如在夏令时时钟向前拨1小时。要获得一个真正的时间点,你必须将它与时区结合起来(就像上面的例子中所做的那样)。引发了异常(3)和(4),因为格式化程序想要打印一个时区值,而这种类型中不存在该值

我不明白为什么设计师选择在运行时而不是编译时发现所描述的问题。也许这会让类的层次结构变得太复杂。

 类似资料:
  • 我从GPS接收机接收到一个时间戳,它以秒后的微秒时间表示:

  • 我想把UTC的时间戳转换成Postgres中的毫秒。我在Ruby控制台上使用这个查询(使用Postgres)。我的问题是: 以上查询结果, 2018年7月5日星期四05:05:39 UTC 00:00至1530767139732.35 输出看起来不错,但在“.”之后我不需要35岁。有没有办法得到13位毫秒的输出。 我会很感激你的帮助。

  • 问题内容: 如何在Linux中手动将抖动转换为毫秒,反之亦然?我知道内核2.6具有此功能,但是我正在研究2.4(家庭作业),尽管我看了一下代码,但它使用了许多宏常量,我不知道它们是否在2.4中定义。 问题答案: 如先前的回答所述,增量的速率是固定的。 为接受的函数指定时间的标准方法是使用常数。 那是Hertz的缩写,或每秒的刻度数。在计时器滴答设置为1ms的系统上,HZ = 1000。一些发行版或

  • 问题内容: 我已使用ruby脚本将iso时间戳转换为纪元,我正在解析的文件具有以下时间戳结构: 由于我想保留毫秒,因此我使用了以下Ruby代码将其转换为纪元时间: 但是在python中,我尝试了以下操作: 但是我没有把原定的时间日期倒退, 我想知道这与我的格式化方式有关吗? 问题答案: 用途: 指令仅受支持,而不受。 UPDATE 替代使用,:

  • 问题内容: 这是我的代码: 是否可以在日期格式中添加毫秒和纳秒? 问题答案: 您可以通过在末尾添加来添加毫秒数,例如格式为。 毫微秒内没有参考。通常用于性能调试,而不用于显示目的。

  • 我有一个Unix历元时间戳(以毫秒为单位),需要获取本地时间的日期字符串。 这是我的代码: 由上述函数生成的原始时间戳和结果日期、小时和所有其他值均以UTC为单位。如何更改代码以在当地时间获取它?