SimpleDateFormat 转换为 java.time

3
我正在尝试理解Java 8日期/时间框架的工作原理。
实际上,我是这样使用SimpleDateFormat返回一个字符串表示的毫秒数:
new SimpleDateFormat("yyyyMMddHHmmssSSS").parse(builder.toString()).getTime();

Java 8中的新类会有哪些变化?


2
您期望的格式接近于标准ISO 8601格式。我强烈建议您坚持使用标准格式,而不是自己发明格式。该标准被明智地设计为避免歧义。并且在java.time类中默认使用这些格式来解析/生成字符串。您的格式接近于“基本”版本,最小化使用分隔符。要完全符合规范,请(a)在年-月-日和时-分-秒之间插入T,(b)在小数秒之前插入逗号(最好)或句号(周期)。 - Basil Bourque
2个回答

2
您指定的模式在Java-8中无法工作。该问题已在Java-9中得到修复,但似乎没有回溯到Java-8,而Java-9尚未发布。
可能的Java-8解决方法包括笨拙的字符串预处理,即在小数部分之前插入十进制分隔符,或者下载其他第三方库(根据我的观察,其中的解析器可能仍比Java-9更快): 字符串预处理
String mydate = "20130812214600025";
String adjustedInput = new StringBuilder(mydate).insert(14, '.').toString();
ZonedDateTime date =
    ZonedDateTime.parse(
        adjustedInput,
        DateTimeFormatter.ofPattern("yyyyMMddHHmmss.SSS").withZone(ZoneOffset.systemDefault()));
System.out.println(date); // 2013-08-12T21:46:00.025+02:00[Europe/Berlin]
System.out.println(date.toInstant().toEpochMilli()); // 1376336760025

Joda-Time:

String mydate = "20130812214600025";
DateTime date =
    DateTime.parse(
        mydate,
        DateTimeFormat.forPattern("yyyyMMddHHmmssSSS"));
System.out.println(date); // 2013-08-12T21:46:00.025+02:00
System.out.println(date.toInstant().getMillis()); // 1376336760025

My library Time4J

long millisSinceUnix =
    ChronoFormatter.ofPattern(
        "yyyyMMddHHmmssSSS",
        PatternType.CLDR,
        Locale.ROOT,
        Moment.axis(TemporalType.MILLIS_SINCE_UNIX)
    ).with(Timezone.ofSystem()).parse(mydate).longValue();
System.out.println(millisSinceUnix); // 1376336760025

供您参考:时区信息是必要的,因为我们将本地的年、月、日、小时等细节转换为全球瞬间,但您的输入不包含任何区域或偏移信息。因此,必须向格式化程序提供一个区域或偏移量。
正如您所见,SimpleDateFormat 和 Joda-Time 默认(隐式地)使用系统时区。然而,java.time-API 和 Time4J 要求显式指定时区(在我看来这是更清晰的设计)。

1

您可以使用:

ZonedDateTime date = ZonedDateTime.parse("mydate",DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS"));
System.out.println(date.toInstant().toEpochMilli());

1
这给了我一个错误:“在索引0处无法解析文本'20140920111703000'”。 - LppEdd

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