java - java 将字符串转换为日期时间

标签 java date-format date-formatting localdate dateformatter

字符串必须转换为 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);
                }
            }

最佳答案

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

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

关于java - java 将字符串转换为日期时间,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58084723/

相关文章:

Java 应用程序正常运行时间未按预期显示

mysql - phpMyAdmin 中的德国日期?

java - ARCore – WorldScale 和 LocalScale 有什么区别?

java - 查询选择不同的行和自动生成的测试 ID 的最大值?

java - HashMap 和数组在查找时间复杂度上的区别

objective-c - NSDateFormatter 崩溃。怎么会?

matplotlib - 在 matplotlib 中向日期格式的时间序列添加垂直线

java - 对常量使用接口(interface)还是类?

Java/Apache Velocity date.format 给出错误的年份

java - 使用 Struts 显示带有外语字母的日期