代码之家  ›  专栏  ›  技术社区  ›  YK S

解析作为查询参数传递给restapi的不同日期的标准方法是什么?

  •  0
  • YK S  · 技术社区  · 6 年前

    yyyy-mm-dd[(T| )HH:MM:SS[.fff]][(+|-)NNNN] 
    

    这意味着以下是有效日期:

    2017-05-05 00:00:00.000+0000
    2017-05-05 00:00:00.000
    2017-05-05T00:00:00
    2017-05-05+0000
    2017-05-05
    

    现在来解析我使用的所有这些不同的日期时间 Java8 datetime 应用程序编程接口。代码如下:

    DateTimeFormatter formatter = new DateTimeFormatterBuilder().parseCaseInsensitive()
        .append(DateTimeFormatter.ofPattern("yyyy-MM-dd[[ ][['T'][ ]HH:mm:ss[.SSS]][Z]"))
        .toFormatter(); 
    LocalDateTime localDateTime = null;
    LocalDate localDate = null;
    ZoneId zoneId = ZoneId.of(ZoneOffset.UTC.getId());
    Date date = null;
    
    try {
        localDateTime = LocalDateTime.parse(datetime, formatter);
        date = Date.from(localDateTime.atZone(zoneId).toInstant());
    } catch (Exception exception) {
        System.out.println("Inside Excpetion");
        localDate = LocalDate.parse(datetime, formatter);
        date = Date.from(localDate.atStartOfDay(zoneId).toInstant());
    }
    

    从我使用的代码中可以看出 DateTimeFormatter LocalDateTime try-block 如果它抛出了一个例外,比如 2017-05-05 由于时间不多,我正在使用 LocalDate catch block

    上面的方法为我提供了我正在寻找的解决方案,但我的问题是,这是处理以字符串形式发送的日期的标准方法吗?我的方法是否符合这些标准?

    另外,如果可能的话,除了一些简单的解决方案,比如使用数组列表,放置所有可能的格式,然后使用for循环尝试解析日期之外,还有什么其他方法可以解析不同类型的日期(上面显示为有效日期)?

    2 回复  |  直到 6 年前
        1
  •  2
  •   Anonymous    6 年前
        DateTimeFormatter formatter = new DateTimeFormatterBuilder()
                .append(DateTimeFormatter.ISO_LOCAL_DATE)
                // time is optional
                .optionalStart()
                .parseCaseInsensitive()
                .appendPattern("[ ]['T']")
                .append(DateTimeFormatter.ISO_LOCAL_TIME)
                .optionalEnd()
                // offset is optional
                .appendPattern("[xx]")
                .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
                .parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
                .toFormatter();
        for (String queryParam : new String[] {
                "2017-05-05 00:00:00.000+0000",
                "2017-05-05 00:00:00.000",
                "2017-05-05T00:00:00",
                "2017-05-05+0000",
                "2017-05-05",
                "2017-05-05T11:20:30.643+0000",
                "2017-05-05 16:25:09.897+0000",
                "2017-05-05 22:13:55.996",
                "2017-05-05t02:24:01"
        }) {
            Instant inst = OffsetDateTime.parse(queryParam, formatter).toInstant();
            System.out.println(inst);
        }
    

    此代码段的输出是:

    2017-05-05T00:00:00Z
    2017-05-05T00:00:00Z
    2017-05-05T00:00:00Z
    2017-05-05T00:00:00Z
    2017-05-05T00:00:00Z
    2017-05-05T11:20:30.643Z
    2017-05-05T16:25:09.897Z
    2017-05-05T22:13:55.996Z
    2017-05-05T02:24:01Z
    

    我使用的技巧包括:

    • optionalStart optionalEnd 或在 []
    • DateTimeFormatter.ISO_LOCAL_TIME 已经处理可选的秒数和秒的分数。
    • 用于解析为 OffsetDateTime parseDefaulting 这是真的。

    Date . 这个 java.util.Date 类已经过时很久了,并且有很多设计问题,所以尽可能避免它。 Instant 会很好的。如果你真的需要 对于您现在无法更改或不想更改的遗留API,请按照问题中的方法进行转换。

    编辑:现在默认 HOUR_OF_DAY ,不是 MILLI_OF_DAY . 后者在只有毫秒丢失的情况下引发了冲突,但格式化程序似乎只对丢失时间的默认小时感到满意。

        2
  •  0
  •   Leon    6 年前

    我通常用 DateUtils.parseDate commons-lang

    此方法如下所示:

    public static Date parseDate(String str,
                             String... parsePatterns)
                      throws ParseException
    

    描述如下:

    解析将依次尝试每个解析模式。只有当解析整个输入字符串时,解析才会被视为成功。如果没有匹配的解析模式,则抛出ParseException。

        3
  •  0
  •   Mirza Shujathullah    4 年前
    @Configuration
    public class DateTimeConfig extends WebMvcConfigurationSupport {
        /**
         * https://docs.spring.io/spring-framework/docs/current/reference/html/core.html#format-configuring-formatting-globaldatetimeformat
         * @return
         */
    
        @Bean
        @Override
        public FormattingConversionService mvcConversionService() {
            DefaultFormattingConversionService conversionService = new DefaultFormattingConversionService(false);
            conversionService.addFormatterForFieldAnnotation(new NumberFormatAnnotationFormatterFactory());
    // Register JSR-310 date conversion with a specific global format
            DateTimeFormatterRegistrar dateTimeRegistrar = new DateTimeFormatterRegistrar();
            dateTimeRegistrar.setDateTimeFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
            dateTimeRegistrar.setDateTimeFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
           dateTimeRegistrar.setDateTimeFormatter(DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss'Z'"));
           dateTimeRegistrar.registerFormatters(conversionService);
    
      // Register date conversion with a specific global format
            DateFormatterRegistrar dateRegistrar = new DateFormatterRegistrar();
            dateRegistrar.setFormatter(new DateFormatter("yyyy-MM-dd"));
            dateRegistrar.setFormatter(new DateFormatter("yyyy-MM-dd HH:mm:ss"));
            dateRegistrar.setFormatter(new DateFormatter("yyyy-MM-dd'T'HH:mm:ss'Z'"));
            dateRegistrar.registerFormatters(conversionService);
            return conversionService;
        }
    }