首页 > 解决方案 > java 8 日期/时间 API:使用通用日期/时间格式解析以提取自纪元以来的毫秒数

问题描述

给定任何日期/时间格式(由用户传递),我需要用它解析日期并返回自 java epoch 以来的毫秒数,这可以使用旧日期 API 使用以下代码完成:

//dateFormatter is SimpleDateFormat
Date d = dateFormatter.parse(value);
return d.getTime();

对包含日期部分的格式的唯一要求,例如以下所有可能的格式:

"dd/MM/yyyy"
"dd/MM/yyyy HH:mm X" //with timezone

缺少的部分以当天/当地时区的开始完成。所以我想出了以下内容,这似乎更加冗长,并且不确定是否有更有效的方法来做到这一点:

        //dateFormatter is DateTimeFormatter
        TemporalAccessor ta = dateFormatter.parse(value);
        
        LocalDate ld = LocalDate.from(ta); //assume must have date part

        LocalTime lt = ta.query(TemporalQueries.localTime());
        if (lt == null) {
            lt = LocalTime.MIN;
        }
        
        ZoneId zoneId = ta.query(TemporalQueries.zone());
        if (zoneId == null) {
            zoneId = ZoneId.systemDefault();
        }
        
        Instant d = LocalDateTime.of(ld, lt).atZone(zoneId).toInstant();
        return d.toEpochMilli();

标签: javadatetime

解决方案


用于DateTimeFormatterBuilder.parseDefaulting在格式字符串中找不到该字段时设置默认值:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
        .appendPattern(patternFromTheUser)
        // make everything non-required default to 0
        .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
        .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
        .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
        .parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
        .toFormatter();
System.out.println(ZonedDateTime.parse("01/01/2021 20:00", formatter)
        .toInstant()
        .toEpochMilli());

推荐阅读