我有一个要求,我必须以任何格式将值作为json从传入请求映射到Date。 例如,在我的请求中,我可以使用以下任何一种格式获取日期字符串:
1. 03/22/1990 -- MM/dd/yyyy
2. 03/22/1990 12:34:45
3. 03/22/1990 12:23 AM
如何将传入的映射值映射到Date。
答案 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)
我认为您需要在此处解决两个问题:
关于第一个问题,您可以使用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}