91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

你可能不會注意的Timestamp

發布時間:2020-07-04 06:52:26 來源:網絡 閱讀:5179 作者:chellman 欄目:軟件技術

提起java里面的時間戳,相信很多人都用過。
不就是java.sql.Timestamp類,兩個構造器,13個方法,這也許屬于java中最簡單的基礎類了。

俗話說淹死的都是會游泳的,同樣在開發中讓我們栽跟頭的往往都是耳熟能詳的一些類庫。

引子

首先讓我們看看以下幾行代碼的輸出結果吧


Timestamp t1 = new Timestamp(0);
System.out.println(t1);
Timestamp t2 = Timestamp.valueOf("2037-12-31 23:59:59");
System.out.println(t2.getTime());
System.out.println(t2.getTime() == new Long(Integer.MAX_VALUE) * 1000);
Timestamp t3 = new Timestamp(new Long(Integer.MAX_VALUE) * 1000);
System.out.println(t3);Timestamp t21 = Timestamp.valueOf("9999-12-31 23:59:59");
System.out.println(t21.getTime());
Timestamp t22 = new Timestamp(t21.getTime());
System.out.println(t22);Date d1 = new Date(0);
System.out.println(d1.equals(t1));
System.out.println(t1.equals(d1));

如果你能很明確的說出每一個輸出結果是什么以及為什么,那么你已經不需要繼續往下看了。
如果你對一個或者更多的結果感到迷茫,就讓我們來一起踩踩坑吧。

時間范圍

要搞清楚Timestamp類的范圍方法有很多,可以看文檔、看源代碼,寫個代碼測試一下或者搜索引擎看看別人怎么說。
當我們實踐了上面的一種或者多種方法后我們再回過頭來看看我們引子里的第一段和第二段代碼的輸出結果。


Timestamp t1 = new Timestamp(0);
System.out.println(t1);//1970-01-01 08:00:00.0

有沒有看著很熟悉?跟格林尼治標準時(計算機用的比較多的說法是UTC)就差8個小時,那也很好理解我們是東八區嘛。
換句話說Timestamp類的開始時間可以認為是格林尼治標準時,在不同時區使用會加上時區的偏移量。


Timestamp t2 = Timestamp.valueOf("2037-12-31 23:59:59");
System.out.println(t2.getTime());//2145887999000
System.out.println(t2.getTime() == new Long(Integer.MAX_VALUE) * 1000);//false
Timestamp t3 = new Timestamp(new Long(Integer.MAX_VALUE) * 1000);
System.out.println(t3);//2038-01-19 11:14:07.0
Timestamp t21 = Timestamp.valueOf("9999-12-31 23:59:59");
System.out.println(t21.getTime());//253402271999000
Timestamp t22 = new Timestamp(t21.getTime());
System.out.println(t22);//9999-12-31 23:59:59.0

上面幾段代碼其實都是根據網上關于Timestamp的最大值做出的驗證

第一種 2037-12-31 23:59:59(t2)

可以發現獲取出來的毫秒數和Integer.MAX_VALUE差不多就是1000倍的差距,
那不妨推斷一下這種說法的依據是在32位系統中存儲毫秒數,無溢出情況下的最大月末或者年末。
接下來通過Integer.MAX_VALUE構造出來的時間(t3)是2038-01-19 11:14:07.0 也驗證了我們的推斷。

第二種 9999-12-31 23:59:59

這個時間是我們在目前時間格式下的最大時間了,通過t21,t22的驗證發現通過,Timestamp類是可以存儲這種時間的。
再回過頭去看源代碼,發現用于存儲毫秒數的是Long而不是Integer,64位的Long完全可以到9999年嘛。

通過上面的驗證我們可以確認Timestamp類的最大時間可以是9999-12-31 23:59:59

Tips:
實際使用的時候我們的數據需要存儲到數據庫。
mysql為例,如果你想當然的將java的Timestamp直接就對應到數據庫的Timestamp,你會發現兩個數據類型范圍并不一樣。
摘抄一段mysql官方文檔的說明:

The DATE type is used for values with a date part but no time part. MySQL retrieves and displays DATE values in ‘YYYY-MM-DD’ format. The supported range is ‘1000-01-01’ to ‘9999-12-31’. The DATE type is used for values with a date part but no time part. MySQL retrieves and displays DATE values in ‘YYYY-MM-DD’ format. The supported range is ‘1000-01-01’ to ‘9999-12-31’.
The DATETIME type is used for values that contain both date and time parts. MySQL retrieves and displays DATETIME values in ‘YYYY-MM-DD HH:MM:SS’ format. The supported range is ‘1000-01-01 00:00:00’ to ‘9999-12-31 23:59:59’.
The TIMESTAMP data type is used for values that contain both date and time parts. TIMESTAMP has a range of ‘1970-01-01 00:00:01’ UTC to ‘2038-01-19 03:14:07’ UTC.


在真實使用的時候將業務,java類庫,數據庫數據類型進行對照,盡可能的找出符合要求的組合。

Equals并不相等

用到了時間,當然不能不比較了,看看下面這段代碼的輸出吧


Date d1 = new Date(0);
System.out.println(d1.equals(t1));//true
System.out.println(t1.equals(d1));//false

很有意思的結果,我們先來看看他是怎么做到的吧,看源碼>>
Date.equals:


public boolean equals(Object obj) {	return obj instanceof Date && getTime() == ((Date) obj).getTime();}

由于Timestamp是繼承自Date,并且在強轉后高精度部分丟失導致getTime完全一致,所以第一個比較返回了true

Timestamp.equals:


public boolean equals(java.lang.Object ts) {
	if (ts instanceof Timestamp) {
		return this.equals((Timestamp)ts);	
		} else {
			return false;	}
			}

判斷Date并不是Timestamp類型,直接返回false;

代碼沒毛病,可是回到現實世界不就是說a = b 而b != a嗎,作為一個嚴謹的程序員是不是總感覺哪里不舒服呢?

相信作者也是這樣,先是在類上出現了這段說明

The inheritance relationship between Timestamp and java.util.Date really denotes implementation inheritance, and not type inheritance.

然后方法上還要補上

Note: This method is not symmetric with respect to the equals(Object) method in the base class.

大意就是:我寫這個繼承關系只是實現繼承并不是類型繼承(為了少寫點代碼,其實沒毛關系),equals方法和父類的equals方法不對等(你們用錯了我不負責啊)

總結

最后總結以下幾點
1, java.sql.Timestamp可以接受的時間范圍是1970-01-01 00:00:00 - 9999-12-31 23:59:59,具體使用的時候需要考慮時區帶來的偏移量
2, 和數據庫結合使用需要結合實際需求、數據庫數據類型的具體范圍選擇合適的范圍,不能僅僅通過名字來選擇數據類型
3, Timestamp類的equals方法和父類的equals方法并不是對等的,只有兩個比較的對象都是Timestamp的時候才能返回一致的結果
4, 我們在實際設計開發的時候盡量避免這種不舒服的設計,結合繼承,封裝,多態等多種手段確保我們設計的魯棒。


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

灵宝市| 满洲里市| 清丰县| 银川市| 怀来县| 肇源县| 右玉县| 侯马市| 陇南市| 大方县| 景德镇市| 阿尔山市| 阿巴嘎旗| 晴隆县| 辽宁省| 方山县| 易门县| 灵石县| 永州市| 香格里拉县| 旺苍县| 枣阳市| 清远市| 和田县| 聂拉木县| 乌兰县| 左云县| 邯郸县| 北票市| 米脂县| 银川市| 当雄县| 西昌市| 华亭县| 永安市| 民乐县| 青神县| 赤壁市| 金华市| 留坝县| 曲水县|