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

如何使用默认区域解析ZoneDateTime?

阮梓
2023-03-14

如何从不包含zone和其他字段的字符串中解析ZoneDateTime?

以下是在斯波克进行的测试:

import spock.lang.Specification
import spock.lang.Unroll

import java.time.ZoneId
import java.time.ZoneOffset
import java.time.ZonedDateTime
import java.time.format.DateTimeFormatter

@Unroll
class ZonedDateTimeParsingSpec extends Specification {
    def "DateTimeFormatter.ISO_ZONED_DATE_TIME parsing incomplete date: #value #expected"() {
        expect:
        ZonedDateTime.parse(value, DateTimeFormatter.ISO_ZONED_DATE_TIME) == expected
        where:
        value                           | expected
        '2014-04-23T04:30:45.123Z'      | ZonedDateTime.of(2014, 4, 23, 4, 30, 45, 123_000_000, ZoneOffset.UTC)
        '2014-04-23T04:30:45.123+01:00' | ZonedDateTime.of(2014, 4, 23, 4, 30, 45, 123_000_000, ZoneOffset.ofHours(1))
        '2014-04-23T04:30:45.123'       | ZonedDateTime.of(2014, 4, 23, 4, 30, 45, 123_000_000, ZoneId.systemDefault())
        '2014-04-23T04:30'              | ZonedDateTime.of(2014, 4, 23, 4, 30, 0, 0, ZoneId.systemDefault())
        '2014-04-23'                    | ZonedDateTime.of(2014, 4, 23, 0, 0, 0, 0, ZoneId.systemDefault())
    }
}

前两个测试通过,所有其他测试都通过了DateTimeParseException:

  • '2014-04-23T04:30:45.123'无法在索引23处解析
  • '2014-04-23T04:30'无法在索引16处解析
  • '2014-04-23'无法在索引10处解析

如何解析时间和区域设置为默认的不完整日期?

共有2个答案

吉岳
2023-03-14

格式化程序有一个with Zone()方法,可以调用该方法来提供丢失的时区。

ZonedDateTime.parse(
    value,
    DateTimeFormatter.ISO_ZONED_DATE_TIME.withZone(ZoneId.systemDefault()))

请记住,有一个错误,所以您需要8u20或更高版本才能完全工作。

楚羽
2023-03-14

由于格式化程序需要区域或偏移量信息,因此解析失败。您必须制作一个日期时间格式(DateTimeFormatter),其中包含区域信息和时间部分的可选部分。反向工程ZonedDateTimeFormatter并添加可选标记并不难。

然后使用格式化程序的parseBest()方法解析String。然后,对于次优的解析结果,您可以使用所需的任何默认值创建ZonedDateTime

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .parseCaseInsensitive()
        .append(ISO_LOCAL_DATE)
        .optionalStart()           // time made optional
        .appendLiteral('T')
        .append(ISO_LOCAL_TIME)
        .optionalStart()           // zone and offset made optional
        .appendOffsetId()
        .optionalStart()
        .appendLiteral('[')
        .parseCaseSensitive()
        .appendZoneRegionId()
        .appendLiteral(']')
        .optionalEnd()
        .optionalEnd()
        .optionalEnd()
        .toFormatter();

TemporalAccessor temporalAccessor = formatter.parseBest(value, ZonedDateTime::from, LocalDateTime::from, LocalDate::from);
if (temporalAccessor instanceof ZonedDateTime) {
    return ((ZonedDateTime) temporalAccessor);
}
if (temporalAccessor instanceof LocalDateTime) {
    return ((LocalDateTime) temporalAccessor).atZone(ZoneId.systemDefault());
}
return ((LocalDate) temporalAccessor).atStartOfDay(ZoneId.systemDefault());
 类似资料:
  • 问题内容: 我需要将使用的字符串用户ID解析为整数,但是如果存在/具有非小数/整数值的字符串,则返回null / nil,在这种情况下,我需要将默认整数值指定为。 我试过了,但似乎不起作用,我不知道它是否正确。 如果分配为空,如何为整数分配默认值? 字符串userid是Web服务函数调用中的一部分参数,因此无法将其数据类型更新为整数。 问题答案: 您可以使用正则表达式尝试此方法。

  • 在Graphql工具文档的默认解析器部分中,它声明 从obj返回具有相关字段名的属性,或 https://www.apollographql.com/docs/graphql-tools/resolvers.html#Default-resolver 类型def: 给定此查询解析器: 因此,如果我像这样手动定义解析器,它就会工作。 但是,如果我删除定义并依赖默认解析功能,它将无法工作。 我希望它调

  • 问题内容: 我有一个称为Product的类和一些扩展它的子类。现在在我的注释中,我有很多类型,例如: 然后定义我的Product类。我想做的是,如果Jackson无法检测到该字段不符合任何这些结构,则返回 未知产品 我该如何使用Jackson @Type注释呢?它应该像是在名称中插入空白或在我实际上不知道的值中添加一些标志(我尝试创建扩展Product的UnknownProduct,并且在名称值中

  • 我安装了php5.6.6作为apache 2.4模块。 当加载带有 因此,正如文档所建议的,我编辑了httpd.conf指向php.ini配置文件(在C:\php56中)。我还添加了C:\php56到PATH和PHPRC环境变量。 由于我在这个文件夹中没有任何php.ini文件,我复制并重命名了“php.ini生产”文件,并编辑了扩展路径。 当我再次显示页面时,它将保持空白。。。下面是“php--

  • 问题内容: 我想解析Go中的JSON对象,但想为未指定的字段指定默认值。例如,我具有struct类型: A,B和C的默认值分别是“ a”,“ b”和“ c”。这意味着当我解析json时: 我想得到的结构: 使用内置包可以吗?否则,是否有任何具有此功能的Go库? 问题答案: 使用encoding / json可以实现:调用时,不需要给它一个空结构,可以给它一个默认值。 例如: 在Go操场上运行此示例