Java/MySQL中没有时间或时区组件的日期

Java/MySQL中没有时间或时区组件的日期,java,sql,date,timezone,java-time,Java,Sql,Date,Timezone,Java Time,我需要能够存储没有时间组件的日期(年/月/日)。这是一个日期的抽象概念,比如生日——我需要表示一年中的一个日期,而不是时间上的某个特定时刻 我正在使用Java解析一些输入文本中的日期,需要存储在MySQL数据库中。无论数据库、应用程序或任何客户端处于哪个时区,它们都应该看到相同的年/月/日 我的应用程序将在与数据库服务器具有不同系统时区的机器上运行,而我对这两者都没有控制权。是否有人有一个优雅的解决方案来确保我正确存储日期 我能想到这些解决方案,但这两种方案都不是很好: 查询mymysql连接

我需要能够存储没有时间组件的日期(年/月/日)。这是一个日期的抽象概念,比如生日——我需要表示一年中的一个日期,而不是时间上的某个特定时刻

我正在使用Java解析一些输入文本中的日期,需要存储在MySQL数据库中。无论数据库、应用程序或任何客户端处于哪个时区,它们都应该看到相同的年/月/日

我的应用程序将在与数据库服务器具有不同系统时区的机器上运行,而我对这两者都没有控制权。是否有人有一个优雅的解决方案来确保我正确存储日期

我能想到这些解决方案,但这两种方案都不是很好:

  • 查询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实际上是一回事。所以我看不见。。你答案中的任何一点。我错过什么了吗?我觉得我必须这么做,因为你的经验可能是我的一千倍。