将字符串映射为不同的日期格式

时间:2019-04-26 10:43:53

标签: java date java-8

我有一个要求,我必须以任何格式将值作为json从传入请求映射到Date。 例如,在我的请求中,我可以使用以下任何一种格式获取日期字符串:

 1. 03/22/1990 -- MM/dd/yyyy
 2. 03/22/1990 12:34:45 
 3. 03/22/1990 12:23 AM 

如何将传入的映射值映射到Date。

5 个答案:

答案 0 :(得分:2)

您可以使用正则表达式轻松识别您提到的三种格式。例如,模式\d\d\/\d\d\/\d\d\d\d \d\d:\d\d:\d\d将与示例中的第二个字符串匹配,但与其他两个字符串不匹配。

然后,您可以将SimpleDateFormatter与已标识的格式一起使用。例如

SimpleDateFormat format = new SimpleDateFormat("dd/MM/yyyy"); 
Date date =formatter1.parse(dateString);

答案 1 :(得分:1)

我建议您可以使用JodaTime库来实现这一点

您可以使用多个解析器,并通过使用DateTimeFormatterBuilder.append方法将它们添加到构建器中:

DateTimeParser[] parsers = { 
        DateTimeFormat.forPattern( "MM/dd/yyyy" ).getParser(),
        DateTimeFormat.forPattern( "MM/dd/yyyy HH:mm:ss" ).getParser(),
        DateTimeFormat.forPattern( "MM/dd/yyyy HH:mm tt" ).getParser() 
};
DateTimeFormatter formatter = new DateTimeFormatterBuilder().append( null, parsers ).toFormatter();

DateTime date1 = formatter.parseDateTime( "03/22/1990" );
DateTime date2 = formatter.parseDateTime( "03/22/1990 10:34:11" );

答案 2 :(得分:0)

如果出于某种原因需要使用Java.time,则可以使用以下内容:

private Timestamp parseDateFromString(String dateString) {
    if (StringUtils.isNotBlank(dateString)) {
        try {
            final DateFormat df = new SimpleDateFormat("MM/dd/yyyy");
            final Date date = df.parse(dateString);
            return new Timestamp(date.getTime());
        } catch (ParseException e) {
            log.error("Error parsing string: " + dateString, e);
        }
    }
    return null;
}

答案 3 :(得分:0)

因此,您可以使用这一解决方案

private Date parse(final String date) {
    return parseDate(date, "MM/dd/yyyy HH:mm a")
        .orElseGet(() -> parseDate(date, "MM/dd/yyyy HH:mm:ss")
            .orElseGet(() -> parseDate(date, "MM/dd/yyyy").orElse(null)));
}

private Optional<Date> parseDate(String date, String pattern) {
    try {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat(pattern);

        return Optional.of(simpleDateFormat.parse(date));
    } catch (ParseException e) {
        return Optional.empty();
    }
}




 @Test
 public void test() {
    String date = "03/22/1990";
    String date1 = "03/22/1990 12:34:45";
    String date2 = "03/22/1990 12:34 AM";

    System.out.println(parse(date));
    System.out.println(parse(date1));
    System.out.println(parse(date2));
}

答案 4 :(得分:0)

我认为您需要在此处解决两个问题:

  1. 如何解析日期
  2. 如何为JSON创建自定义反序列化器

关于第一个问题,您可以使用JODA或Java8。我将坚持使用Java 8,因为新的java.time库可以处理您问题中的格式。

关于JSON,我建议使用Jackson库,因为它非常灵活,您可以使用它创建自己的自定义反序列化器。

为了导入Jackson库,您可以使用以下Maven依赖项:

<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-core</artifactId>
    <version>2.9.5</version>
</dependency>
<dependency>
    <groupId>com.fasterxml.jackson.core</groupId>
    <artifactId>jackson-databind</artifactId>
    <version>2.9.5</version>
</dependency>

默认解串器需要打包到模块中。这是一些反序列化器代码示例:

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonTokenId;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
import com.fasterxml.jackson.databind.module.SimpleModule;

import java.io.IOException;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;

/**
 * Used to deserialize LocalTime from a multiple string formats.
 */
public class GenericDateSerializerModule extends SimpleModule {

    public static final StdScalarDeserializer<LocalDateTime> DATE_TIME_STD_SCALAR_DESERIALIZER =
            new StdScalarDeserializer<LocalDateTime>(LocalDate.class) {

                private DateTimeFormatter[] dtfs =  {
                        new DateTimeFormatterBuilder()
                                .appendPattern("MM/dd/yyyy")
                                .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
                                .parseDefaulting(ChronoField.MINUTE_OF_HOUR, 0)
                                .parseDefaulting(ChronoField.SECOND_OF_MINUTE, 0)
                                .toFormatter(),
                        DateTimeFormatter.ofPattern("MM/dd/yyyy HH:mm:ss"),
                        DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a")
                };

                @Override
                public LocalDateTime deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
                        throws IOException {
                    if (jsonParser.getCurrentTokenId() == JsonTokenId.ID_STRING) {
                        String string = jsonParser.getText().trim();
                        for (DateTimeFormatter dtf : dtfs) {
                            try {
                                return LocalDateTime.parse(string, dtf);
                            } catch(Exception e) {
                                System.err.println(e);
                            }
                        }
                    }
                    return null;
                }
            };

    public GenericDateSerializerModule() {
        addDeserializer(LocalDateTime.class, DATE_TIME_STD_SCALAR_DESERIALIZER);
    }
}

然后,您可以将这个简单的模块与序列化程序一起使用,以将JSON映射到类:

import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.time.LocalDateTime;

class GenericDateSerializerModuleTest {

    private ObjectMapper genericDateSerializerMapper = new ObjectMapper();

    @BeforeEach
    void setUp() {
        genericDateSerializerMapper.registerModule(new GenericDateSerializerModule());
    }

    @Test
    void extractMultiFormatDates() throws IOException {
        String json = "{\n" +
                "    \"bookingDate\": \"03/22/1990\",\n" +
                "    \"createdOn\": \"03/22/1990 12:34:45\",\n" +
                "    \"modifiedOn\": \"03/22/1990 12:23 AM\"\n" +
                "}";
        DateJson dateJson = genericDateSerializerMapper.readerFor(DateJson.class).readValue(json);
        System.out.println(dateJson);
    }

    static class DateJson {
        private LocalDateTime BookingDate;
        private LocalDateTime CreatedOn;
        private LocalDateTime ModifiedOn;

        public LocalDateTime getBookingDate() {
            return BookingDate;
        }

        public void setBookingDate(LocalDateTime bookingDate) {
            BookingDate = bookingDate;
        }

        public LocalDateTime getCreatedOn() {
            return CreatedOn;
        }

        public void setCreatedOn(LocalDateTime createdOn) {
            CreatedOn = createdOn;
        }

        public LocalDateTime getModifiedOn() {
            return ModifiedOn;
        }

        public void setModifiedOn(LocalDateTime modifiedOn) {
            ModifiedOn = modifiedOn;
        }

        @Override
        public String toString() {
            return "DateJson{" +
                    "BookingDate=" + BookingDate +
                    ", CreatedOn=" + CreatedOn +
                    ", ModifiedOn=" + ModifiedOn +
                    '}';
        }
    }
}

如果运行此测试,您将在控制台上看到以下输出:

java.time.format.DateTimeParseException: Text '03/22/1990 12:34:45' could not be parsed, unparsed text found at index 10
java.time.format.DateTimeParseException: Text '03/22/1990 12:23 AM' could not be parsed, unparsed text found at index 10
java.time.format.DateTimeParseException: Text '03/22/1990 12:23 AM' could not be parsed at index 16
DateJson{BookingDate=1990-03-22T00:00, CreatedOn=1990-03-22T12:34:45, ModifiedOn=1990-03-22T00:23}