日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程语言 > java >内容正文

java

Java的日期API真烂

發(fā)布時(shí)間:2025/3/19 java 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Java的日期API真烂 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
記得在我剛學(xué)Java的時(shí)候,真是搞不清楚Date和Calendar這兩個(gè)類,后來(lái)我漸漸知道,原來(lái)不能全怪我啊,Java日期API之爛是公認(rèn)的(不妨參見(jiàn)這篇文章,Tiago Fernandez做過(guò)一個(gè)投票,就是要選舉最爛的Java API,結(jié)果Java日期API排行第二,僅次于臭名遠(yuǎn)揚(yáng)的EJB2,嘿嘿)。 蛋疼的java.sql.Date 只有Date和Calendar搞定一切嗎?那還好啊。當(dāng)然不是!光Date就有java.util.Date和java.sql.Date,而且關(guān)系是java.sql.Date extends java.util.Date。為了把前者轉(zhuǎn)成后者,我寫(xiě)了這樣的代碼:
12 Date date = new Date(); java.sql.Date d = new java.sql.Date(date.getTime());
居然不支持Date參數(shù)的構(gòu)造器,我只好傳入long類型的時(shí)間。接下去,我嘗試把當(dāng)前小時(shí)數(shù)取出來(lái):
1 System.out.println(d.getHours());
悲劇出現(xiàn)了:
12 Exception in thread "main" java.lang.IllegalArgumentException at java.sql.Date.getHours(Date.java:177)
一看源碼,坑爹啊:
123 public int getHours() { throw new java.lang.IllegalArgumentException(); }
在java.util.Date里面好好的方法怎么變成這個(gè)鳥(niǎo)樣了? 方法注釋給出了說(shuō)明: This method is deprecated and should not be used because SQL Date values do not have a time component. 也就是說(shuō),java.sql.Date是SQL中的單純的日期類型,哪會(huì)有時(shí)分秒啊?我覺(jué)得它根本不應(yīng)該設(shè)計(jì)成java.util.Date的子類。如果你把java.sql.Date通過(guò)JDBC插入數(shù)據(jù)庫(kù),你會(huì)發(fā)現(xiàn)時(shí)分秒都丟失了,因此如果你同時(shí)需要日期和時(shí)間,你應(yīng)該使用Timestamp,它也是java.util.Date的子類。 另外還有一個(gè)java.util.Date的子類叫Time,java.sql包下面的Date、Time和Timestamp可以放在一起記憶。Date只包含年月日信息、Time只包含時(shí)分秒信息,而Times則包含時(shí)間戳的完整信息。 現(xiàn)在知道人家拋出IllegalArgumentException的用心良苦了吧…… 坑爹的year和month 看看Date類的構(gòu)造器:
1 public Date(int year, int month, int day)
長(zhǎng)得并不奇葩嘛。 好,現(xiàn)在我要輸出2012年的1月1號(hào)了:
12 Date date = new Date(2012,1,1); System.out.println(date);
結(jié)果,你傻眼了:
1 Thu Feb 01 00:00:00 CST 3912
等等,這是啥?3192年? 原來(lái)實(shí)際年份是要在你的年份參數(shù)上加上個(gè)起始年份1900。 更坑爹的是,月份參數(shù)我不是給了1嗎?怎么輸出二月(Feb)了? Date里面的月份居然是用0~11表示的,換句話說(shuō),一月用0來(lái)表示,二月用1來(lái)表示。如果不用常量或者枚舉,很容易踩到坑里去,對(duì)不對(duì)? 后來(lái)發(fā)現(xiàn)Go語(yǔ)言的time.Date方法,對(duì)于月份做了個(gè)惡心但是不容易坑人的處理(看奇葩的月份參數(shù)啊):
1 func Date(year int, month Month, day, hour, min, sec, nsec int, loc *Location)
我甚至懷疑Google這樣處理是在用極端的方法鄙視Java(另,據(jù)我所知,JavaScript好像也是這樣的,月份從0開(kāi)始)…… 嘗試Joda吧 最開(kāi)始的時(shí)候,Date既要承載日期信息,又要做日期之間的轉(zhuǎn)換,還要做不同日期格式的顯示,職責(zé)較繁雜,從JDK 1.1 開(kāi)始,這三項(xiàng)職責(zé)分開(kāi)了:
  • 使用Calendar類實(shí)現(xiàn)日期和時(shí)間字段之間轉(zhuǎn)換;
  • 使用DateFormat類來(lái)格式化和分析日期字符串;
  • 而Date只用來(lái)承載日期和時(shí)間信息。
  • 原有Date中的相應(yīng)方法已廢棄。不過(guò),無(wú)論是Date,還是Calendar,都用著太不方便了,這是API沒(méi)有設(shè)計(jì)好的地方。 比如Calendar的getInstance方法,并未提供一個(gè)指定年月日和時(shí)分秒的重載方法,每次要指定特定的日期時(shí)間,必須先獲取一個(gè)表示當(dāng)前時(shí)間的Calendar實(shí)例,再去設(shè)值,比如:
    123 Calendar c = Calendar.getInstance();c.set(2012, 0, 1, 11, 11, 11); System.out.println(c.getTime());

    轉(zhuǎn)載于:https://blog.51cto.com/daheyuan/1140096

    總結(jié)

    以上是生活随笔為你收集整理的Java的日期API真烂的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。