Java/MySQL中没有时间或时区组件的日期
我需要能够存储没有时间组件的日期(年/月/日)。这是一个日期的抽象概念,比如生日——我需要表示一年中的一个日期,而不是时间上的某个特定时刻 我正在使用Java解析一些输入文本中的日期,需要存储在MySQL数据库中。无论数据库、应用程序或任何客户端处于哪个时区,它们都应该看到相同的年/月/日 我的应用程序将在与数据库服务器具有不同系统时区的机器上运行,而我对这两者都没有控制权。是否有人有一个优雅的解决方案来确保我正确存储日期 我能想到这些解决方案,但这两种方案都不是很好:Java/MySQL中没有时间或时区组件的日期,java,sql,date,timezone,java-time,Java,Sql,Date,Timezone,Java Time,我需要能够存储没有时间组件的日期(年/月/日)。这是一个日期的抽象概念,比如生日——我需要表示一年中的一个日期,而不是时间上的某个特定时刻 我正在使用Java解析一些输入文本中的日期,需要存储在MySQL数据库中。无论数据库、应用程序或任何客户端处于哪个时区,它们都应该看到相同的年/月/日 我的应用程序将在与数据库服务器具有不同系统时区的机器上运行,而我对这两者都没有控制权。是否有人有一个优雅的解决方案来确保我正确存储日期 我能想到这些解决方案,但这两种方案都不是很好: 查询mymysql连接
- 查询mymysql连接的时区并解析该时区中的输入日期
- 将日期完全作为字符串yyyy MM dd处理
public static Date truncateDate(Date date)
{
GregorianCalendar cal = getGregorianCalendar();
cal.set(Calendar.ZONE_OFFSET, 0); // UTC
cal.set(Calendar.DST_OFFSET, 0); // We don't want DST to get in the way.
cal.setTime(date);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.AM_PM, Calendar.AM);
return cal.getTime();
}
难道不能在表中使用MySQL
DATE
类型,然后在insert语句中使用格式化字符串吗?我认为这样做可以避免任何时区调整
INSERT INTO time_table(dt) VALUES('2008-12-31')
我得出结论,在我当前的应用程序(一个直接使用jdbc的简单实用程序)中,最好的方法是直接作为字符串插入。对于更大的Hibernate应用程序,我可能会费心编写自己的用户类型。无法相信有人还没有在一些公开可用的代码中解决这个问题,但是…由于您指定服务器和数据库位于不同的时区,在我看来,您在解释方面似乎有问题。如果您将日期归零,或存储为MM dd YYYY,这相当于相同的内容,那么您是存储服务器日期还是数据库日期?如果服务器上的时间是晚上11点,数据库上的时间是第二天凌晨1点,那么哪个日期“正确”?当你看一年后的日期时,你会记得日期所依赖的机器时区吗
这些考虑可能有点过头了。但是为什么不直接将日期存储在GMT中(如果您愿意,可以将秒数归零)?类
java.sql.Date
的存在正是出于这个原因,不幸的是,它非常不方便使用,因为它只是扩展了java.util.Date
,您必须手动将时间部分设置为零。java.time
这确实是java.util
date-time API的一个问题,直到JSR-310被合并到JavaSE8中。java.util.Date
对象不像;相反,它表示自称为“历元”的标准基准时间(即1970年1月1日00:00:00 GMT)起的毫秒数。当您打印java.util.Date
的对象时,其toString
方法返回JVM时区中的日期时间,从该毫秒值计算得出
您描述的问题是通过*解决的,其中,LocalDate
只表示一个日期。在下面的句子中,作者很好地描述了它的目的:
例如,您可以使用LocalDate对象来表示出生
日期,因为大多数人在同一天过生日,
无论他们是在自己的出生地,还是在世界各地
国际日期线的一侧
,再次描述如下:
LocalDate表示ISO日历中的年-月-日,是
用于表示没有时间的日期。你可以用
LocalDate跟踪重要事件,如出生日期或
结婚日期
我应该为LocalDate
使用哪种数据类型?
它映射为DATE
ansisql类型。ANSI SQL类型与java.time
类型的映射如中所示:
ANSI SQL
JavaSE8
日期
本地日期
时间
当地时间
时间戳
LocalDateTime
带时区的时间
业余时间
带时区的时间戳
抵销日期时间
是的,在Java代码中,创建自己的日期类型,或者只使用字符串。java.util.Date对象是一个特定的时间瞬间,不能正确地建模您的用例。我有一个类似的用例:一个独立于年份的任意日期,用于将我的数据关联到季节数据。我将月份和日期存储为整数,而不是使用字符串,并且我不存储年份的任何表示形式。您好,SQL注入漏洞!提问者不想保存具体的时间,只想保存日期。这种情况下的出生日期。所以时区变得无关紧要,只有在解析时才应该解释本地时区。将时区设置为UTC/GMT实际上是一回事。所以我看不见。。你答案中的任何一点。我错过什么了吗?我觉得我必须这么做,因为你的经验可能是我的一千倍。