<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Java好用的時(shí)間類(lèi),別在用Date了

          共 6360字,需瀏覽 13分鐘

           ·

          2022-01-13 16:36

          前言

          假設(shè)你想獲取當(dāng)前時(shí)間,那么你肯定看過(guò)這樣的代碼

          public static void main(String[] args) {

          Date date = new Date(System.currentTimeMillis());
          System.out.println(date.getYear());
          System.out.println(date.getMonth());
          System.out.println(date.getDate());
          }
          復(fù)制代碼

          獲取年份,獲取月份,獲取..日期?
          運(yùn)行一下

          121
          9
          27
          復(fù)制代碼

          怎么回事?獲取年份,日期怎么都不對(duì),點(diǎn)開(kāi)源碼發(fā)現(xiàn)

          /**
          * Returns a value that is the result of subtracting 1900 from the
          * year that contains or begins with the instant in time represented
          * by this Date object, as interpreted in the local
          * time zone.
          *
          * @return the year represented by this date, minus 1900.
          * @see java.util.Calendar
          * @deprecated As of JDK version 1.1,
          * replaced by Calendar.get(Calendar.YEAR) - 1900.
          */
          @Deprecated
          public int getYear() {
          return normalize().getYear() - 1900;
          }
          復(fù)制代碼

          原來(lái)是某個(gè)對(duì)象值 減去了 1900,注釋也表示,返回值減去了1900,難道我們每次獲取年份需要在 加上1900?注釋也說(shuō)明了讓我們 用Calendar.get()替換,并且該方法已經(jīng)被廢棄了。點(diǎn)開(kāi)getMonth()也是一樣,返回了一個(gè)0到11的值。getDate()獲取日期?不應(yīng)該是getDay()嗎?老外的day都是sunday、monday,getDate()才是獲取日期。再注意到這些api都是在1.1的時(shí)候被廢棄了,私以為是為了消除getYear減去1900等這些歧義。收~

          Calendar 日歷類(lèi)

          public static void main(String[] args) {

          Calendar calendar = Calendar.getInstance();
          int year = calendar.get(Calendar.YEAR);
          int month = calendar.get(Calendar.MONTH);
          int dom = calendar.get(Calendar.DAY_OF_MONTH);
          int doy = calendar.get(Calendar.DAY_OF_YEAR);
          int dow = calendar.get(Calendar.DAY_OF_WEEK);
          int dowim = calendar.get(Calendar.DAY_OF_WEEK_IN_MONTH);
          System.out.println(year+"年"+ month+"月");
          System.out.println(dom+"日");
          System.out.println(doy+"日");
          System.out.println(dow+"日");
          System.out.println(dowim);
          }
          復(fù)制代碼

          打印(運(yùn)行時(shí)間2021年10月27日 星期三 晴)

          2021年9月
          27日
          300日
          4日
          4
          復(fù)制代碼

          問(wèn):月份怎么是上個(gè)月的?
          答:是為了計(jì)算方便,月是0到11之間的值。
          問(wèn):計(jì)算方便?
          答:比如月份從1月開(kāi)始,增加一個(gè)月,12月+1=13,沒(méi)有13月。假設(shè)取余,(12+1)%12=1 正好為1月,那11月增加一個(gè)月,(11+1)%12=0,這就有問(wèn)題了。所以為了計(jì)算方便1月,返回了0值。date.getMonth()也是一個(gè)道理。問(wèn):那下面的DAY_OF_XXX 又是什么意思?
          答:猜!根據(jù)結(jié)果猜。
          Calendar.DAY_OF_MONTH ?在這個(gè)月 的這一天
          Calendar.DAY_OF_YEAR 在這一年 的這一天
          Calendar.DAY_OF_WEEK 在這一周 的這一天
          Calendar.DAY_OF_WEEK_IN_MONTH ?在這一個(gè)月 ?這一天在 第幾周
          到這里 Calendar.DAY_OF_WEEK 為什么是 4 ,你肯定也猜到了
          Calendar.HOUR
          Calendar.HOUR_OF_DAY
          Calendar.SECOND
          ...其他的 你肯定也會(huì)用了

          LocalDate 本地日期類(lèi)

          LocalDate localDate = LocalDate.now();
          System.out.println("當(dāng)前日期:"+localDate.getYear()+" 年 "+localDate.getMonthValue()+" 月 "+localDate.getDayOfMonth()+"日" );

          //結(jié)果
          當(dāng)前日期:2021 年 10 月 27日
          復(fù)制代碼

          也可以通過(guò) LocalDate.of(年,月,日)去構(gòu)造

          LocalDate pluslocalDate = localDate.plusDays(1);//增加一天
          LocalDate pluslocalDate = localDate.plusYears(1);//增加一年
          復(fù)制代碼

          其他api

          LocalDate.isBefore(LocalDate);
          LocalDate.isAfter();
          LocalDate.isEqual();
          復(fù)制代碼

          也就是對(duì)兩個(gè)日期的判斷,是在前、在后、或者相等。

          LocalTime 本地時(shí)間類(lèi)

          LocalTime localTime = LocalTime.now();
          System.out.println("當(dāng)前時(shí)間:"+localTime.getHour()+"h "+localTime.getSecond()+"m "+localTime.getMinute()+"s" );
          復(fù)制代碼

          LocalDate和LocalTime 都有類(lèi)似作用的api
          LocalDate.plusDays(1) ?增加一天
          LocalTime.plusHours(1) 增加一小時(shí) 等等~
          其他api

          LocalTime.isBefore(LocalTime);
          LocalTime.isAfter();
          復(fù)制代碼

          對(duì)兩個(gè)時(shí)間的判斷??隙ㄅ龅竭^(guò)一個(gè)需求,今天離活動(dòng)開(kāi)始時(shí)間還剩多少天。

          LocalDateTime 本地日期時(shí)間類(lèi)

          public final class LocalDateTime ...{

          private final LocalDate date;

          private final LocalTime time;
          }
          復(fù)制代碼

          LocalDateTime = LocalDate + LocalTime ?懂的都懂

          Instant 類(lèi)

          Instant 是瞬間,某一時(shí)刻的意思

          Instant.ofEpochMilli(System.currentTimeMillis())
          Instant.now()
          復(fù)制代碼

          通過(guò)Instant可以創(chuàng)建一個(gè) “瞬間” 對(duì)象,ofEpochMilli()可以接受某一個(gè)“瞬間”,比如當(dāng)前時(shí)間,或者是過(guò)去、將來(lái)的一個(gè)時(shí)間。
          比如,通過(guò)一個(gè)“瞬間”創(chuàng)建一個(gè)LocalDateTime對(duì)象

          LocalDateTime now = LocalDateTime.ofInstant(
          Instant.ofEpochMilli(System.currentTimeMillis()),ZoneId.systemDefault());

          System.out.println("當(dāng)前日期:"+now.getYear()+" 年 "+now.getMonthValue()+" 月 "+now.getDayOfMonth()+"日" );
          復(fù)制代碼

          Period 類(lèi)

          Period 是 時(shí)期,一段時(shí)間 的意思
          Period有個(gè)between方法專(zhuān)門(mén)比較兩個(gè) 日期 的

          LocalDate startDate = LocalDateTime.ofInstant(
          Instant.ofEpochMilli(1601175465000L), ZoneId.systemDefault()).toLocalDate();//1601175465000是2020-9-27 10:57:45
          Period p = Period.between(startDate, LocalDate.now());

          System.out.println("目標(biāo)日期距離今天的時(shí)間差:"+p.getYears()+" 年 "+p.getMonths()+" 個(gè)月 "+p.getDays()+" 天" );

          //目標(biāo)日期距離今天的時(shí)間差:1 年 1 個(gè)月 1 天
          復(fù)制代碼

          看一眼源碼

          public static Period between(LocalDate startDateInclusive, LocalDate endDateExclusive) {
          return startDateInclusive.until(endDateExclusive);
          }

          public Period until(ChronoLocalDate endDateExclusive) {
          LocalDate end = LocalDate.from(endDateExclusive);
          long totalMonths = end.getProlepticMonth() - this.getProlepticMonth(); // safe
          int days = end.day - this.day;
          if (totalMonths > 0 && days < 0) {
          totalMonths--;
          LocalDate calcDate = this.plusMonths(totalMonths);
          days = (int) (end.toEpochDay() - calcDate.toEpochDay()); // safe
          } else if (totalMonths < 0 && days > 0) {
          totalMonths++;
          days -= end.lengthOfMonth();
          }
          long years = totalMonths / 12; // safe
          int months = (int) (totalMonths % 12); // safe
          return Period.of(Math.toIntExact(years), months, days);
          }

          復(fù)制代碼

          他只接受兩個(gè)LocalDate對(duì)象,對(duì)時(shí)間的計(jì)算,算好之后返回Period對(duì)象

          Duration 類(lèi)

          Duration 是 期間 持續(xù)時(shí)間 的意思 上代碼

          LocalDateTime end = LocalDateTime.ofInstant(Instant.ofEpochMilli(System.currentTimeMillis()), ZoneId.systemDefault());
          LocalDateTime start = LocalDateTime.ofInstant(Instant.ofEpochMilli(1601175465000L), ZoneId.systemDefault());
          Duration duration = Duration.between(start, end);

          System.out.println("開(kāi)始時(shí)間到結(jié)束時(shí)間,持續(xù)了"+duration.toDays()+"天");
          System.out.println("開(kāi)始時(shí)間到結(jié)束時(shí)間,持續(xù)了"+duration.toHours()+"小時(shí)");
          System.out.println("開(kāi)始時(shí)間到結(jié)束時(shí)間,持續(xù)了"+duration.toMillis()/1000+"秒");
          復(fù)制代碼

          可以看到between也接受兩個(gè)參數(shù),LocalDateTime對(duì)象,源碼是對(duì)兩個(gè)時(shí)間的計(jì)算,并返回對(duì)象。

          對(duì)象轉(zhuǎn)換

          再貼點(diǎn)api

          //long -> LocalDateTime
          LocalDateTime.ofInstant(Instant.ofEpochMilli(timestamp), ZoneId.systemDefault())

          //String -> LocalDateTime
          DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
          LocalDateTime.parse("2021-10-28 00:00:00", dateTimeFormatter1);

          //LocalDateTime -> long
          LocalDateTime對(duì)象.atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();

          //LocalDateTime -> String
          DateTimeFormatter dateTimeFormatter1 = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
          LocalDateTime對(duì)象.format(dateTimeFormatter1)
          復(fù)制代碼

          對(duì)象轉(zhuǎn)換幾乎都涵蓋了,里面有個(gè)時(shí)區(qū)對(duì)象,這個(gè)一般用默認(rèn)時(shí)區(qū)。

          總結(jié)

          用LocalDate、LocalTime、LocalDateTime代替了Date類(lèi)。Date管日期,Time管時(shí)間
          LocalDateTime = LocalDate + LocalTime
          Period 只能用LocalDate
          Duration 持續(xù)時(shí)間,所以L(fǎng)ocalDate、LocalTime、LocalDateTime 都能處理
          至于Calendar 日歷類(lèi),這里面的api,都是針對(duì)日歷的,比如這個(gè)月的第一天是星期幾。
          總體來(lái)說(shuō),都是api的使用,非常清晰,廢棄date.getMonth()等,使用localDate.getMonthValue()來(lái)獲取幾月,更易理解,更易貼合使用。代碼都貼在了github上了


          作者:回眸婉約
          鏈接:https://juejin.cn/post/7024389549652443172
          來(lái)源:稀土掘金
          著作權(quán)歸作者所有。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán),非商業(yè)轉(zhuǎn)載請(qǐng)注明出處。



          瀏覽 111
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  五月丁香在线观看 | 最近中文字幕免费MV第一季歌词怀孕 | 免费看h网站 | 黄色一级片A | 成人做爰A片免费视频 |