Java 春季的日期转换休息一天
我有一个POST端点,它包含两个值,一个是endDate和startDate。当JSON以以下方式发布时:Java 春季的日期转换休息一天,java,spring,spring-mvc,time,Java,Spring,Spring Mvc,Time,我有一个POST端点,它包含两个值,一个是endDate和startDate。当JSON以以下方式发布时: { "startDate" : "2015-01-30", "endDate" : "2015-12-30" } Spring将其转换为总是落后一天的java.util.Date对象。在日志中,我看到: Validating that startDate Thu Jan 29 16:00:00 PST 2015 < endDate Tue Dec 29 16:00:00 PST 2
{ "startDate" : "2015-01-30", "endDate" : "2015-12-30" }
Spring将其转换为总是落后一天的java.util.Date对象。在日志中,我看到:
Validating that startDate Thu Jan 29 16:00:00 PST 2015 < endDate Tue Dec 29 16:00:00 PST 2015
验证起始日期2015年1月29日星期四16:00:00太平洋标准时间<结束日期2015年12月29日星期二16:00:00太平洋标准时间
所以它的时区是正确的。我假设它与UTC转换有关,但我不确定如何配置或修改它,以便它使用适当的偏移进行转换。它的时间戳部分不是必需的——我只关心年、日和月与传入的内容匹配
如果有必要的话,我正在使用Spring(发生在4.0.6和4.1.7中)和一篇博文检查如何自定义自动Spring转换:
String str="2015-01-30";
try{
SimpleDateFormat isoFormat = new SimpleDateFormat("yyyy-MM-dd");
isoFormat.setTimeZone(TimeZone.getTimeZone("PST"));
Date date = isoFormat.parse(str);
System.out.println(date);
}catch(ParseException e){
e.printStackTrace();
}
@Controller
public class MyFormController {
@InitBinder
public void initBinder(WebDataBinder binder) {
SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
dateFormat.setLenient(false);
binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, false));
}
// ...
}
tl;博士
为作业使用正确的数据类型
您正在尝试将一个仅限日期的值适配到日期时间类型中,java.util.date
。当你试图找出一天中与你约会的时间时,一个时区正在被注入,这就是你的问题所在
LocalDate
解决方案:
- 永远不要使用糟糕的老式日期时间类,如
。仅使用现代java.time类java.util.date
- 对于仅限日期的值,请使用
LocalDate
LocalDate ld = LocalDate.parse( "2015-01-30" ) ;
ZoneDateTime
如果您想要一个时刻,一个带有时间的日期,让java.time确定一天中的第一个时刻。永远不要假设那一刻是00:00:00。在某些日期的某些区域,可能是另一个时间,例如01:00:00,因为异常情况,例如
Instant
要从调整到UTC(同一时刻,不同的挂钟时间),请提取一个瞬间
Instant instant = zdt.toInstant() ; // Adjust to UTC. Same moment, same simultaneous point on the timeline, different wall-clock time.
关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,& 该项目现已启动,建议迁移到类 要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是 您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*
类
从哪里获得java.time类
- 、和更高版本-标准Java API的一部分,带有捆绑实现。
- Java9添加了一些次要功能和修复
- 及
- 大多数java.time功能都在中向后移植到Java6和Java7
-
- 更高版本的Android捆绑包实现了java.time类
- 对于早期的Android(请告诉我您希望Spring为“2015-01-30”创建一个java.util.Date对象,其中包含“Thu-Jan 30 XX:XX:XX PST 2015”与它现在所做的相比。我假设我缺少一个配置设置。我不明白为什么它假设2015年1月30日UTC,然后转换回我的时间。检查此链接:希望它有帮助。仅供参考,非常麻烦的旧日期时间类,如和
,现在被类E取代s内置于Java 8和更高版本中。请参阅。我看到了相同的问题。邮递员上的日期显示为“2013-01-30”但是Date变量是在2013年1月29日星期二16:00:00 PST分配的,所以它有一天的休息时间。问题是由于遗留问题,我无法切换到LocalDate,所以我不得不使用java Date。另一个原因是我们使用的JSF版本不支持LocalDate。如果我将它作为字符串传递并转换为日期,那么就没有问题了——一切都可以正常工作。当Spring做的转换是有问题的。所以我从java.util.Date开始,我需要将它转换为一个以我的时区为中心的毫秒,而不是UTCFYI,现在,非常麻烦的旧日期时间类,如和java.text.simpleDataFormat
,被java 8和稍后。请参阅。我对“@JsonFormat(pattern=“yyyy-MM-dd”)公共日期生日有类似的问题,在我的Spring模型中,Date是java.sql.Date,我还可以使用@JsonFormat和LocalDate吗?@develandressalemi您不应该再使用java.text.simpleDataFormat
,永远不要再使用了。对于没有时间的日期,请使用java.sql.Date
类。我不知道您从哪里得到LocalDate
,但任何像样的框架都应该升级ted现在已经为java.time类提供了支持。请看我添加的图表。我明白了,谢谢,动机是使用需要日期的CallableStatement,但基本上我只需要使用Spring Boot将日期持久化到SQL Server,使用大量存储过程和原始JDBC,最后使用CallableStatement.SetObject和LocalDate,现在就可以完美地工作了!@JsonFormat
ZonedId z = ZoneId.of( "America/Montreal" ) ; ZonedDateTime zdt = ld.atStartOfDay( z ) ; // Let java.time determine the first moment of that date in that zone.
Instant instant = zdt.toInstant() ; // Adjust to UTC. Same moment, same simultaneous point on the timeline, different wall-clock time.