繁体   English   中英

YAML、时间戳和 SnakeYAML 引擎

[英]YAML, timestamps, and SnakeYAML Engine

我不确定应该如何表示 YAML “时间戳”。 YAML 1.2 规范看来,YAML 似乎只是假设如果您有一个看起来像 ISO 8601 日期的字符串格式的值,那么除非您另有说明,否则它将被解析为日期。 以下是规范中的几个示例:

date: 2002-12-14
not-date: !!str 2002-04-28

YAML™ 版本 1.1 工作草案的时间戳语言独立类型(从 2005 年开始,目前是 15 年前!)似乎表明应该使用格式为tag:yaml.org,2002:timestamp的特殊标记。 它还表示!!timestamp的简写。

在 Java 中使用SnakeYAML Engine v2.0 ( org.snakeyaml:snakeyaml-engine:2.0 ) 我尝试解析2002-12-14表单,并得到一个字符串作为解析值,而不是任何类型的日期 ZA8CFDE6331BD59EB26666ZC4。 我看到 SnakeYAML Engine 存储库有一个使用!!timestamp方法的示例(例如::timestamp 2020-03-24T12.34:00.333 ),但这是最近的更改,我确定此支持是否已发布.

我尝试了fooBar: !!timestamp 2020-03-24fooBar: ::timestamp 2020-03-24T12.34:00.333的形式,但 SnakeYAML Engine 报告:

could not determine a constructor for the tag tag:yaml.org,2002:timestamp

那么在 YAML 中表示日期(特别是带有 YYYY-MM-DD 的本地日期)的官方方式是什么,以及最新的 YAML 规范中反映的正确方法是什么? SnakeYAML Engine 是否支持官方的 YAML 日期方法?

从 YAML 1.2 规范来看,YAML 似乎只是假设如果您有一个看起来像 ISO 8601 日期的字符串格式的值,那么除非您另有说明,否则它将被解析为日期。

不,YAML 规范给出了应该支持的三种模式(故障安全、JSON 和核心); 它们都不包含时间戳类型。 但是,如果使用支持它的模式,则可以解析看起来像时间戳的标量。 该规范仅告诉您,如果您想确保标量作为时间戳加载,请在其前面加上!!str

那么在 YAML 中表示日期(特别是带有 YYYY-MM-DD 的本地日期)的官方方式是什么。

您链接的!!timestamp定义最接近官方方式 但是,包含它的标签存储库不是规范的一部分,并且不需要实现来支持它。 此外,它是为过时的 YAML 1.1 定义的。

这意味着 SnakeYAML 根本不需要支持时间戳。 您可以在给出的示例中看到不包括时间戳支持; 该示例实现了加载时间戳本身。 您可以修改该代码以与普通公共接口一起使用:

class TimestampConstructor extends Constructor {
    public static final Pattern TIMESTAMP = Pattern
            .compile("^(?:[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]|[0-9][0-9][0-9][0-9]-[0-9][0-9]?-[0-9][0-9]?(?:[Tt]|[ \t]+)[0-9][0-9]?:[0-9][0-9]:[0-9][0-9](?:\\.[0-9]*)?(?:[ \t]*(?:Z|[-+][0-9][0-9]?(?::[0-9][0-9])?))?)$");
    public static final Tag TAG = new Tag(Tag.PREFIX + "timestamp");


    public TimestampConstructor() {
        this.yamlConstructors.put(TAG, new ConstructTimestamp());
    }

    private class ConstructTimestamp extends AbstractConstruct {
        public Object construct(Node node) {
            String val = (String) constructScalar(node);
            return LocalDateTime.parse(val);
        }
    }
}

然后,像这样使用它:

Yaml yaml = new Yaml(new TimestampConstructor());
yaml.addImplicitResolver(TimestampConstructor.TAG,
        TimestampConstructor.PATTERN, "0123456789");

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM