`DateTimeFormatter`在小数秒

时间:2016-08-11 01:39:13

标签: java parsing datetime-format java-time date-parsing

java.time类中,我们如何为DateTimeFormatter指定格式模式,允许完全停止(.)(句点或点)或COMMA({ {1}})作为小数秒的分隔符?

例如,以下内容适用于解析以,.0Z中的,0Z20090813145607.0Z结尾的输入日期值。

20090813145607,0Z

但是对于打印,输出包含两个,生成一对重复的小数秒。

  

20090813145607,0.0Z

所以我推断我在格式化模式中使用String input = "20090813145607.0Z"; DateTimeFormatter f = DateTimeFormatter.ofPattern ( "uuuuMMddHHmmss[,S][.S]X" ); 并不是获得此功能的正确方法。

[,S][.S]

我尝试使用传递DateTimeFormatter::withDecimalStyleDecimalStyle方法,但是在我的实验中没有像我预期的那样表现。文档并没有真正解释其预期的行为。

此问题很重要,因为ISO 8601标准建议使用COMMA但允许完全停止。两者都是在实践中常用的。

DecimalStyle无法容忍逗号

在java.time中,逗号和/或点的容差可能不可能decimal mark

我在Java 8 Update 102中尝试了以下代码。带有FULL STOP(点)的第一个输入成功,而带COMMA的第二个输入失败。

Instant

3 个答案:

答案 0 :(得分:4)

在点对逗号上,根据我的经验,点比逗号更常见。 RFC3339仅使用点XML schema。点不再是"首选" (根据wikipedia):

  

小数点,可以是逗号或点(没有任何偏好为   第22届大会CGPM第10号决议中所述   2003年,[16]但根据ISO优先使用逗号   8601:2004)

鉴于这一切,JSR-310更喜欢一个点。

import threading import time class LoopSimulation(threading.Thread): def __init__(self): threading.Thread.__init__(self) self.daemon = True # OK for main to exit even if instance still running self.lock = threading.Lock() self.j = 0 start_counting = threading.Thread.start # an alias for starting thread def run(self): for i in range(1000000): with self.lock: self.j = i time.sleep(0.5) def get_i(self): with self.lock: return self.j 类确实提供了一些控制,其中DateTimeFormatterBuilder.appendFraction方法与DecimalStyle一起用于从true输出小数点。

要解析点或逗号是不可能的。这被追踪为JDK-8132536,它解决了一般性问题,或者#34;解析中的概念。

使用ISO_INSTANT解析实例,其中表示"未使用本地化的十进制样式"。

因此,JSR-310的格式化程序无法达到你想要的效果。

答案 1 :(得分:1)

String fmt1 = "uuuuMMddHHmmss,SX";
String fmt2 = "uuuuMMddHHmmss.SX";
DateTimeFormatter f = DateTimeFormatter.ofPattern(fmt1);
TemporalAccessor dateObject = null;
try {
    dateObject = f.parse("20090813145607.0Z");
} catch (DateTimeParseException e) {
    f = DateTimeFormatter.ofPattern(fmt2);
    try {
        dateObject = f.parse(input);
    } catch (DateTimeParseException e1) { 
        throw new IllegalArgumentException("invalid format "+input);
    } 
} 

也许使用不同的RuntimeException子类,但这应该对你进行排序。

答案 2 :(得分:1)

(根据我的评论)

我是dbout if" DateTimeFormatter"允许这样的"或"图案。

我能想到的两个解决方法是

  1. 使用多个格式化程序。例如。一个用于,,一个用于.,如果第一个无法解析,则使用第二个。

    伪代码

    List<DateTimeFormatter> formatters = Arrays.asList(
            DateTimeFormatter.ofPattern( "uuuuMMddHHmmss.SX" ),
            DateTimeFormatter.ofPattern( "uuuuMMddHHmmss,SX" ));
    
    TemporalAccessor result = null;
    for (DateTimeFormatter f: formatters) {
        try {
            result = f.parse(input);
            break;
        } catch(DateTimeParseException ignored) {
        }
    }
    if (result == null) {
        throw new WhateverException();
    }
    
  2. &#34;规格化&#34;如果它是.,则将第三个最后一个字符替换为,,并且您可以使用一个格式化程序。 E.g。

    f = DateTimeFormatter.ofPattern( "uuuuMMddHHmmss.SX" )
    result = f.parse(input.matches(",..$")
                     ? input.replaceAll("^(.*),(..)$", "\\1.\\2")
                     : input);