2016-11-25 81 views
1

我正在用Java创建一个小程序。日期字段是一个组合框,用于只选择月份和日期为02/2016。是否有一种方法可以在mysql中记录此日期格式仅在mm/yy字段中?在MySQL数据库中只创建月份和年份列

+0

至少,以yyyymm格式存储它。 – Strawberry

+0

@Strawberry其实,[YYYY-MM](https://en.wikipedia.org/wiki/ISO_8601#Calendar_dates)是[标准格式](https://en.wikipedia.org/wiki/ISO_8601)。 –

回答

0

而不是以这种格式存储它,也许最好的办法是将它存储为一个正常的日期,并且一直设置为该月的第一天。 然后在检索的时候,将日期格式化为SimpleDateFormat格式,只获取月份和年份并将其返回给用户界面。

+0

你是对的,而且我为他们所做的第一个真正的问题是,在每个月底,子办事处都会在总部发送纸质数据,因为子办事处没有数据库。必须存储在数据库中的数据以发送纸质表格的形式恢复办公室的财务状况。因此在现有数据库中,对于那些信息,仅需要涉及的月份和年份,而不是它们。 –

+0

你不需要在你的用户界面中查询这一天。按照您现在的做法,只问月份和年份。但是,当您在后端接收到信息时,请在将日期(例如月底)添加为MySql之前,将其作为实际日期。如果在数据库中有一些只有月份和年份信息的数据作为字符串,最好将它们迁移到实际日期,以便能够对它们执行范围和比较操作,并且具有高效和一致的索引。 –

0

你不应该这样做,并且没有原生的方式来做到这一点。只需将它保存为mysql中的正常DATE,并在查询数据库SELECT MONTH(datefield), YEAR(datefield)或使用java解析日期时。 mysql日期和日期时间类型由包含一天(或包括时间)的日期组成。为了能够查询范围和其他日期相关的东西,你应该坚持存储日期的预期方式。 Mysql具有出色的日期时间功能,你不应该做一些让他们离开你的东西。

0

ISO 8601

ISO 8601标准定义多种格式用于表示日期时间值的字符串。其中一个是一年零一个月,没有任何日期,没有时区,也没有时间:YYYY-MM。例如:2016-02二月2016年

数据库存储

在数据库中保存的文本列这些标准的字符串。请注意,按字母排序也意味着按时间排序。

的Java

的java.time类解析/生成的字符串表示日期时间值时使用ISO 8601标准格式默认。

YearMonth类代表没有日期的年份值。在你的应用程序中,使用这些对象而不是单纯的字符串或数字。这样做可以提供类型安全性,确保有效的值,并使代码更加自我记录。

YearMonth ym = YearMonth.of(2016 , 2); 
String output = ym.toString(); // 2016-02 

然后去解析一个标准字符串。按字母顺序排序时

YearMonth ym = YearMonth.parse("2016-02"); 

查询

可以进行文本查询作为标准格式是按时间顺序。该ISO委员会的人非常聪明。

例如,查询值在2016年第一季度:

WHERE expiration >= '2016-01' 
AND expiration <= '2016-03' 

此外,在日期时间的工作,我们通常在开始使用半开方法的时间跨度是包括而结尾是独家

WHERE expiration >= '2016-01' 
AND expiration < '2016-04' // Up to, but not including, the month at end of this span. 

当然,你真的应该使用PreparedStatement而不是原始SQL查询。

YearMonth q2016_ymStart = YearMonth.of(2016 , 1); // 2016-01 
YearMonth q2016_ymStop = q2016_ymStart.plusMonths(3); // 2016-04 for half-open quarter. 
… 
myPreparedStatement.setString(… , q2016_ymStart.toString()); 
myPreparedStatement.setString(… , q2016_ymStop.toString()); 

及宿舍来说,看到ThreeTen-Extra项目YearQuarterQuarter类。

LocalDate

要变换YearMonth为日期,使用LocalDate类。

LocalDate firstOfMonth = ym.atDay(1); 
LocalDate endOfMonth = ym.atEndOfMonth(); 

ZonedDateTime

要变换YearMonth成一个时刻在时间轴上,指定由您的业务方案的预期背景下的时区。让java.time确定当天的第一时刻,第一时刻是总是00:00:00

ZoneId z = ZoneId.of("America/Montreal"); 
ZonedDateTime zdt = ym.atDay(1).atStartOfDay(z); 

数据库访问

对于数据库的访问,你的JDBC 4.2兼容的驱动程序可能能够直接通过调用PreparedStatement::setObjectResultSet::getObject方法处理这些java.time类型。

如果不能,回落到转换java.time类型使用添加到这些老班新方法的老的java.sql类型。搜索堆栈溢出了解更多信息。


关于java.time

java.time框架是建立在Java 8和更高版本。这些类取代了日期时间类legacy,如java.util.Date,Calendar,& SimpleDateFormat

Joda-Time项目现在位于maintenance mode,建议迁移到java.time。请参阅Oracle Tutorial。并搜索堆栈溢出了很多例子和解释。规格是JSR 310

从何处获取java.time类?

ThreeTen-Extra项目与其他类扩展java.time。这个项目是未来可能增加java.time的一个试验场。您可以在这里找到一些有用的类,如Interval,YearWeek,YearQuartermore

+0

如果在数据库中,我将它作为文本列或字符串存储,是否可以有一个SQL请求,比如'select * from table_name where date date between dat1 and date2'?由于此请求使用数字和日期格式,但日期与文本列一样,我不确定它会起作用 –

+0

如果您只关注年份,则日期无关紧要。此外,您还有迄今为止忽略的时区这个至关重要的问题。对于任何特定时刻,日期因地区而异。搜索堆栈溢出*了解更多信息。如果您正在存储的内容类似于信用卡过期,那么此答案就足够了。对于一个范围,例如第一季度(1月 - 3月),搜索'WHERE到期日期='2016-01'和到期日期<='2016-03''。 –