mysql所支持的日期時間類型有:DATETIME、 TIMESTAMP、DATE、TIME、YEAR。前端
幾種類型比較以下:java
日期時間類型 | 佔用空間 | 日期格式 | 最小值 | 最大值 | 零值表示 |
DATETIME | 8 bytes | YYYY-MM-DD HH:MM:SS | 1000-01-01 00:00:00 | 9999-12-31 23:59:59 | 0000-00-00 00:00:00 |
TIMESTAMP | 4 bytes | YYYY-MM-DD HH:MM:SS | 19700101080001 | 2038 年的某個時刻 | 00000000000000 |
DATE | 4 bytes | YYYY-MM-DD | 1000-01-01 | 9999-12-31 | 0000-00-00 |
TIME | 3 bytes | HH:MM:SS | -838:59:59 | 838:59:59 | 00:00:00 |
YEAR | 1 bytes | YYYY | 1901 | 2155 | 0000 |
DATETIMEmysql
DATETIME 用於表示 年月日 時分秒,是 DATE 和 TIME 的組合,而且記錄的年份(見上表)比較長久。若是實際應用中有這樣的需求,就可使用 DATETIME 類型。web
TIMESTAMPspring
若是記錄的日期須要讓不一樣時區的人使用,最好使用 TIMESTAMP。sql
DATE數據庫
DATE 用於表示 年月日,若是實際應用值須要保存 年月日 就可使用 DATE。服務器
TIMEmybatis
TIME 用於表示 時分秒,若是實際應用值須要保存 時分秒 就可使用 TIME。oracle
YEAR
YEAR 用於表示 年份,YEAR 有 2 位(最好使用4位)和 4 位格式的年。 默認是4位。若是實際應用只保存年份,那麼用 1 bytes 保存 YEAR 類型徹底能夠。不但可以節約存儲空間,還能提升表的操做效率。
每種日期時間類型都有一個有效值範圍,若是超出這個範圍,在默認的SQLMode下會報錯,並以零值(見上表)存儲。
插入或更新時,日期時間類型容許「不嚴格」語法,以DATETIME爲例(其餘日期時間類型雷同):
一般日期格式都是以時間戳的形式存放在數據庫裏,當前端頁面經過接口查詢時,咱們會將一個對象的某些屬性查出來返回給頁面。例如,某個類裏面有個屬性
Timestamp create_time
給這個對象實體類中的get方法加註解:@JsonFormat 來實現格式的自動轉換:
依賴的jar包:jackson-annotations-2.8.5.jar
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8") public Timestamp getCreate_time() { return create_time; }
加註解前的返回值是一個時間戳,加了以後則按照註解的格式自動格式化,其他類型同理。
咱們能夠這樣聲明 Timestamp ts=new Timestamp(new Date().getTime());這樣咱們就能夠獲得時間比較具體的一個類型轉換。在開發web應用中,針對不一樣的數據庫日期類型,咱們須要在咱們的程序中對日期類型作各類不一樣的轉換。若對應數據庫數據是oracle的Date類型,即只須要年月日的,能夠選擇使用java.sql.Date類型,若對應的是MSsqlserver數據庫的DateTime類型,即須要年月日時分秒的,選擇java.sql.Timestamp類型;
你可使用dateFormat定義時間日期的格式,而後進行轉換:
import java.util.Date; import java.util.Calendar; import java.sql.Timestamp; import java.text.DateFormat; import java.text.SimpleDateFormat; import java.util.Locale; class Datetest{ /** *method 將字符串類型的日期轉換爲一個timestamp(時間戳記java.sql.Timestamp) dateString 須要轉換爲timestamp的字符串 dataTime timestamp */ public final static java.sql.Timestamp string2Time(String dateString) throws java.text.ParseException { DateFormat dateFormat; dateFormat = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss.SSS", Locale.ENGLISH);//設定格式 //dateFormat = new SimpleDateFormat("yyyy-MM-dd kk:mm:ss", Locale.ENGLISH); dateFormat.setLenient(false); java.util.Date timeDate = dateFormat.parse(dateString);//util類型 java.sql.Timestamp dateTime = new java.sql.Timestamp(timeDate.getTime());//Timestamp類型,timeDate.getTime()返回一個long型 return dateTime; } /** *method 將字符串類型的日期轉換爲一個Date(java.sql.Date) dateString 須要轉換爲Date的字符串 dataTime Date */ public final static java.sql.Date string2Date(String dateString) throws java.lang.Exception { DateFormat dateFormat; dateFormat = new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH); dateFormat.setLenient(false); java.util.Date timeDate = dateFormat.parse(dateString);//util類型 java.sql.Date dateTime = new java.sql.Date(timeDate.getTime());//sql類型 return dateTime; } public static void main(String[] args){ Date da = new Date(); //注意:這個地方da.getTime()獲得的是一個long型的值 System.out.println(da.getTime()); //由日期date轉換爲timestamp //第一種方法:使用new Timestamp(long) Timestamp t = new Timestamp(new Date().getTime()); System.out.println(t); //第二種方法:使用Timestamp(int year,int month,int date,int hour,int minute,int second,int nano) Timestamp tt = new Timestamp(Calendar.getInstance().get( Calendar.YEAR) - 1900, Calendar.getInstance().get( Calendar.MONTH), Calendar.getInstance().get( Calendar.DATE), Calendar.getInstance().get( Calendar.HOUR), Calendar.getInstance().get( Calendar.MINUTE), Calendar.getInstance().get( Calendar.SECOND), 0); System.out.println(tt); try { String sToDate = "2005-8-18";//用於轉換成java.sql.Date的字符串 String sToTimestamp = "2005-8-18 14:21:12.123";//用於轉換成java.sql.Timestamp的字符串 Date date1 = string2Date(sToDate); Timestamp date2 = string2Time(sToTimestamp); System.out.println("Date:"+date1.toString());//結果顯示 System.out.println("Timestamp:"+date2.toString());//結果顯示 }catch(Exception e) { e.printStackTrace(); } } }
注意:Mybatis返回值設置jdbctype是沒有這個DATETIME類型的(以下圖報錯),若是數據庫存儲的是DATETIME的類型,而且準確顯示到年月日時分秒,因此用timestamp。
mysql官網也是不認可時間直接相加減的(如CURDATE()+1),雖然會將當前時間轉換爲20160802,這時候就是比較這一串字符,mysql官網是不認可用這種方式比較時間大小的,所以正確的sql語句:
SELECT COUNT(*) FROM USER WHERE registerDate >= CURDATE() AND registerDate < DATE_SUB(CURDATE(),INTERVAL -1 DAY);
此時,就用到了DATE_SUB()這個函數,用法舉例:
--今天是2016年08月01日。 date_sub('2016-08-01',interval 1 day) --表示 2016-07-31 date_sub('2016-08-01',interval 0 day) --表示 2016-08-01 date_sub('2016-08-01',interval -1 day) --表示 2016-08-02 date_sub(curdate(),interval 1 day) --表示 2016-07-31 date_sub(curdate(),interval -1 day) --表示2016-08-02 date_sub(curdate(),interval 1 month) --表示 2016-07-01 date_sub(curdate(),interval -1 month) --表示 2016-09-01 date_sub(curdate(),interval 1 year) --表示 2015-08-01 date_sub(curdate(),interval -1 year) --表示 2017-08-01
注意:SELECT NOW(),CURDATE(),CURTIME()
結果相似:
NOW() | CURDATE() | CURTIME() |
---|---|---|
2016-08-01 16:25:46 | 2016-08-01 | 16:25:46 |
案例:mybatis中查詢時間範圍處理:例如2018-05-22 ~2018-05-23,則查出來的數據僅能查到2018-05-22的,查不到2018-05-23的數據。時間字段在spring MVC中已經處理了,已經沒有2018-05-23 00:00:00.0,已經獲取到了日期,去掉了時分秒,爲何傳入mybatis進行sql查詢的時候依舊會變成這樣?
<if test="saleDateStart != null"> and DATE_FORMAT(info.sale_date,'%Y-%m-%d') >= #{saleDateStart} </if> <if test="saleDateEnd != null"> and DATE_FORMAT(info.sale_date,'%Y-%m-%d') <= #{saleDateStart} </if>
緣由:問題就出在 #{時間字段} 這個地方,雖然這個時候查詢的時候傳入的時間字段值 是 年月日格式 沒有時分秒 可是mybatis在生成sql的時候 ,依舊將 年月日進行格式化 成了 年月日 時分秒類型。
解決辦法:對傳入到Mybatis的具體值進行格式化後再比較
<if test="saleDateStart != null"> and DATE_FORMAT(info.sale_date,'%Y-%m-%d') >= DATE_FORMAT(#{saleDateStart},'%Y-%m-%d') </if> <if test="saleDateEnd != null"> and DATE_FORMAT(info.sale_date,'%Y-%m-%d') <= DATE_FORMAT(#{saleDateStart},'%Y-%m-%d') </if>
其他相似比較SQL語句:
--特定時間秒查詢 SELECT id, date_0 FROM worksheet_data_30 WHERE DATE_FORMAT( date_0, '%Y-%m-%d %H:%i:%S' ) = DATE_FORMAT( '2019-06-05 09:35:06', '%Y-%m-%d %H:%i:%S' ) --特定分鐘查詢 SELECT id, date_0 FROM worksheet_data_30 WHERE DATE_FORMAT( date_0, '%Y-%m-%d %H:%i' ) = DATE_FORMAT( '2019-06-05 09:35:06', '%Y-%m-%d %H:%i' ) --特定小時查詢 SELECT id, date_0 FROM worksheet_data_30 WHERE DATE_FORMAT( date_0, '%Y-%m-%d %H' ) = DATE_FORMAT( '2019-06-05 09:35:06', '%Y-%m-%d %H' ) --當天數據查詢 select * from security_code_config where DATE_FORMAT(create_date,'%Y-%m-%d') = DATE_FORMAT(NOW(),'%Y-%m-%d') --本月數據查詢 select * from security_code_config where DATE_FORMAT(create_date,'%Y-%m') = DATE_FORMAT(NOW(),'%Y-%m') --本年數據查詢 select * from security_code_config where DATE_FORMAT(create_date,'%Y') = DATE_FORMAT(NOW(),'%Y') --查詢最近7天 按天分組統計數據 SELECT create_date, IFNULL(sum(security_code_total), 0) createSCNum, IFNULL(sum(print_num), 0) printNum FROM security_code_config WHERE tid = 'ten_pisen' AND DATE_FORMAT(create_date,'%Y-%m-%d') <= DATE_FORMAT('2019-03-12','%Y-%m-%d') AND DATE_FORMAT(create_date,'%Y-%m-%d') >= DATE_FORMAT('2019-03-01','%Y-%m-%d') GROUP BY DATE_FORMAT(create_date,'%Y-%m-%d') --查詢最近6個月 按月分組統計數據 SELECT create_date, IFNULL(sum(security_code_total), 0) createSCNum, IFNULL(sum(print_num), 0) printNum FROM security_code_config WHERE tid = 'ten_pisen' AND DATE_FORMAT(create_date,'%Y-%m-%d') <= DATE_FORMAT('2019-03-12','%Y-%m-%d') AND DATE_FORMAT(create_date,'%Y-%m-%d') >= DATE_FORMAT('2018-10-01','%Y-%m-%d') GROUP BY DATE_FORMAT(create_date,'%Y-%m')
===============================附錄,mysql格式化方法以及時間符號========================
date_format(date,'%Y-%m-%d %H:%i:%s') -------------->oracle中的to_char();
str_to_date(date,'%Y-%m-%d %H:%i:%s') -------------->oracle中的to_date();
format參數的格式有
%a | 縮寫星期名 |
%b | 縮寫月名 |
%c | 月,數值 |
%D | 帶有英文前綴的月中的天 |
%d | 月的天,數值(00-31) |
%e | 月的天,數值(0-31) |
%f | 微秒 |
%H | 小時 (00-23) |
%h | 小時 (01-12) |
%I | 小時 (01-12) |
%i | 分鐘,數值(00-59) |
%j | 年的天 (001-366) |
%k | 小時 (0-23) |
%l | 小時 (1-12) |
%M | 月名 |
%m | 月,數值(00-12) |
%p | AM 或 PM |
%r | 時間,12-小時(hh:mm:ss AM 或 PM) |
%S | 秒(00-59) |
%s | 秒(00-59) |
%T | 時間, 24-小時 (hh:mm:ss) |
%U | 周 (00-53) 星期日是一週的第一天 |
%u | 周 (00-53) 星期一是一週的第一天 |
%V | 周 (01-53) 星期日是一週的第一天,與 %X 使用 |
%v | 周 (01-53) 星期一是一週的第一天,與 %x 使用 |
%W | 星期名 |
%w | 周的天 (0=星期日, 6=星期六) |
%X | 年,其中的星期日是周的第一天,4 位,與 %V 使用 |
%x | 年,其中的星期一是周的第一天,4 位,與 %v 使用 |
%Y | 年,4 位 |
%y | 年,2 位 |