简介

  • Date是一个日期相关的类
  • 一般我们都是使用Date来存储日期,如数据库的日期类型
  • 我们操作的会是将其进行格式化,格式化参见下面几篇

    源码

    1. public class Date
    2. implements java.io.Serializable, Cloneable, Comparable<Date>
    3. {
    4. private static final BaseCalendar gcal =
    5. CalendarSystem.getGregorianCalendar();
    6. private static BaseCalendar jcal;
    7. private transient long fastTime;
    8. private transient BaseCalendar.Date cdate;
    9. private static int defaultCenturyStart;
    10. private static final long serialVersionUID = 7523967970034938905L;
    11. // 无参构造方法 ,调用System的静态方法获取系统时间的毫秒数
    12. public Date() {
    13. this(System.currentTimeMillis());
    14. }
    15. // 根据毫秒设置时间
    16. public Date(long date) {
    17. fastTime = date;
    18. }
    19. // 根据年月日设置时间
    20. @Deprecated
    21. public Date(int year, int month, int date) {
    22. this(year, month, date, 0, 0, 0);
    23. }
    24. // 年月日时分
    25. @Deprecated
    26. public Date(int year, int month, int date, int hrs, int min) {
    27. this(year, month, date, hrs, min, 0);
    28. }
    29. // 年月日时分秒
    30. @Deprecated
    31. public Date(int year, int month, int date, int hrs, int min, int sec) {
    32. // 注意是从 1900 + year
    33. int y = year + 1900;
    34. // month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
    35. if (month >= 12) {
    36. y += month / 12;
    37. month %= 12;
    38. } else if (month < 0) {
    39. y += CalendarUtils.floorDivide(month, 12);
    40. month = CalendarUtils.mod(month, 12);
    41. }
    42. BaseCalendar cal = getCalendarSystem(y);
    43. cdate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef());
    44. cdate.setNormalizedDate(y, month + 1, date).setTimeOfDay(hrs, min, sec, 0);
    45. getTimeImpl();
    46. cdate = null;
    47. }
    48. // toString 方法
    49. @Deprecated
    50. public Date(String s) {
    51. this(parse(s));
    52. }
    53. public Object clone() {
    54. Date d = null;
    55. try {
    56. d = (Date)super.clone();
    57. if (cdate != null) {
    58. d.cdate = (BaseCalendar.Date) cdate.clone();
    59. }
    60. } catch (CloneNotSupportedException e) {} // Won't happen
    61. return d;
    62. }
    63. // 获得时间的自1970年1月1日的毫秒数
    64. @Deprecated
    65. public static long UTC(int year, int month, int date,
    66. int hrs, int min, int sec) {
    67. int y = year + 1900;
    68. // month is 0-based. So we have to normalize month to support Long.MAX_VALUE.
    69. if (month >= 12) {
    70. y += month / 12;
    71. month %= 12;
    72. } else if (month < 0) {
    73. y += CalendarUtils.floorDivide(month, 12);
    74. month = CalendarUtils.mod(month, 12);
    75. }
    76. int m = month + 1;
    77. BaseCalendar cal = getCalendarSystem(y);
    78. BaseCalendar.Date udate = (BaseCalendar.Date) cal.newCalendarDate(null);
    79. udate.setNormalizedDate(y, m, date).setTimeOfDay(hrs, min, sec, 0);
    80. // Use a Date instance to perform normalization. Its fastTime
    81. // is the UTC value after the normalization.
    82. Date d = new Date(0);
    83. d.normalize(udate);
    84. return d.fastTime;
    85. }
    86. // 日期转换方法
    87. @Deprecated
    88. public static long parse(String s) {
    89. int year = Integer.MIN_VALUE;
    90. int mon = -1;
    91. int mday = -1;
    92. int hour = -1;
    93. int min = -1;
    94. int sec = -1;
    95. int millis = -1;
    96. int c = -1;
    97. int i = 0;
    98. int n = -1;
    99. int wst = -1;
    100. int tzoffset = -1;
    101. int prevc = 0;
    102. syntax:
    103. {
    104. if (s == null)
    105. break syntax;
    106. int limit = s.length();
    107. while (i < limit) {
    108. c = s.charAt(i);
    109. i++;
    110. if (c <= ' ' || c == ',')
    111. continue;
    112. if (c == '(') { // skip comments
    113. int depth = 1;
    114. while (i < limit) {
    115. c = s.charAt(i);
    116. i++;
    117. if (c == '(') depth++;
    118. else if (c == ')')
    119. if (--depth <= 0)
    120. break;
    121. }
    122. continue;
    123. }
    124. if ('0' <= c && c <= '9') {
    125. n = c - '0';
    126. while (i < limit && '0' <= (c = s.charAt(i)) && c <= '9') {
    127. n = n * 10 + c - '0';
    128. i++;
    129. }
    130. if (prevc == '+' || prevc == '-' && year != Integer.MIN_VALUE) {
    131. // timezone offset
    132. if (n < 24)
    133. n = n * 60; // EG. "GMT-3"
    134. else
    135. n = n % 100 + n / 100 * 60; // eg "GMT-0430"
    136. if (prevc == '+') // plus means east of GMT
    137. n = -n;
    138. if (tzoffset != 0 && tzoffset != -1)
    139. break syntax;
    140. tzoffset = n;
    141. } else if (n >= 70)
    142. if (year != Integer.MIN_VALUE)
    143. break syntax;
    144. else if (c <= ' ' || c == ',' || c == '/' || i >= limit)
    145. // year = n < 1900 ? n : n - 1900;
    146. year = n;
    147. else
    148. break syntax;
    149. else if (c == ':')
    150. if (hour < 0)
    151. hour = (byte) n;
    152. else if (min < 0)
    153. min = (byte) n;
    154. else
    155. break syntax;
    156. else if (c == '/')
    157. if (mon < 0)
    158. mon = (byte) (n - 1);
    159. else if (mday < 0)
    160. mday = (byte) n;
    161. else
    162. break syntax;
    163. else if (i < limit && c != ',' && c > ' ' && c != '-')
    164. break syntax;
    165. else if (hour >= 0 && min < 0)
    166. min = (byte) n;
    167. else if (min >= 0 && sec < 0)
    168. sec = (byte) n;
    169. else if (mday < 0)
    170. mday = (byte) n;
    171. // Handle two-digit years < 70 (70-99 handled above).
    172. else if (year == Integer.MIN_VALUE && mon >= 0 && mday >= 0)
    173. year = n;
    174. else
    175. break syntax;
    176. prevc = 0;
    177. } else if (c == '/' || c == ':' || c == '+' || c == '-')
    178. prevc = c;
    179. else {
    180. int st = i - 1;
    181. while (i < limit) {
    182. c = s.charAt(i);
    183. if (!('A' <= c && c <= 'Z' || 'a' <= c && c <= 'z'))
    184. break;
    185. i++;
    186. }
    187. if (i <= st + 1)
    188. break syntax;
    189. int k;
    190. for (k = wtb.length; --k >= 0;)
    191. if (wtb[k].regionMatches(true, 0, s, st, i - st)) {
    192. int action = ttb[k];
    193. if (action != 0) {
    194. if (action == 1) { // pm
    195. if (hour > 12 || hour < 1)
    196. break syntax;
    197. else if (hour < 12)
    198. hour += 12;
    199. } else if (action == 14) { // am
    200. if (hour > 12 || hour < 1)
    201. break syntax;
    202. else if (hour == 12)
    203. hour = 0;
    204. } else if (action <= 13) { // month!
    205. if (mon < 0)
    206. mon = (byte) (action - 2);
    207. else
    208. break syntax;
    209. } else {
    210. tzoffset = action - 10000;
    211. }
    212. }
    213. break;
    214. }
    215. if (k < 0)
    216. break syntax;
    217. prevc = 0;
    218. }
    219. }
    220. if (year == Integer.MIN_VALUE || mon < 0 || mday < 0)
    221. break syntax;
    222. // Parse 2-digit years within the correct default century.
    223. if (year < 100) {
    224. synchronized (Date.class) {
    225. if (defaultCenturyStart == 0) {
    226. defaultCenturyStart = gcal.getCalendarDate().getYear() - 80;
    227. }
    228. }
    229. year += (defaultCenturyStart / 100) * 100;
    230. if (year < defaultCenturyStart) year += 100;
    231. }
    232. if (sec < 0)
    233. sec = 0;
    234. if (min < 0)
    235. min = 0;
    236. if (hour < 0)
    237. hour = 0;
    238. BaseCalendar cal = getCalendarSystem(year);
    239. if (tzoffset == -1) { // no time zone specified, have to use local
    240. BaseCalendar.Date ldate = (BaseCalendar.Date) cal.newCalendarDate(TimeZone.getDefaultRef());
    241. ldate.setDate(year, mon + 1, mday);
    242. ldate.setTimeOfDay(hour, min, sec, 0);
    243. return cal.getTime(ldate);
    244. }
    245. BaseCalendar.Date udate = (BaseCalendar.Date) cal.newCalendarDate(null); // no time zone
    246. udate.setDate(year, mon + 1, mday);
    247. udate.setTimeOfDay(hour, min, sec, 0);
    248. return cal.getTime(udate) + tzoffset * (60 * 1000);
    249. }
    250. // syntax error
    251. throw new IllegalArgumentException();
    252. }
    253. private final static String wtb[] = {
    254. "am", "pm",
    255. "monday", "tuesday", "wednesday", "thursday", "friday",
    256. "saturday", "sunday",
    257. "january", "february", "march", "april", "may", "june",
    258. "july", "august", "september", "october", "november", "december",
    259. "gmt", "ut", "utc", "est", "edt", "cst", "cdt",
    260. "mst", "mdt", "pst", "pdt"
    261. };
    262. private final static int ttb[] = {
    263. 14, 1, 0, 0, 0, 0, 0, 0, 0,
    264. 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
    265. 10000 + 0, 10000 + 0, 10000 + 0, // GMT/UT/UTC
    266. 10000 + 5 * 60, 10000 + 4 * 60, // EST/EDT
    267. 10000 + 6 * 60, 10000 + 5 * 60, // CST/CDT
    268. 10000 + 7 * 60, 10000 + 6 * 60, // MST/MDT
    269. 10000 + 8 * 60, 10000 + 7 * 60 // PST/PDT
    270. };
    271. // 获取年
    272. @Deprecated
    273. public int getYear() {
    274. return normalize().getYear() - 1900;
    275. }
    276. // 设置年
    277. @Deprecated
    278. public void setYear(int year) {
    279. getCalendarDate().setNormalizedYear(year + 1900);
    280. }
    281. // 返回月
    282. @Deprecated
    283. public int getMonth() {
    284. return normalize().getMonth() - 1; // adjust 1-based to 0-based
    285. }
    286. // 设置月
    287. public void setMonth(int month) {
    288. int y = 0;
    289. if (month >= 12) {
    290. y = month / 12;
    291. month %= 12;
    292. } else if (month < 0) {
    293. y = CalendarUtils.floorDivide(month, 12);
    294. month = CalendarUtils.mod(month, 12);
    295. }
    296. BaseCalendar.Date d = getCalendarDate();
    297. if (y != 0) {
    298. d.setNormalizedYear(d.getNormalizedYear() + y);
    299. }
    300. d.setMonth(month + 1); // adjust 0-based to 1-based month numbering
    301. }
    302. // 获取月的第几天
    303. @Deprecated
    304. public int getDate() {
    305. return normalize().getDayOfMonth();
    306. }
    307. // 设置月的第几天
    308. @Deprecated
    309. public void setDate(int date) {
    310. getCalendarDate().setDayOfMonth(date);
    311. }
    312. // 获取返回该日期是星期几。 返回值(0 =星期日,1 =周一,2 =周二,3 =周三,4 =周四,5 =周五,6 =星期六)
    313. // 表示包含或与此代表了时间的瞬间开始的一周中的一天Date对象在本地时区解释。
    314. @Deprecated
    315. public int getDay() {
    316. return normalize().getDayOfWeek() - BaseCalendar.SUNDAY;
    317. }
    318. // (0至23)
    319. @Deprecated
    320. public int getHours() {
    321. return normalize().getHours();
    322. }
    323. @Deprecated
    324. public void setHours(int hours) {
    325. getCalendarDate().setHours(hours);
    326. }
    327. @Deprecated
    328. public int getMinutes() {
    329. return normalize().getMinutes();
    330. }
    331. @Deprecated
    332. public void setMinutes(int minutes) {
    333. getCalendarDate().setMinutes(minutes);
    334. }
    335. @Deprecated
    336. public int getSeconds() {
    337. return normalize().getSeconds();
    338. }
    339. @Deprecated
    340. public void setSeconds(int seconds) {
    341. getCalendarDate().setSeconds(seconds);
    342. }
    343. //获取毫秒数
    344. public long getTime() {
    345. return getTimeImpl();
    346. }
    347. private final long getTimeImpl() {
    348. if (cdate != null && !cdate.isNormalized()) {
    349. normalize();
    350. }
    351. return fastTime;
    352. }
    353. // 设置时间的毫秒数
    354. public void setTime(long time) {
    355. fastTime = time;
    356. cdate = null;
    357. }
    358. public boolean before(Date when) {
    359. return getMillisOf(this) < getMillisOf(when);
    360. }
    361. public boolean after(Date when) {
    362. return getMillisOf(this) > getMillisOf(when);
    363. }
    364. public boolean equals(Object obj) {
    365. return obj instanceof Date && getTime() == ((Date) obj).getTime();
    366. }
    367. static final long getMillisOf(Date date) {
    368. if (date.cdate == null || date.cdate.isNormalized()) {
    369. return date.fastTime;
    370. }
    371. BaseCalendar.Date d = (BaseCalendar.Date) date.cdate.clone();
    372. return gcal.getTime(d);
    373. }
    374. public int compareTo(Date anotherDate) {
    375. long thisTime = getMillisOf(this);
    376. long anotherTime = getMillisOf(anotherDate);
    377. return (thisTime<anotherTime ? -1 : (thisTime==anotherTime ? 0 : 1));
    378. }
    379. public int hashCode() {
    380. long ht = this.getTime();
    381. return (int) ht ^ (int) (ht >> 32);
    382. }
    383. public String toString() {
    384. // "EEE MMM dd HH:mm:ss zzz yyyy";
    385. BaseCalendar.Date date = normalize();
    386. StringBuilder sb = new StringBuilder(28);
    387. int index = date.getDayOfWeek();
    388. if (index == BaseCalendar.SUNDAY) {
    389. index = 8;
    390. }
    391. convertToAbbr(sb, wtb[index]).append(' '); // EEE
    392. convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
    393. CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 2).append(' '); // dd
    394. CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
    395. CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
    396. CalendarUtils.sprintf0d(sb, date.getSeconds(), 2).append(' '); // ss
    397. TimeZone zi = date.getZone();
    398. if (zi != null) {
    399. sb.append(zi.getDisplayName(date.isDaylightTime(), TimeZone.SHORT, Locale.US)); // zzz
    400. } else {
    401. sb.append("GMT");
    402. }
    403. sb.append(' ').append(date.getYear()); // yyyy
    404. return sb.toString();
    405. }
    406. private static final StringBuilder convertToAbbr(StringBuilder sb, String name) {
    407. sb.append(Character.toUpperCase(name.charAt(0)));
    408. sb.append(name.charAt(1)).append(name.charAt(2));
    409. return sb;
    410. }
    411. @Deprecated
    412. public String toLocaleString() {
    413. DateFormat formatter = DateFormat.getDateTimeInstance();
    414. return formatter.format(this);
    415. }
    416. @Deprecated
    417. public String toGMTString() {
    418. // d MMM yyyy HH:mm:ss 'GMT'
    419. long t = getTime();
    420. BaseCalendar cal = getCalendarSystem(t);
    421. BaseCalendar.Date date =
    422. (BaseCalendar.Date) cal.getCalendarDate(getTime(), (TimeZone)null);
    423. StringBuilder sb = new StringBuilder(32);
    424. CalendarUtils.sprintf0d(sb, date.getDayOfMonth(), 1).append(' '); // d
    425. convertToAbbr(sb, wtb[date.getMonth() - 1 + 2 + 7]).append(' '); // MMM
    426. sb.append(date.getYear()).append(' '); // yyyy
    427. CalendarUtils.sprintf0d(sb, date.getHours(), 2).append(':'); // HH
    428. CalendarUtils.sprintf0d(sb, date.getMinutes(), 2).append(':'); // mm
    429. CalendarUtils.sprintf0d(sb, date.getSeconds(), 2); // ss
    430. sb.append(" GMT"); // ' GMT'
    431. return sb.toString();
    432. }
    433. @Deprecated
    434. public int getTimezoneOffset() {
    435. int zoneOffset;
    436. if (cdate == null) {
    437. TimeZone tz = TimeZone.getDefaultRef();
    438. if (tz instanceof ZoneInfo) {
    439. zoneOffset = ((ZoneInfo)tz).getOffsets(fastTime, null);
    440. } else {
    441. zoneOffset = tz.getOffset(fastTime);
    442. }
    443. } else {
    444. normalize();
    445. zoneOffset = cdate.getZoneOffset();
    446. }
    447. return -zoneOffset/60000; // convert to minutes
    448. }
    449. private final BaseCalendar.Date getCalendarDate() {
    450. if (cdate == null) {
    451. BaseCalendar cal = getCalendarSystem(fastTime);
    452. cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
    453. TimeZone.getDefaultRef());
    454. }
    455. return cdate;
    456. }
    457. private final BaseCalendar.Date normalize() {
    458. if (cdate == null) {
    459. BaseCalendar cal = getCalendarSystem(fastTime);
    460. cdate = (BaseCalendar.Date) cal.getCalendarDate(fastTime,
    461. TimeZone.getDefaultRef());
    462. return cdate;
    463. }
    464. // Normalize cdate with the TimeZone in cdate first. This is
    465. // required for the compatible behavior.
    466. if (!cdate.isNormalized()) {
    467. cdate = normalize(cdate);
    468. }
    469. // If the default TimeZone has changed, then recalculate the
    470. // fields with the new TimeZone.
    471. TimeZone tz = TimeZone.getDefaultRef();
    472. if (tz != cdate.getZone()) {
    473. cdate.setZone(tz);
    474. CalendarSystem cal = getCalendarSystem(cdate);
    475. cal.getCalendarDate(fastTime, cdate);
    476. }
    477. return cdate;
    478. }
    479. // fastTime and the returned data are in sync upon return.
    480. private final BaseCalendar.Date normalize(BaseCalendar.Date date) {
    481. int y = date.getNormalizedYear();
    482. int m = date.getMonth();
    483. int d = date.getDayOfMonth();
    484. int hh = date.getHours();
    485. int mm = date.getMinutes();
    486. int ss = date.getSeconds();
    487. int ms = date.getMillis();
    488. TimeZone tz = date.getZone();
    489. if (y == 1582 || y > 280000000 || y < -280000000) {
    490. if (tz == null) {
    491. tz = TimeZone.getTimeZone("GMT");
    492. }
    493. GregorianCalendar gc = new GregorianCalendar(tz);
    494. gc.clear();
    495. gc.set(GregorianCalendar.MILLISECOND, ms);
    496. gc.set(y, m-1, d, hh, mm, ss);
    497. fastTime = gc.getTimeInMillis();
    498. BaseCalendar cal = getCalendarSystem(fastTime);
    499. date = (BaseCalendar.Date) cal.getCalendarDate(fastTime, tz);
    500. return date;
    501. }
    502. BaseCalendar cal = getCalendarSystem(y);
    503. if (cal != getCalendarSystem(date)) {
    504. date = (BaseCalendar.Date) cal.newCalendarDate(tz);
    505. date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
    506. }
    507. // Perform the GregorianCalendar-style normalization.
    508. fastTime = cal.getTime(date);
    509. // In case the normalized date requires the other calendar
    510. // system, we need to recalculate it using the other one.
    511. BaseCalendar ncal = getCalendarSystem(fastTime);
    512. if (ncal != cal) {
    513. date = (BaseCalendar.Date) ncal.newCalendarDate(tz);
    514. date.setNormalizedDate(y, m, d).setTimeOfDay(hh, mm, ss, ms);
    515. fastTime = ncal.getTime(date);
    516. }
    517. return date;
    518. }
    519. private static final BaseCalendar getCalendarSystem(int year) {
    520. if (year >= 1582) {
    521. return gcal;
    522. }
    523. return getJulianCalendar();
    524. }
    525. private static final BaseCalendar getCalendarSystem(long utc) {
    526. // Quickly check if the time stamp given by `utc' is the Epoch
    527. // or later. If it's before 1970, we convert the cutover to
    528. // local time to compare.
    529. if (utc >= 0
    530. || utc >= GregorianCalendar.DEFAULT_GREGORIAN_CUTOVER
    531. - TimeZone.getDefaultRef().getOffset(utc)) {
    532. return gcal;
    533. }
    534. return getJulianCalendar();
    535. }
    536. private static final BaseCalendar getCalendarSystem(BaseCalendar.Date cdate) {
    537. if (jcal == null) {
    538. return gcal;
    539. }
    540. if (cdate.getEra() != null) {
    541. return jcal;
    542. }
    543. return gcal;
    544. }
    545. synchronized private static final BaseCalendar getJulianCalendar() {
    546. if (jcal == null) {
    547. jcal = (BaseCalendar) CalendarSystem.forName("julian");
    548. }
    549. return jcal;
    550. }
    551. private void writeObject(ObjectOutputStream s)
    552. throws IOException
    553. {
    554. s.writeLong(getTimeImpl());
    555. }
    556. private void readObject(ObjectInputStream s)
    557. throws IOException, ClassNotFoundException
    558. {
    559. fastTime = s.readLong();
    560. }
    561. public static Date from(Instant instant) {
    562. try {
    563. return new Date(instant.toEpochMilli());
    564. } catch (ArithmeticException ex) {
    565. throw new IllegalArgumentException(ex);
    566. }
    567. }
    568. public Instant toInstant() {
    569. return Instant.ofEpochMilli(getTime());
    570. }
    571. }