java 如何解析 new Date().toString() 的输出

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4713825/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 07:40:10  来源:igfitidea点击:

how to parse output of new Date().toString()

javadate-format

提问by Daniel

I need a date format (maybe SimpleDateFormat) that parses reliable the output I get when I call toString() on a Date object. Output on my german(!) system is: "Sun Dec 12 13:45:12 CET 2010", so it doesn't seem to honor locales, which seems to make it easy.

我需要一种日期格式(可能是 SimpleDateFormat),它可以解析我在 Date 对象上调用 toString() 时获得的可靠输出。我的德语(!)系统上的输出是:“Sun Dec 12 13:45:12 CET 2010”,所以它似乎不尊重语言环境,这似乎很容易。

Anyone?

任何人?

回答by BalusC

That format is specified in the Date#toString().

该格式在Date#toString().

Converts this Dateobject to a Stringof the form:

dow mon dd hh:mm:ss zzz yyyy

将此Date对象转换String为以下形式的 a:

dow mon dd hh:mm:ss zzz yyyy

So, in SimpleDateFormatpattern terms:

所以,在SimpleDateFormat模式方面:

EEE MMM dd HH:mm:ss zzz yyyy


Unrelated to the problem, I wonder if it wasn't in first place a bad idea to use Date#toString()instead of SimpleDateFormat#format()to output dates. I would consider to fix it straight there.

与问题无关,我想知道使用Date#toString()而不是SimpleDateFormat#format()输出日期是否首先不是一个坏主意。我会考虑直接在那里修复它。

回答by Bozho

BalusC gave you the correct format, you I'd say - don't. The toString()method must not be used for anything other than logging.

BalusC 给了你正确的格式,我会说 - 不要。该toString()方法不得用于日志记录以外的任何其他用途。

You can use SimpleDateFormatfor both formatting and parsing.

您可以SimpleDateFormat用于格式化和解析。

回答by Ole V.V.

TL;DR

TL; 博士

    Instant parsedBack = Instant.parse(Instant.now().toString());
    System.out.println(parsedBack);

2019-05-30T08:36:47.966274Z

2019-05-30T08:36:47.966274Z

Use ISO 8601 and java.time

使用 ISO 8601 和 java.time

  1. If your real goal is to serialize and deserialize a date and time (for data transfer or for persistence, for example), serialize to ISO 8601, the standard format for date and time data.
  2. Skip the long outdated Dateclass. The modern Java date and time API known as java.timeis so much nicer to work with. The class you need from it is probably Instant(this depends on your more exact requirements).
  1. 如果您的真正目标是序列化和反序列化日期和时间(例如,用于数据传输或持久性),请序列化为 ISO 8601,即日期和时间数据的标准格式。
  2. 跳过早已过时的Date课程。现代 Java 日期和时间 API 使用起来java.time要好得多。您需要的课程可能是Instant(这取决于您更确切的要求)。

The two points go nicely hand in hand:

这两点很好地相辅相成:

    Instant i = Instant.now();
    String s = i.toString();
    Instant theSameInstant = Instant.parse(s);

The modern classes' toStringmethods produce ISO 8601 format (e.g., 2018-01-11T10:59:45.036Z), and their parsemethods read the same format back. So this snippet is all you need, and you get an instant equal to the first, with nanosecond precision.

现代类的toString方法产生 ISO 8601 格式(例如,2018-01-11T10:59:45.036Z),并且它们的parse方法读回相同的格式。所以这个片段就是你所需要的,你会得到一个与第一个相同的时刻,精度为纳秒。

If you cannot control the string you get, and you get the result from Date.toString(), the format pattern string in BalusC's answer works with java.timetoo:

如果您无法控制获得的字符串,并且从 中获得结果Date.toString(),则 BalusC 的答案中的格式模式字符串java.time也适用:

    DateTimeFormatter dtf 
            = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ROOT);
    Date d = new Date();
    String s = d.toString();
    Instant nearlyTheSameInstant = ZonedDateTime.parse(s, dtf).toInstant();

Some warnings, though:

不过有一些警告:

  1. Milliseconds from the original Dateare lost since they are not in the string, leading to an inaccuracy of up to 999 milliseconds (which was why I named the variable nearlyTheSameInstant).
  2. The era from the original Dateis not in the string either. So if your original Datewas in year 44 BCE, you will get the corresponding date in year 44 CE (AD) (in which case the variable name nearlyTheSameInstantwas a lie anyway).
  3. The time zone abbreviation in the string is often (most often?) ambiguous, so there is a great risk of getting the wrong time zone and hence a wrong time. To make matters worse, an ambiguous time zone abbreviation will be interpreted differently on different JVMs
  4. It's essential to provide a locale. Otherwise the JVM's default locale will be used, and if it's not English, parsing will fail. In the worst case you will see your code running fine for many years and suddenly it will break when one day someone runs it on a computer or device with a different locale setting. I use Locale.ROOTfor “the locale neutral locale” or “don't apply any locale specific processing”. It seems to be the correct approach here.
  1. 原始的毫秒数Date丢失了,因为它们不在字符串中,导致高达 999 毫秒的不准确(这就是我命名变量的原因nearlyTheSameInstant)。
  2. 原作的时代Date也不在弦上。因此,如果您的原件Date是在公元前 44 年,您将获得公元 44 年(公元)的相应日期(在这种情况下,变量名称nearlyTheSameInstant无论如何都是谎言)。
  3. 字符串中的时区缩写通常(最常见?)含糊不清,因此获取错误时区并因此获取错误时间的风险很大。更糟糕的是,一个不明确的时区缩写在不同的 JVM 上会有不同的解释
  4. 提供语言环境至关重要。否则将使用 JVM 的默认语言环境,如果不是英语,解析将失败。在最坏的情况下,您会看到您的代码运行良好多年,但有一天有人在具有不同区域设置的计算机或设备上运行它时,它会突然中断。我Locale.ROOT用于“语言环境中性语言环境”或“不应用任何语言环境特定处理”。这似乎是这里的正确方法。

Links

链接