@DateTimeFormat 转换时出现夏令时错误
@DateTimeFormat with daylight saving error when converting
我在使用 @DateTimeFormat
注释转换实际不存在的日期时遇到问题。
例如,当我设置日期 15/10/2017 时,我的实体中的注释如下:
@Column(nullable = false)
@NotNull
@DateTimeFormat(pattern = "dd/MM/yyyy")
private Date dataVisita;
我收到错误:
Failed To Convert Property Value Of Type Java.Lang.String To Required Type Java.Util.Date For Property DataVisita;
Nested Exception Is Org.Springframework.Core.Convert.ConversionFailedException:
Failed To Convert From Type Java.Lang.String To Type @Javax.Persistence.Column @Javax.Validation.Constraints.NotNull @Org.Springframework.Format.Annotation.DateTimeFormat Java.Util.Date For Value 15/10/2017;
Nested Exception Is Java.Lang.IllegalArgumentException:
Cannot Parse "15/10/2017": Illegal Instant Due To Time Zone Offset Transition (America/Sao_Paulo)
我明白错误告诉我日期15/10/2017 00:00:00
实际上并不存在,但我想转换为15/10/2017 01:00:00
,忽略这种方式的问题并找到对应的日期。
有没有办法让我覆盖 @DateTimeFormat
注释或让格式化程序变得宽松?
试试这个:
@Column(nullable = false)
@NotNull
@DateTimeFormat(pattern = "dd/MM/yyyy HH:mm:ss")
private Date dataVisita;
它似乎做你想要的(调整0:00到1:00),你需要实现一个validator如下:
public class PersonValidator implements Validator {
/**
* This Validator validates *just* Person instances
*/
public boolean supports(Class clazz) {
return Date.class.equals(clazz);
}
public void validate(Object obj, Errors e) {
String dateString = (String) obj;
DateTimeFormatter fmt = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss");
DateTime ourDate = null;
try {
fmt.parseDateTime(dateString);
} catch (IllegalArgumentException e) {
// massage your hour here
} finally {
ourDate = fmt.parseDateTime(dateString);
}
}
}
如果您想使用 DateTimeFormat
,它是 Java 8 class 和新框架的一部分(从 java 8 开始)"java.time" 框架,您可能需要使用 Java 8 日期 classes:
日期:
java.time.LocalDate
时间:
java.time.LocalTime、java.time.OffsetTime
时间戳:
java.time.Instant、java.time.LocalDate时间、java.time.OffsetDateTime 和 java.time.ZonedDateTime
此外,您在 Spring 框架中使用哪种 ORM? Spring 数据、休眠或其他?如果您使用 Hibernate,请查阅 Hibernate 用户指南:Mapping Date/Time Values
取决于您在数据库中存储日期的方式以及您的服务器时区,
解决方案是在 Spring 初始化时将默认时区设置为 UTC,使用以下代码:
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
对我来说,你不应该直接搞乱系统的语言环境。这才是你真正的问题所在。
我的意思是你没有提供时区,所以你使用的是服务器之一。在此服务器及其配置上,它将是 day/date。在另一台服务器上它会另一个 day/date.
请确保您在 UTC(因此没有夏令时等等)或客户在输入中提供的明确语言环境中工作,使用本地日期来存储...要么像这样保持它,当你需要比较日期,将其转换为 UTC。这样问题就会消失。
快速解决方法是确保您的服务器使用 UTC,但从长远来看 运行 您应该始终控制您使用的语言环境,因此提供的日期必须是 UTC 或本地日期,并且另一个字段提供时区。
这应该非常简单。
这里的问题是,您正在为日期对象传递字符串值。这是相关注释的文档:
这里简单说一下需要的类型:java.util.Date、java.util.Calendar、java.lang.Long、Joda-Time值类型
一种非常幼稚的方式:
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date destnationDateToBeSaved = sdf.parse("15/10/2017");
推荐方式:
使用:
@DateTimeFormat(iso = ISO.DATE_TIME)
private ZonedDateTime zonedDateTime;
和
// 'yyyy-MMM-dd HH:mm:ss' pattern or if preferred ISO
ZonedDateTime destnationDateToBeSaved= ZonedDateTime.parse("2017-Oct-15 23:35:05", DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm:ss").withZone(ZoneId.of("UTC")));
希望对您有所帮助!
我在使用 @DateTimeFormat
注释转换实际不存在的日期时遇到问题。
例如,当我设置日期 15/10/2017 时,我的实体中的注释如下:
@Column(nullable = false)
@NotNull
@DateTimeFormat(pattern = "dd/MM/yyyy")
private Date dataVisita;
我收到错误:
Failed To Convert Property Value Of Type Java.Lang.String To Required Type Java.Util.Date For Property DataVisita;
Nested Exception Is Org.Springframework.Core.Convert.ConversionFailedException:
Failed To Convert From Type Java.Lang.String To Type @Javax.Persistence.Column @Javax.Validation.Constraints.NotNull @Org.Springframework.Format.Annotation.DateTimeFormat Java.Util.Date For Value 15/10/2017;
Nested Exception Is Java.Lang.IllegalArgumentException:
Cannot Parse "15/10/2017": Illegal Instant Due To Time Zone Offset Transition (America/Sao_Paulo)
我明白错误告诉我日期15/10/2017 00:00:00
实际上并不存在,但我想转换为15/10/2017 01:00:00
,忽略这种方式的问题并找到对应的日期。
有没有办法让我覆盖 @DateTimeFormat
注释或让格式化程序变得宽松?
试试这个:
@Column(nullable = false)
@NotNull
@DateTimeFormat(pattern = "dd/MM/yyyy HH:mm:ss")
private Date dataVisita;
它似乎做你想要的(调整0:00到1:00),你需要实现一个validator如下:
public class PersonValidator implements Validator {
/**
* This Validator validates *just* Person instances
*/
public boolean supports(Class clazz) {
return Date.class.equals(clazz);
}
public void validate(Object obj, Errors e) {
String dateString = (String) obj;
DateTimeFormatter fmt = DateTimeFormat.forPattern("dd/MM/yyyy HH:mm:ss");
DateTime ourDate = null;
try {
fmt.parseDateTime(dateString);
} catch (IllegalArgumentException e) {
// massage your hour here
} finally {
ourDate = fmt.parseDateTime(dateString);
}
}
}
如果您想使用 DateTimeFormat
,它是 Java 8 class 和新框架的一部分(从 java 8 开始)"java.time" 框架,您可能需要使用 Java 8 日期 classes:
日期:
java.time.LocalDate
时间:
java.time.LocalTime、java.time.OffsetTime
时间戳:
java.time.Instant、java.time.LocalDate时间、java.time.OffsetDateTime 和 java.time.ZonedDateTime
此外,您在 Spring 框架中使用哪种 ORM? Spring 数据、休眠或其他?如果您使用 Hibernate,请查阅 Hibernate 用户指南:Mapping Date/Time Values
取决于您在数据库中存储日期的方式以及您的服务器时区, 解决方案是在 Spring 初始化时将默认时区设置为 UTC,使用以下代码:
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
对我来说,你不应该直接搞乱系统的语言环境。这才是你真正的问题所在。
我的意思是你没有提供时区,所以你使用的是服务器之一。在此服务器及其配置上,它将是 day/date。在另一台服务器上它会另一个 day/date.
请确保您在 UTC(因此没有夏令时等等)或客户在输入中提供的明确语言环境中工作,使用本地日期来存储...要么像这样保持它,当你需要比较日期,将其转换为 UTC。这样问题就会消失。
快速解决方法是确保您的服务器使用 UTC,但从长远来看 运行 您应该始终控制您使用的语言环境,因此提供的日期必须是 UTC 或本地日期,并且另一个字段提供时区。
这应该非常简单。
这里的问题是,您正在为日期对象传递字符串值。这是相关注释的文档:
这里简单说一下需要的类型:java.util.Date、java.util.Calendar、java.lang.Long、Joda-Time值类型
一种非常幼稚的方式:
SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy");
Date destnationDateToBeSaved = sdf.parse("15/10/2017");
推荐方式:
使用:
@DateTimeFormat(iso = ISO.DATE_TIME)
private ZonedDateTime zonedDateTime;
和
// 'yyyy-MMM-dd HH:mm:ss' pattern or if preferred ISO
ZonedDateTime destnationDateToBeSaved= ZonedDateTime.parse("2017-Oct-15 23:35:05", DateTimeFormatter.ofPattern("yyyy-MMM-dd HH:mm:ss").withZone(ZoneId.of("UTC")));
希望对您有所帮助!