【问题标题】:convert String to DateTime java [duplicate]将字符串转换为日期时间 java [重复]
【发布时间】:2020-01-24 20:08:15
【问题描述】:

必须将字符串转换为 LocalDateTime 类型 - “yyyy-MM-dd'T'HH:mm:ss”。

几秒钟后忽略任何内容。

尝试了这段代码,但几秒钟后出现的任何错误都会出错。

String testDate = "2019-09-17T23:38:47";



LocalDateTime lDate = null;
            if (!StringUtils.isEmpty(testDate) && !"".equals(testDate)) {
                DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
                try {
                    sqlDate = LocalDateTime.parse(testDate, formatter);
                    log.info("Converted SQL date=" + lDate );
                } catch (Exception ex) {
                    log.error("Error in parsing lDate " +ex);
                }
            }

【问题讨论】:

    标签: java date-format date-formatting localdate dateformatter


    【解决方案1】:

    试试这个:(+异常处理)

    String testDate = "2019-09-17T23:38:47.342";
    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
    java.util.Date date = format.parse(testDate);
    LocalDateTime localDateTime = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
    System.out.println(localDateTime);
    System.out.println(localDateTime.getNano());
    

    输出:

    2019-09-17T23:38:47
    0
    

    如您所见,小数秒已被消除。

    编辑:
    这是一个具有更新日期时间类的解决方案:

    DateTimeFormatter format = new DateTimeFormatterBuilder()
        .appendPattern("yyyy-MM-dd'T'HH:mm:ss")
        .appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true)
        .toFormatter();
    LocalDateTime date1 = LocalDateTime.parse("2019-09-17T23:38:47", format).withNano(0);
    LocalDateTime date2 = LocalDateTime.parse("2019-09-17T23:38:47.342", format).withNano(0);
    System.out.println(date1);
    System.out.println(date2);
    

    输出:

    2019-09-17T23:38:47
    2019-09-17T23:38:47
    

    编辑 2:
    我构建了一个示例,说明如何使用正则表达式和格式字符串处理不同类型的输入:

    InputDatePattern.java

    public enum InputDatePattern
    {
        WITH_TIMESTAMP("\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{0,9})?", Optional.of("yyyy-MM-dd'T'HH:mm:ss")), 
        WITHOUT_TIMESTAMP("\\d{4}-\\d{2}-\\d{2}", Optional.of("yyyy-MM-dd")),
        TIMESTAMP_ONLY("\\d{2}:\\d{2}:\\d{2}(\\.\\d{0,9})?", Optional.of("HH:mm:ss")),
        UNKNOWN(".*", Optional.empty()); // must come last, since elements are matched in order
        private final Pattern pattern;
        private final Optional<DateTimeFormatter> formatter;
    
        private static final LocalDate DEFAULT_DATE = LocalDate.EPOCH;
        private static final LocalTime DEFAULT_TIME = LocalTime.MIDNIGHT;
        private static final Logger log = Logger.getLogger(Logger.class.getName());
    
        private InputDatePattern(String regex, Optional<String> format)
        {
            pattern = Pattern.compile(regex);
            var formatter = Optional.of(new DateTimeFormatterBuilder());
            formatter.ifPresent(f -> format.ifPresent(f::appendPattern));
            formatter.ifPresent(f -> f.appendFraction(ChronoField.NANO_OF_SECOND, 0, 9, true));
            this.formatter = formatter.map(DateTimeFormatterBuilder::toFormatter);
        }
    
        public boolean matches(String type)
        {
            return pattern.matcher(type).matches();
        }
    
        public Optional<LocalDateTime> toLocalDateTime(String dateString)
        {
            try
            {
                switch(this)
                {
                case WITH_TIMESTAMP:
                    return formatter.map(f -> LocalDateTime.parse(dateString, f).withNano(0));
                case WITHOUT_TIMESTAMP:
                    return toLocalDate(dateString).map(date -> date.atTime(DEFAULT_TIME).withNano(0));
                case TIMESTAMP_ONLY:
                    return toLocalTime(dateString).map(date -> date.atDate(DEFAULT_DATE).withNano(0));
                case UNKNOWN:
                    return Optional.empty();
                default:
                    throw new IllegalStateException("Attempting conversion with unknown InputDatePattern!");
                }
            }
            catch(DateTimeParseException e)
            {
                log.info(e.getMessage());
                return Optional.empty();
            }
        }
    
        public Optional<LocalDate> toLocalDate(String dateString)
        {
            try
            {
                switch(this)
                {
                case WITH_TIMESTAMP:
                case WITHOUT_TIMESTAMP:
                    return formatter.map(f -> LocalDate.parse(dateString, f));
                case TIMESTAMP_ONLY:
                case UNKNOWN:
                    return Optional.empty();
                default:
                    throw new IllegalStateException("Attempting conversion with unknown InputDatePattern!");
                }
            }
            catch(DateTimeParseException e)
            {
                log.info(e.getMessage());
                return Optional.empty();
            }
        }
    
        public Optional<LocalTime> toLocalTime(String dateString)
        {
            try
            {
                switch(this)
                {
                case WITH_TIMESTAMP:
                case TIMESTAMP_ONLY:
                    return formatter.map(f -> LocalTime.parse(dateString, f));
                case WITHOUT_TIMESTAMP:
                case UNKNOWN:
                    return Optional.empty();
                default:
                    throw new IllegalStateException("Attempting conversion with unknown InputDatePattern!");
                }
            }
            catch(DateTimeParseException e)
            {
                log.info(e.getMessage());
                return Optional.empty();
            }
        }
    
        public static InputDatePattern forDateString(String dateString)
        {
            for(InputDatePattern pattern : InputDatePattern.values())
            {
                if(pattern.matches(dateString))
                    return pattern;
            }
            return InputDatePattern.UNKNOWN;
        }
    }
    

    Demo.java

    public class Demo
    {
        public static void main(String[] args)
        {
            String[] trying = {"2019-09-17T23:38:00", "2019-09-17T23:38:00.123",
                    "2019-09-17", "bad input", "09:12:13.45"};
            for(String str : trying)
            {
                InputDatePattern pattern = InputDatePattern.forDateString(str);
                System.out.format("Input pattern type for %s is %s%n", str, pattern);
                Optional<LocalDateTime> localDateTime = pattern.toLocalDateTime(str);
                if(localDateTime.isPresent())
                {
                    System.out.println("The corresponding LocalDateTime is: "+localDateTime.get());
                }
                else
                {
                    System.out.format("Unknown type of LocalDateTime! Bad input=\"%s\"%n",str);
                }
            }
        }
    }
    

    输出:

    Input pattern type for 2019-09-17T23:38:00 is WITH_TIMESTAMP
    The corresponding LocalDateTime is: 2019-09-17T23:38
    Input pattern type for 2019-09-17T23:38:00.123 is WITH_TIMESTAMP
    The corresponding LocalDateTime is: 2019-09-17T23:38
    Input pattern type for 2019-09-17 is WITHOUT_TIMESTAMP
    The corresponding LocalDateTime is: 2019-09-17T00:00
    Input pattern type for bad input is UNKNOWN
    Unknown type of LocalDateTime! Bad input="bad input"
    Input pattern type for 09:12:13.45 is TIMESTAMP_ONLY
    The corresponding LocalDateTime is: 1970-01-01T09:12:13
    

    【讨论】:

    • @RealSkeptic 此解决方案消除了小数秒。
    • OP 的问题是他们得到了一个日期字符串,其中 包含 小数秒并且需要对其进行解析。您的示例不包括这些。
    • @JNPW 将 vars 更改为类名 :)
    • @Avi 在这个工作中我在想如果我只得到没有时间戳的日期只有 yyyy-MM-dd 怎么办。我还能在不出错的情况下消费这个日期吗?
    • @JNPW 如果您的输入与预期的模式不匹配,您将遇到问题。我建议先检查匹配的类型,然后根据匹配的模式将字符串分派到适当的 DateTimeFormatter。
    猜你喜欢
    • 1970-01-01
    • 2016-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-30
    • 2017-11-20
    • 1970-01-01
    相关资源
    最近更新 更多