日韩成人免费在线_国产成人一二_精品国产免费人成电影在线观..._日本一区二区三区久久久久久久久不

當(dāng)前位置:首頁 > 科技  > 軟件

還在用Calendar操作Date?Java8都被放棄了,你還不知道Java8中全新的日期時間API

來源: 責(zé)編: 時間:2024-03-18 09:38:50 170觀看
導(dǎo)讀引言在過去的Java版本中,日期和時間的處理主要依賴于java.util.Date和java.util.Calendar類,然而隨著業(yè)務(wù)系統(tǒng)的復(fù)雜以及技術(shù)層面的提升,這些傳統(tǒng)的日期時間類暴露出了若干顯著的不足之處。隨著Java8的發(fā)布,其引入了一套

引言

在過去的Java版本中,日期和時間的處理主要依賴于java.util.Date和java.util.Calendar類,然而隨著業(yè)務(wù)系統(tǒng)的復(fù)雜以及技術(shù)層面的提升,這些傳統(tǒng)的日期時間類暴露出了若干顯著的不足之處。隨著Java8的發(fā)布,其引入了一套全新的日期時間API,徹底改變了我們處理日期和時間的方式。nGf28資訊網(wǎng)——每日最新資訊28at.com

傳統(tǒng)的日期時間類

相比較Java8中新引入的java.time包下的時間處理類,傳統(tǒng)的日期時間處理類在易用性,線程安全,不支持市時區(qū)等缺點。nGf28資訊網(wǎng)——每日最新資訊28at.com

  1. 設(shè)計復(fù)雜性:Date類的設(shè)計較為簡單,但它實際上混合了日期和時間信息,并且沒有提供直觀的方法來單獨操作日期或時間部分。Calendar類雖然提供了更多靈活性,但由于其內(nèi)部狀態(tài)和方法的復(fù)雜性,使得開發(fā)者在使用過程中容易出現(xiàn)錯誤和混淆,尤其是在進行日期時間計算和格式化時。比如:
Date currentDate = new Date();  // 輸出原始的日期時間,通常不是人類可讀格式   Fri Mar 08 03:13:47 CST 2024System.out.println(currentDate);// 要改變?nèi)掌诘哪硞€部分,必須先將其轉(zhuǎn)換為 Calendar,然后設(shè)置  Calendar calendar = Calendar.getInstance();  calendar.setTime(currentDate);  // 修改日期的天數(shù)  calendar.add(Calendar.DAY_OF_MONTH, 1);
  1. 線程安全性:Date和 Calendar類,以及格式化日期的SimpleDateFormat類都不是線程安全的,這意味著在多線程環(huán)境下的并發(fā)訪問可能會導(dǎo)致數(shù)據(jù)不一致。

Date類內(nèi)部維護了一個 long 類型的瞬時值,當(dāng)調(diào)用如setTime()方法來更新這個瞬時值時,不同的線程同時調(diào)用就會互相覆蓋彼此的值,造成數(shù)據(jù)不一致。nGf28資訊網(wǎng)——每日最新資訊28at.com

Calendar類不僅包含了日期和時間信息,還有一系列內(nèi)部狀態(tài)變量,如年、月、日、小時、分鐘、秒等。Calendar類的方法通常會修改這些內(nèi)部狀態(tài),例如 add()、set() 等。在多線程環(huán)境下,若多個線程嘗試同時修改同一個 Calendar 實例,也會導(dǎo)致不可預(yù)期的結(jié)果。nGf28資訊網(wǎng)——每日最新資訊28at.com

SimpleDateFormat類在執(zhí)行格式化和解析日期時間操作時,內(nèi)部會維護一個 Calendar對象以及其他一些狀態(tài)變量。在 format() 或 parse() 方法執(zhí)行過程中,這些狀態(tài)會被更新以完成格式轉(zhuǎn)換。并且SimpleDateFormat中的方法并非原子操作,因此在多線程并發(fā)調(diào)用時,可能在一個線程還未完成整個操作時就被另一個線程打斷,導(dǎo)致錯誤的日期時間處理結(jié)果。nGf28資訊網(wǎng)——每日最新資訊28at.com

  1. 時區(qū)處理能力:Date類雖能表示時間戳,但它不直接關(guān)聯(lián)時區(qū)信息,難以進行時區(qū)相關(guān)的轉(zhuǎn)換。而 Calendar 雖然支持時區(qū),但操作過程相當(dāng)復(fù)雜。
  2. 精度差異:Date類精度只到毫秒級。

Java8中日期時間類

Java8中引入的LocalDate,LocalTime,LocalDateTime這幾個位于java.time下的類克服了上述傳統(tǒng)類別的局限性,提供了更強大、直觀和精準(zhǔn)的日期時間處理能力,成為現(xiàn)代Java開發(fā)中處理日期時間首選的工具類。相比較傳統(tǒng)的日期時間類,具備以下顯著優(yōu)勢:nGf28資訊網(wǎng)——每日最新資訊28at.com

  1. 功能豐富java.time包下的類如 LocalDate、LocalTime、LocalDateTime、ZonedDateTime 等都有明確的職責(zé)劃分,分別處理日期、時間、日期時間以及帶時區(qū)的日期時間,結(jié)構(gòu)清晰,易于理解和使用。并且它們提供了一系列直觀、面向?qū)ο蟮腁PI,如 plusXxx()、minusXxx()、withXxx()等方法,使日期時間操作變得簡單明了。
  2. 時區(qū)支持除此之外,還支持時區(qū),通過ZonedDateTime和 ZoneId等類提供了對時區(qū)的更好支持,可以方便地進行時區(qū)轉(zhuǎn)換和處理。
  3. 線程安全這些類都是不可變對象,線程安全,可以在多線程環(huán)境下安全使用,不會出現(xiàn)因并發(fā)操作導(dǎo)致的數(shù)據(jù)不一致問題。
  4. 更高的精度支持納秒級精度,相比 Date 類的毫秒精度更勝一籌。

java.time下主要有如下一些關(guān)鍵類:nGf28資訊網(wǎng)——每日最新資訊28at.com

  1. LocalDateLocalDate類表示一個不包含時間信息的日期,只包含年、月、日三個部分,且不關(guān)聯(lián)任何特定時區(qū)。
  2. LocalTimeLocalTime類表示一個不包含日期信息的具體時間,包含時、分、秒和納秒四個部分。
  3. LocalDateTimeLocalDateTime類結(jié)合了日期和時間,表示一個具體的日期和時間點,但是不包含時區(qū)信息。
  4. ZonedDateTimeZonedDateTime類表示一個帶有時區(qū)的日期時間,它可以明確表示某一特定時區(qū)內(nèi)的某一確切時間點。
  5. InstantInstant類表示時間線上某一瞬時點,通常以Unix紀(jì)元(1970-01-01T00:00:00Z)以來的秒數(shù)和納秒數(shù)表示,它是全球通用的時間點表示。
  6. PeriodPeriod類用于表示兩個日期之間的期間,包括年、月、日的數(shù)量。
  7. DurationDuration類表示兩個時間點之間的時間差,包含秒和納秒的持續(xù)時間,主要用于表示時間間隔而非日歷單位。
  8. DateTimeFormatterDateTimeFormatter類用于日期時間的格式化和解析,提供了標(biāo)準(zhǔn)化和自定義的日期時間格式化方式。
  9. TemporalAdjustersTemporalAdjusters類提供了一系列實用方法,用于調(diào)整日期時間,例如獲取下一個工作日、月初、月末等。

這些類共同構(gòu)成了一個強大、靈活且易于使用的日期時間處理體系,大大改善了Java在處理日期時間問題時的效率和準(zhǔn)確性。接下來我們在使用上分別介紹這些類,以及使用他們的方式,感受他們的強大。nGf28資訊網(wǎng)——每日最新資訊28at.com

Java8中日期時間類使用

創(chuàng)建

NOW方法獲取當(dāng)前 時刻、日期、時間
LocalTime localTime = LocalTime.now();  System.out.println("localTime:"+localTime);  LocalDate localDate = LocalDate.now();  System.out.println("localDate:"+localDate);  LocalDateTime localDateTime = LocalDateTime.now();  System.out.println("localDateTime:"+localDateTime);

輸出為:nGf28資訊網(wǎng)——每日最新資訊28at.com

localTime:15:28:45.241181localDate:2024-03-11localDateTime:2024-03-11T15:28:45.260655

針對LocalTime,LocalDateTime獲取當(dāng)前時刻默認(rèn)會帶有毫秒,如果不需要毫秒的話,可以通過設(shè)置納秒為0 保留秒 1秒 = 十億納秒 。例如:nGf28資訊網(wǎng)——每日最新資訊28at.com

LocalTime localTime = LocalTime.now().withNano(0);System.out.println("localTime:"+localTime);  LocalDateTime localDateTime = LocalDateTime.now().withNano(0);  System.out.println("localDateTime:"+localDateTime);

輸出為:nGf28資訊網(wǎng)——每日最新資訊28at.com

localTime:15:32:31localDateTime:2024-03-11T15:32:31

而對于LocalDateTime獲取當(dāng)前日期,默認(rèn)toString會帶有T分隔日期和時間,在項目中,可以通過全局序列化,進行統(tǒng)一的時間格式輸出為 yyyy-MM-dd HH:mm:ss。但是一般不建議這么干,畢竟改變?nèi)中蛄谢渲茫ㄗh不使用toString,可以使用DateTimeFormatter進行自定義轉(zhuǎn)換。nGf28資訊網(wǎng)——每日最新資訊28at.com

of()方法指定年、月、日、時刻創(chuàng)建
// of方法直接傳遞對應(yīng)的年、月、日  LocalDate localDate = LocalDate.of(2024, 3, 11);  System.out.println("localDate:"+localDate);  localDate = LocalDate.of(2024, Month.MARCH, 11);  System.out.println("localDate:"+localDate);  localDate = LocalDate.ofYearDay(2024, 71);  System.out.println("localDate:"+localDate);  // 北京時間對應(yīng)的時區(qū)  ZoneId chinaTimeZone = ZoneId.of("Asia/Shanghai");  // 創(chuàng)建一個 Instant,這里使用當(dāng)前時間的 InstantInstant instant = Instant.now();  localDate = LocalDate.ofInstant(instant, chinaTimeZone);  System.out.println("localDate:"+localDate);  // 使用ofEpochDay()方法,則EpochDay為從公元1970年1月1日(Unix紀(jì)元)開始的第多少天  localDate = LocalDate.ofEpochDay(LocalDate.now().toEpochDay());  System.out.println("localDate:"+localDate);  LocalTime localTime = LocalTime.of(1, 30);  System.out.println("localTime:"+localTime);  localTime = LocalTime.of(1, 30, 30);  System.out.println("localTime:"+localTime);  localTime = LocalTime.ofInstant(instant, chinaTimeZone);  System.out.println("localTime:"+localTime);  // 根據(jù)一天中的總秒數(shù)構(gòu)建時間localTime = LocalTime.ofSecondOfDay(localTime.toSecondOfDay());  System.out.println("localTime:"+localTime);  LocalDateTime localDateTime = LocalDateTime.of(2024, 3, 11, 1, 30, 30);  System.out.println("localDateTime:"+localDateTime);  localDateTime = LocalDateTime.of(2024, Month.MARCH, 11, 1, 30, 30);  System.out.println("localDateTime:"+localDateTime);  // 使用LocalDate和LocalTime組合構(gòu)造  localDateTime = LocalDateTime.of(localDate, localTime);  System.out.println("localDateTime:"+localDateTime);  localDateTime = LocalDateTime.ofInstant(instant, chinaTimeZone);  System.out.println("localDateTime:"+localDateTime);

輸出為:nGf28資訊網(wǎng)——每日最新資訊28at.com

localDate:2024-03-11localDate:2024-03-11localDate:2024-03-11localDate:2024-03-11localDate:2024-03-11localTime:01:30localTime:01:30:30localTime:16:41:37.893310localTime:16:41:37localDateTime:2024-03-11T01:30:30localDateTime:2024-03-11T01:30:30localDateTime:2024-03-11T16:41:37localDateTime:2024-03-11T16:41:37.893310
from()方法轉(zhuǎn)換

from()方法將TemporalAccessor類型(如ZonedDateTime)轉(zhuǎn)換為相對應(yīng)的日期或者時間。TemporalAccessor接口是一個用于讀取或?qū)懭肴掌凇r間或者日期時間的通用接口。nGf28資訊網(wǎng)——每日最新資訊28at.com

// 創(chuàng)建一個ZonedDateTime實例  ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of("Asia/Shanghai"));  LocalTime localTime = LocalTime.from(zonedDateTime);  System.out.println("localTime:"+localTime);  LocalDate localDate = LocalDate.from(zonedDateTime);  System.out.println("localDate:"+localDate);  LocalDateTime localDateTime = LocalDateTime.from(zonedDateTime);  System.out.println("localDateTime:"+localDateTime);

輸出為:nGf28資訊網(wǎng)——每日最新資訊28at.com

localTime:17:18:27.942911localDate:2024-03-11localDateTime:2024-03-11T17:18:27.942911
parse()方法轉(zhuǎn)換

將字符串按照指定格式(可選)解析為對應(yīng)的日期時間類。nGf28資訊網(wǎng)——每日最新資訊28at.com

LocalTime localTime = LocalTime.parse("17:25:30");  System.out.println("localTime:"+localTime);  localTime = LocalTime.parse("17:25:30", DateTimeFormatter.ofPattern("HH:mm:ss"));  System.out.println("localTime:"+localTime);  LocalDate localDate = LocalDate.parse("2024-03-11");  System.out.println("localDate:"+localDate);  localDate = LocalDate.parse("2024/03/11", DateTimeFormatter.ofPattern("yyyy/MM/dd"));  System.out.println("localDate:"+localDate);  LocalDateTime localDateTime = LocalDateTime.parse("2024-03-11T17:25:30");  System.out.println("localDateTime:"+localDateTime);  localDateTime = LocalDateTime.parse("2024/03/11 17:25:30", DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss"));  System.out.println("localDateTime:"+localDateTime);

輸出為:nGf28資訊網(wǎng)——每日最新資訊28at.com

localTime:17:25:30localTime:17:25:30localDate:2024-03-11localDate:2024-03-11localDateTime:2024-03-11T17:25:30localDateTime:2024-03-11T17:25:30

日期時間類的相互轉(zhuǎn)換

LocalTime、LocalDate、LocalDateTime 相互轉(zhuǎn)化
// LocalTime + LocalDate = LocalDateTimeLocalDateTime localDateTime = LocalTime.now().atDate(LocalDate.now());System.out.println("localDateTime:"+localDateTime);localDateTime = LocalDate.now().atTime(LocalTime.now());System.out.println("localDateTime:"+localDateTime);localDateTime = LocalDateTime.of(LocalDate.now(), LocalTime.now());System.out.println("localDateTime:"+localDateTime);// LocalDateTime 轉(zhuǎn) LocalDateLocalDate localDate = LocalDateTime.now().toLocalDate();System.out.println("localDate:"+localDate);// LocalDateTime 轉(zhuǎn) LocalTimeLocalTime localTime = LocalDateTime.now().toLocalTime();System.out.println("localTime:"+localTime);// 獲取今日開始時間 2024-03-11T00:00localDateTime = LocalDate.now().atStartOfDay();System.out.println("localDateTime:"+localDateTime);// 獲取今日開始時間 2024-03-11T00:00LocalDateTime startDateTime = LocalDateTime.of(LocalDate.now(), LocalTime.MIN);System.out.println("startDateTime:"+ startDateTime);// 獲取今日結(jié)束時間 2024-03-11T23:59:59.999999999LocalDateTime endDateTime = LocalDateTime.of(LocalDate.now(), LocalTime.MAX);System.out.println("endDateTime:"+ endDateTime);

輸出為:nGf28資訊網(wǎng)——每日最新資訊28at.com

localDateTime:2024-03-11T18:04:22.348539localDateTime:2024-03-11T18:04:22.370562localDateTime:2024-03-11T18:04:22.370768localDate:2024-03-11localTime:18:04:22.371062localDateTime:2024-03-11T00:00startDateTime:2024-03-11T00:00endDateTime:2024-03-11T23:59:59.999999999
String 與 LocalTime、LocalDate、LocalDateTime 相互轉(zhuǎn)化

主要使用format 和 parse 進行轉(zhuǎn)換,使用方法基本相同。使用 DateTimeFormatter.ofPattern() 定義時間格式,再進行轉(zhuǎn)換。DateTimeFormatter線程安全。nGf28資訊網(wǎng)——每日最新資訊28at.com

// LocalTime 轉(zhuǎn) String 自定義輸出格式,例如:**時**分**秒 該轉(zhuǎn)化的 00 不會被省略String localTimeStr = LocalTime.now().format(DateTimeFormatter.ofPattern("HH時mm分ss秒"));System.out.println("localTimeStr:"+localTimeStr);String localDateStr = LocalDate.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));System.out.println("localDateStr:"+localDateStr);// LocalDateTime 轉(zhuǎn) StringString localDateTimeStr = LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));System.out.println("localDateTimeStr:"+localDateTimeStr);// String 轉(zhuǎn) LocalDateTimeLocalDateTime localDateTime = LocalDateTime.parse("2023-04-14 15:59:40", DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));System.out.println("localDateTime:"+localDateTime);

輸出結(jié)果:nGf28資訊網(wǎng)——每日最新資訊28at.com

localTimeStr:19時02分58秒localDateStr:2024-03-11localDateTimeStr:2024-03-11 19:02:58localDateTime:2023-04-14T15:59:40
Date 與 LocalDate、LocalDateTime 相互轉(zhuǎn)化
// Date 轉(zhuǎn) LocalDateTimeDate currentDate = new Date();// 轉(zhuǎn)換為Instant Instant instant = currentDate.toInstant();// 通過zoneId設(shè)置時區(qū)(這里使用系統(tǒng)時區(qū)),轉(zhuǎn)換為帶帶時區(qū)的 ZoneDateTimeZonedDateTime zonedDateTime = instant.atZone(ZoneId.systemDefault());// 然后通過ZonedDateTime轉(zhuǎn)換為LocalDateTimeLocalDateTime localDateTime = zonedDateTime.toLocalDateTime();System.out.println("localDateTime:"+localDateTime);// LocalDateTime 轉(zhuǎn) Date,同理也是通過ZonedDateTime轉(zhuǎn)換為DateDate localDateTimeToDate = Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());System.out.println(localDateTimeToDate);// Date轉(zhuǎn)LocalDate 同理 LocalDateTime轉(zhuǎn)換LocalDate localDate = currentDate.toInstant().atZone(ZoneId.systemDefault()).toLocalDate();System.out.println("localDate:"+localDate);// LocalDate 轉(zhuǎn) Date  需要先將 LocalDate 轉(zhuǎn) LocalDateTimeDate localDateToDate = Date.from(LocalDate.now().atStartOfDay(ZoneId.systemDefault()).toInstant());

這里介紹一下ZoneId。java.time.ZoneId是Java 8中java.time包中用于表示時區(qū)的類。時區(qū)是地球上的地理位置,用于確定在該位置觀察太陽升落以及規(guī)定當(dāng)?shù)鼐用裆詈蜕虡I(yè)活動時間的標(biāo)準(zhǔn)時間。ZoneId使用IANA時區(qū)數(shù)據(jù)庫提供的時區(qū)標(biāo)識符,這個標(biāo)識符是唯一的,這些標(biāo)識符通常是地區(qū)/城市對,例如“Asia/Shanghai”代表中國上海所在的時區(qū),America/New_York代表美國紐約城市。其實例獲取有兩種方式:nGf28資訊網(wǎng)——每日最新資訊28at.com

  • ZoneId.systemDefault():獲取系統(tǒng)默認(rèn)的時區(qū)ID。
  • ZoneId.of(String zoneId):根據(jù)提供的時區(qū)ID字符串獲取ZoneId實例。至于zoneId的值,可以查看源碼。可以通過ZoneId.getAvailableZoneIds()查看獲取。
Long 與 LocalDate、LocalDateTime 相互轉(zhuǎn)化

時間戳轉(zhuǎn)換。nGf28資訊網(wǎng)——每日最新資訊28at.com

long timeMillis = System.currentTimeMillis();// 時間戳(Long) 轉(zhuǎn) LocalDateTimeLocalDateTime localDateTime = Instant.ofEpochMilli(timeMillis).atZone(ZoneOffset.ofHours(8)).toLocalDateTime();System.out.println("localDateTime:"+localDateTime);localDateTime = Instant.ofEpochMilli(timeMillis).atZone(ZoneId.systemDefault()).toLocalDateTime();System.out.println("localDateTime:"+localDateTime);// LocalDateTime 轉(zhuǎn) 時間戳(Long) 秒級long localDateTimeToSecond = LocalDateTime.now().toEpochSecond(ZoneOffset.ofHours(8));System.out.println("localDateTimeToSecond:"+ localDateTimeToSecond);// LocalDateTime 轉(zhuǎn) 時間戳(Long) 毫秒級long localDateTimeToMilliSecond = LocalDateTime.now().toInstant(ZoneOffset.ofHours(8)).toEpochMilli();System.out.println("localDateTimeToMilliSecond:"+ localDateTimeToMilliSecond);// 時間戳(Long) 轉(zhuǎn) LocalDateLocalDate localDate = Instant.ofEpochMilli(timeMillis).atZone(ZoneOffset.ofHours(8)).toLocalDate();System.out.println("localDate:"+ localDate);// LocalDate 轉(zhuǎn) 時間戳(Long) 秒級long localDateToSecond =  LocalDate.now().atStartOfDay().toEpochSecond(ZoneOffset.ofHours(8));System.out.println("localDateToSecond:"+ localDateToSecond);// LocalDate 轉(zhuǎn) 時間戳(Long) 毫秒級long localDateToMilliSecond = LocalDate.now().atStartOfDay().toInstant(ZoneOffset.ofHours(8)).toEpochMilli();System.out.println("localDateToMilliSecond:"+ localDateToMilliSecond);

輸出結(jié)果為:nGf28資訊網(wǎng)——每日最新資訊28at.com

localDateTime:2024-03-11T19:37:02.335localDateTime:2024-03-11T19:37:02.335localDateTimeToSecond:1710157022localDateTimeToMilliSecond:1710157022365localDate:2024-03-11localDateToSecond:1710086400localDateToMilliSecond:1710086400000

java.time.ZoneOffset是Java8中java.time包內(nèi)用來表示時區(qū)偏移量的類,它表示的是格林尼治標(biāo)準(zhǔn)時間或協(xié)調(diào)世界時間(UTC)基礎(chǔ)上的固定偏移量。每一個時區(qū)都可以通過一個或多個偏移量來表示,比如“+02:00”表示比UTC時間快兩個小時的時區(qū)偏移。其實例創(chuàng)建有如下方式:nGf28資訊網(wǎng)——每日最新資訊28at.com

  • ZoneOffset.ofHours(int hours):根據(jù)小時數(shù)創(chuàng)建偏移量,例如 ZoneOffset.ofHours(2) 表示比UTC早2小時的時區(qū)。
  • ZoneOffset.ofHoursMinutes(int hours, int minutes):根據(jù)小時數(shù)和分鐘數(shù)創(chuàng)建偏移量。
  • ZoneOffset.ofHoursMinutesSeconds(int hours, int minutes, int seconds):根據(jù)小時、分鐘和秒數(shù)創(chuàng)建偏移量。
  • ZoneOffset.ofTotalSeconds(int totalSeconds):根據(jù)相對于UTC的總秒數(shù)創(chuàng)建偏移量。
  • ZoneOffset.of(String offsetId):根據(jù)偏移量ID(如 "+02:00")創(chuàng)建實例。

日期時間類的操作

日期時間的增減

java.time 包中日期時間類(如 LocalDateTime、LocalDate 和 LocalTime)可以通過plusXxx() 和 minusXxx() 方法,用于對日期時間對象進行加減操作,以增加或減少指定的時間或日期單位。nGf28資訊網(wǎng)——每日最新資訊28at.com

1、LocalDateTime 加減:nGf28資訊網(wǎng)——每日最新資訊28at.com

  • plusHours(int hours), plusMinutes(int minutes), plusSeconds(int seconds):分別用于向 LocalDateTime 對象添加指定的小時數(shù)、分鐘數(shù)和秒數(shù)。
  • plus(1, ChronoUnit.XXX):這里的 ChronoUnit 參數(shù)可以是 HOURS、MINUTES、SECONDS 等,也可以是 YEARS、MONTHS、DAYS、WEEKS 等,用于向日期時間對象添加指定單位的數(shù)量。
  • plus(Duration duration):使用 Duration 對象來增加時間,Duration 可以包含秒和納秒的精度。
  • plus(Period period):使用 Period 對象來增加日期,Period 可以表示年、月、日的數(shù)量。
  • 與plusXxx() 方法相對應(yīng),minusXxx() 方法用于從日期時間對象中減少指定的單位。例如 minusHours(int hours)、minusMinutes(int minutes)、minusSeconds(int seconds) 等方法用于減少小時、分鐘、秒數(shù)。
// LocalDateTime 加減LocalDateTime localDateTime = LocalDateTime.now();// 以下為增加時、分、秒LocalDateTime plusLocalDateTime = localDateTime.plusHours(1).plusMinutes(1).plusSeconds(1);System.out.println("plusLocalDateTime:"+plusLocalDateTime);plusLocalDateTime = localDateTime.plus(1, ChronoUnit.HOURS).plus(1, ChronoUnit.MINUTES).plus(1, ChronoUnit.SECONDS);System.out.println("plusLocalDateTime:"+plusLocalDateTime);plusLocalDateTime = localDateTime.plus(Duration.ofHours(1)).plus(Duration.of(1, ChronoUnit.MINUTES)).plus(Duration.of(1, ChronoUnit.SECONDS));System.out.println("plusLocalDateTime:"+plusLocalDateTime);// 以下為增加年、月、日plusLocalDateTime = localDateTime.plusYears(1).plusMonths(1).plusWeeks(1).plusDays(1);System.out.println("plusLocalDateTime:"+plusLocalDateTime);plusLocalDateTime = localDateTime.plus(1, ChronoUnit.YEARS).plus(1, ChronoUnit.MONTHS).plus(1, ChronoUnit.WEEKS).plus(1, ChronoUnit.DAYS);System.out.println("plusLocalDateTime:"+plusLocalDateTime);plusLocalDateTime = localDateTime.plus(Duration.of(1, ChronoUnit.YEARS)).plus(Duration.of(1, ChronoUnit.MONTHS)).plus(Duration.of(1, ChronoUnit.WEEKS)).plus(Duration.ofDays(1));System.out.println("plusLocalDateTime:"+plusLocalDateTime);plusLocalDateTime = localDateTime.plus(Period.ofYears(1)).plus(Period.ofMonths(1)).plus(Period.ofWeeks(1)).plus(Period.ofDays(1));System.out.println("plusLocalDateTime:"+plusLocalDateTime);// 以下為減少時、分、秒LocalDateTime minusLocalDateTime = localDateTime.minusHours(1).minusMinutes(1).minusSeconds(1);System.out.println("minusLocalDateTime:"+minusLocalDateTime);minusLocalDateTime = localDateTime.minus(1, ChronoUnit.HOURS).minus(1, ChronoUnit.MINUTES).minus(1, ChronoUnit.SECONDS);System.out.println("minusLocalDateTime:"+minusLocalDateTime);minusLocalDateTime = localDateTime.minus(Duration.ofHours(1)).minus(Duration.of(1, ChronoUnit.MINUTES)).minus(Duration.of(1, ChronoUnit.SECONDS));System.out.println("minusLocalDateTime:"+minusLocalDateTime);// 以下為減少年、月、日minusLocalDateTime = localDateTime.minusYears(1).minusMonths(1).minusWeeks(1).minusDays(1);System.out.println("minusLocalDateTime:"+minusLocalDateTime);minusLocalDateTime = localDateTime.minus(1, ChronoUnit.YEARS).minus(1, ChronoUnit.MONTHS).minus(1, ChronoUnit.WEEKS).minus(1, ChronoUnit.DAYS);System.out.println("minusLocalDateTime:"+minusLocalDateTime);minusLocalDateTime = localDateTime.minus(Duration.of(1, ChronoUnit.YEARS)).minus(Duration.of(1, ChronoUnit.MONTHS)).minus(Duration.of(1, ChronoUnit.WEEKS)).minus(Duration.ofDays(1));System.out.println("minusLocalDateTime:"+minusLocalDateTime);minusLocalDateTime = localDateTime.minus(Period.ofYears(1)).minus(Period.ofMonths(1)).minus(Period.ofWeeks(1)).minus(Period.ofDays(1));System.out.println("plusLocalDateTime:"+minusLocalDateTime);

2、LocalDate 加減:nGf28資訊網(wǎng)——每日最新資訊28at.com

  • 同樣的,plusYears(int years), plusMonths(int months), plusDays(int days) 分別用于增加年、月、日。
  • plus(1, ChronoUnit.XXX)和plus(Duration/Period duration/period) 方法在此同樣適用,用于增加指定的日期單位。
  • 與plusXxx() 方法相對應(yīng),minusXxx() 方法用于從日期時間對象中減少指定的單位。例如 minusYears(int years)、minusMonths(int months)、minusWeeks(int weeks)、minusDays(int days) 等方法用于減少年、月、周、天數(shù)。
// LocalDate 加減LocalDate localDate = LocalDate.now();LocalDate plusLocalDate = localDate.plusYears(1).plusMonths(1).plusWeeks(1).plusDays(1);System.out.println("plusLocalDate:"+plusLocalDate);plusLocalDate = localDate.plus(1, ChronoUnit.YEARS).plus(1, ChronoUnit.MONTHS).plus(1, ChronoUnit.WEEKS).plus(1, ChronoUnit.DAYS);System.out.println("plusLocalDate:"+plusLocalDate);plusLocalDate = localDate.plus(Duration.of(1, ChronoUnit.YEARS)).plus(Duration.of(1, ChronoUnit.MONTHS)).plus(Duration.of(1, ChronoUnit.WEEKS)).plus(Duration.ofDays(1));System.out.println("plusLocalDate:"+plusLocalDate);plusLocalDate = localDate.plus(Period.ofYears(1)).plus(Period.ofMonths(1)).plus(Period.ofWeeks(1)).plus(Period.ofDays(1));System.out.println("plusLocalDate:"+plusLocalDate);LocalDate minusLocalDate = localDate.minusYears(1).minusMonths(1).minusWeeks(1).minusDays(1);System.out.println("minusLocalDate:"+minusLocalDate);minusLocalDate = localDate.minus(1, ChronoUnit.YEARS).minus(1, ChronoUnit.MONTHS).minus(1, ChronoUnit.WEEKS).minus(1, ChronoUnit.DAYS);System.out.println("minusLocalDate:"+minusLocalDate);minusLocalDate = localDate.minus(Duration.of(1, ChronoUnit.YEARS)).minus(Duration.of(1, ChronoUnit.MONTHS)).minus(Duration.of(1, ChronoUnit.WEEKS)).minus(Duration.ofDays(1));System.out.println("minusLocalDate:"+minusLocalDate);minusLocalDate = localDate.minus(Period.ofYears(1)).minus(Period.ofMonths(1)).minus(Period.ofWeeks(1)).minus(Period.ofDays(1));System.out.println("minusLocalDate:"+minusLocalDate);

3、LocalTime 加減:nGf28資訊網(wǎng)——每日最新資訊28at.com

  • plusHours(int hours), plusMinutes(int minutes), plusSeconds(int seconds):分別用于向 LocalTime 對象添加指定的小時數(shù)、分鐘數(shù)和秒數(shù)。
  • 同樣支持 plus(1, ChronoUnit.XXX) 和 plus(Duration duration) 方法,用于增加時間單位。
  • 與 plusXxx() 方法相對應(yīng),minusXxx() 方法用于從日期時間對象中減少指定的單位。minus(1, ChronoUnit.XXX), minus(Duration duration), minus(Period period) 方法也分別用于減少指定的日期或時間單位。例如 minusHours(int hours)、minusMinutes(int minutes)、minusSeconds(int seconds) 等方法用于減少小時、分鐘、秒數(shù)。
// LocalTime 加減LocalTime localTime = LocalTime.now();LocalTime plusLocalTime = localTime.plusHours(1).plusMinutes(1).plusSeconds(1);System.out.println("plusLocalTime:"+plusLocalTime);plusLocalTime = localTime.plus(1, ChronoUnit.HOURS).plus(1, ChronoUnit.MINUTES).plus(1, ChronoUnit.SECONDS);System.out.println("plusLocalTime:"+plusLocalTime);plusLocalTime = localTime.plus(Duration.ofHours(1)).plus(Duration.of(1, ChronoUnit.MINUTES)).plus(Duration.of(1, ChronoUnit.SECONDS));System.out.println("plusLocalTime:"+plusLocalTime);LocalTime minusLocalTime = localTime.minusHours(1).minusMinutes(1).minusSeconds(1);System.out.println("minusLocalTime:"+minusLocalTime);minusLocalTime = localTime.minus(1, ChronoUnit.HOURS).minus(1, ChronoUnit.MINUTES).minus(1, ChronoUnit.SECONDS);System.out.println("minusLocalDateTime:"+minusLocalTime);minusLocalTime = localTime.minus(Duration.ofHours(1)).minus(Duration.of(1, ChronoUnit.MINUTES)).minus(Duration.of(1, ChronoUnit.SECONDS));System.out.println("minusLocalDateTime:"+minusLocalTime);
日期時間修改指定值

LocalDate、LocalTime、LocalDateTime、ZonedDateTime可以通過相對應(yīng)的withXxx()方法修改指定的值。nGf28資訊網(wǎng)——每日最新資訊28at.com

1、LocalDate:nGf28資訊網(wǎng)——每日最新資訊28at.com

  • LocalDate.withYear(int year):修改年份字段。
  • LocalDate.withMonth(int month):修改月份字段(注意月份是從1開始計數(shù)的)。
  • LocalDate.withDayOfMonth(int dayOfMonth):修改日期字段。
LocalDate localDate = LocalDate.of(2024, 3, 12);LocalDate newDate = localDate.withYear(2025).withMonth(4).with(ChronoField.DAY_OF_MONTH, 13);System.out.println("newDate:"+newDate);

2、LocalTime:nGf28資訊網(wǎng)——每日最新資訊28at.com

  • LocalTime.withHour(int hour):修改小時字段。
  • LocalTime.withMinute(int minute):修改分鐘字段。
  • LocalTime.withSecond(int second):修改秒字段。
  • LocalTime.withNano(int nanoOfSecond):修改納秒字段。
LocalTime localTime = LocalTime.of(17, 25, 30);LocalTime newTime = localTime.withHour(18).withMinute(26).with(ChronoField.SECOND_OF_MINUTE, 31);System.out.println("newTime:"+newTime);

3、LocalDateTime:nGf28資訊網(wǎng)——每日最新資訊28at.com

  • LocalDateTime.withYear(int year)
  • LocalDateTime.withMonth(int month)
  • LocalDateTime.withDayOfMonth(int dayOfMonth)
  • LocalDateTime.withHour(int hour)
  • LocalDateTime.withMinute(int minute)
  • LocalDateTime.withSecond(int second)
  • LocalDateTime.withNano(int nanoOfSecond)
LocalDateTime localDateTime = LocalDateTime.of(2024, 3, 12, 17, 25, 30);LocalDateTime newDateTime = localDateTime.withYear(2025).withMonth(4).with(ChronoField.DAY_OF_MONTH, 13).withHour(18).withMinute(26).with(ChronoField.SECOND_OF_MINUTE, 31);System.out.println("newDateTime:"+ newDateTime);

4、ZonedDateTime:nGf28資訊網(wǎng)——每日最新資訊28at.com

  • 除了上述的日期和時間字段外,還有時區(qū)相關(guān)的 withZoneSameInstant(ZoneId zone) 方法,可以改變時區(qū)的同時保持同一瞬間不變。
ZonedDateTime zonedDateTime = ZonedDateTime.of(2024, 3, 12, 17, 25, 30, 0, ZoneId.of("Europe/London"));ZonedDateTime newZonedDateTime = zonedDateTime.withZoneSameInstant(ZoneId.of("America/New_York"));System.out.println("newZonedDateTime:"+ newZonedDateTime);

除此之外,調(diào)整日期時間還可以通過TemporalAdjusters,TemporalAdjuster 是一個函數(shù)式接口,用于根據(jù)給定的規(guī)則調(diào)整日期時間對象。Java8的 java.time.temporal 包中預(yù)定義了一系列常用的 TemporalAdjuster 實現(xiàn),例如獲取下一個工作日、月初、月末等。nGf28資訊網(wǎng)——每日最新資訊28at.com

LocalDate date = LocalDate.of(2024, 3, 11);// 下一個工作日LocalDate nextWorkingDay = date.with(TemporalAdjusters.next(DayOfWeek.MONDAY)); // 如果11號不是周一,則返回下一個周一的日期// 下一個月的第一天LocalDate firstDayNextMonth = date.with(TemporalAdjusters.firstDayOfMonth()); // 返回4月1日// 當(dāng)月的最后一個工作日LocalDate lastWorkingDay = date.with(TemporalAdjusters.lastInMonth(DayOfWeek.FRIDAY)); // 返回3月最后一個周五的日期// 自定義 TemporalAdjusterTemporalAdjuster adjuster = temporal -> {    return temporal.plusDays(10).with(TemporalAdjusters.lastDayOfMonth());};LocalDate tenthDayNextMonthEnd = date.with(adjuster); // 返回4月最后一個日期,前提是先加10天
日期時間的比較

在Java8及其以后版本的日期時間API中,isBefore() 和 isAfter() 方法是 java.time 包中的 LocalDate、LocalTime、LocalDateTime、ZonedDateTime 等日期時間類所共有的方法,用于比較兩個日期時間對象的先后順序。nGf28資訊網(wǎng)——每日最新資訊28at.com

isBefore():nGf28資訊網(wǎng)——每日最新資訊28at.com

  • 此方法用于判斷當(dāng)前對象是否早于另一個日期時間對象。
  • 如果當(dāng)前對象的時間點在參數(shù)對象之前,則返回 true;否則返回 false。
LocalDate date1 = LocalDate.of(2024, 3, 11);LocalDate date2 = LocalDate.of(2024, 3, 12);boolean isEarlier = date1.isBefore(date2); // 返回 true,因為 date1 在 date2 之前

isAfter():nGf28資訊網(wǎng)——每日最新資訊28at.com

  • 此方法用于判斷當(dāng)前對象是否晚于另一個日期時間對象。
  • 如果當(dāng)前對象的時間點在參數(shù)對象之后,則返回 true;否則返回 false。
LocalDateTime time1 = LocalDateTime.of(2024, 3, 11, 10, 0);LocalDateTime time2 = LocalDateTime.of(2024, 3, 11, 9, 0);boolean isLater = time1.isAfter(time2); // 返回 true,因為 time1 在 time2 之后

compareTo()在Java 8的 java.time 包中,大部分日期時間類如 LocalDate、LocalTime、LocalDateTime、ZonedDateTime 都實現(xiàn)了 Comparable 接口,從而可以直接使用 compareTo() 方法進行比較。compareTo() 方法用于比較兩個日期時間對象的先后順序,返回值含義如下:nGf28資訊網(wǎng)——每日最新資訊28at.com

  • 如果當(dāng)前對象早于(時間點在前)參數(shù)對象,返回負(fù)數(shù)。
  • 如果當(dāng)前對象等于參數(shù)對象,返回0。
  • 如果當(dāng)前對象晚于(時間點在后)參數(shù)對象,返回正數(shù)。
LocalDate date1 = LocalDate.of(2024, 3, 11);LocalDate date2 = LocalDate.of(2024, 3, 12);int comparisonResult = date1.compareTo(date2);if (comparisonResult < 0) {    System.out.println("date1 is before date2");} else if (comparisonResult > 0) {    System.out.println("date1 is after date2");} else {    System.out.println("date1 is equal to date2");}LocalDateTime dateTime1 = LocalDateTime.of(2024, 3, 11, 10, 30);LocalDateTime dateTime2 = LocalDateTime.of(2024, 3, 11, 11, 00);int timeComparisonResult = dateTime1.compareTo(dateTime2);
其他操作

在Java8的 java.time 包中,各個日期時間類如 LocalDate、LocalTime、LocalDateTime 提供了一系列 get 方法,用于獲取特定字段的值。nGf28資訊網(wǎng)——每日最新資訊28at.com

獲取日期中的特定字段:nGf28資訊網(wǎng)——每日最新資訊28at.com

LocalDate date = LocalDate.of(2024, 3, 11);int dayOfMonth = date.getDayOfMonth(); // 獲取當(dāng)月的第幾天,此處返回11int monthValue = date.getMonthValue(); // 獲取月份值,此處返回3Month month = date.getMonth(); // 獲取Month枚舉,此處返回Marchint year = date.getYear(); // 獲取年份,此處返回2024

對于時間部分,類似地可以獲取小時、分鐘、秒和納秒:nGf28資訊網(wǎng)——每日最新資訊28at.com

LocalTime time = LocalTime.of(19, 30, 45);int hour = time.getHour(); // 獲取小時數(shù),此處返回10int minute = time.getMinute(); // 獲取分鐘數(shù),此處返回30int second = time.getSecond(); // 獲取秒數(shù),此處返回45int nano = time.getNano(); // 獲取納秒數(shù)

在SpringBoot中使用

SpringBoot默認(rèn)集成了Jackson作為JSON處理庫,Jackson已經(jīng)能自動處理 LocalDate、LocalTime 和 LocalDateTime 類型。nGf28資訊網(wǎng)——每日最新資訊28at.com

如果需要使用自定義日期時間格式,我們有兩種方式:nGf28資訊網(wǎng)——每日最新資訊28at.com

手動更改全局配置: 如果需要自定義日期格式,可以通過 ObjectMapper 的配置類來注冊自定義的日期格式化器:nGf28資訊網(wǎng)——每日最新資訊28at.com

<dependency>    <groupId>org.springframework.boot</groupId>    <artifactId>spring-boot-starter-json</artifactId></dependency>
@Configurationpublic class JacksonConfig {    @Bean    public Jackson2ObjectMapperBuilderCustomizer jsonCustomizer() {        return builder -> {            builder.simpleDateFormat("yyyy-MM-dd");            // 使用Java 8時間API的日期格式器            builder.dateFormat(new StdDateFormat().withColonInTimeZone(true));            // 注冊LocalDateTime的序列化和反序列化模塊            builder.modules(new JavaTimeModule());        };    }}

手動綁定格式化配置SpringBoot支持自動綁定HTTP請求參數(shù)到控制器方法參數(shù)中,包括 LocalDate、LocalTime 和 LocalDateTime 類型。客戶端需發(fā)送符合日期格式的字符串,Spring Boot會自動轉(zhuǎn)換成相應(yīng)類型。nGf28資訊網(wǎng)——每日最新資訊28at.com

@PostMapping("/events")    public ResponseEntity<Event> createEvent(@RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate date,                                             @RequestParam @DateTimeFormat(pattern = "HH:mm:ss") LocalTime startTime,                                             @RequestParam @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss") LocalDateTime timestamp) {        // ...    }

或者請求或者響應(yīng)VO中:nGf28資訊網(wǎng)——每日最新資訊28at.com

public static class ResponseVO{        @DateTimeFormat(pattern = "yyyy-MM-dd")        private  LocalDate date;        @DateTimeFormat(pattern = "HH:mm:ss")         private LocalTime startTime;        @DateTimeFormat(pattern = "yyyy-MM-dd HH:mm:ss")        private  LocalDateTime timestamp;    }

Mybatis中使用

在MyBatis中查詢MySQL數(shù)據(jù)庫時,使用Java 8的 java.time.LocalDate、java.time.LocalTime 和 java.time.LocalDateTime類型。nGf28資訊網(wǎng)——每日最新資訊28at.com

  1. 數(shù)據(jù)庫表結(jié)構(gòu): 在MySQL數(shù)據(jù)庫中,通常需要使用適合的日期時間類型來存儲這些Java 8的日期時間對象。例如:

LocalDate 對應(yīng)MySQL的DATE類型。LocalTime 對應(yīng)MySQL 的 TIME 類型。LocalDateTime 對應(yīng)MySQL的 DATETIME或TIMESTAMP類型。nGf28資訊網(wǎng)——每日最新資訊28at.com

CREATE TABLE `test_date`(    `id` BIGINT ( 20 ) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '自增主鍵',    test_local_date DATE ,    test_local_time TIME,    test_local_date_time DATETIME,    PRIMARY KEY ( `id` ))ENGINE = INNODB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8mb4 COMMENT = '日期時間測試';
  1. 實體類映射: 在Java實體類中,對應(yīng)字段應(yīng)聲明為 LocalDate、LocalTime 或 LocalDateTime 類型。
@Datapublic class TestDate implements Serializable {    /**    * 自增主鍵    */    private Long id;    private LocalDate testLocalDate;    private LocalTime testLocalTime;    private LocalDateTime testLocalDateTime;    private static final long serialVersionUID = 1L;}

3.MyBatis配置:nGf28資訊網(wǎng)——每日最新資訊28at.com

  • 自動類型轉(zhuǎn)換:如果你使用的是較新的MyBatis版本(>=3.4.5),MyBatis已經(jīng)內(nèi)置了對Java 8日期時間類型的處理。這意味著在執(zhí)行SQL查詢時,MyBatis會自動將數(shù)據(jù)庫中的日期時間字段轉(zhuǎn)換為相應(yīng)的Java8類型。
@Testpublic void testInsertDate(){    TestDate testDate = new TestDate();    testDate.setTestLocalDate(LocalDate.of(2024, 3, 12));    testDate.setTestLocalTime(LocalTime.of(20,10,30));    testDate.setTestLocalDateTime(LocalDateTime.of(2024, 3, 12,20,10,30,0));    testDateMapper.insert(testDate);}@Testpublic void testQueryDate(){    TestDate testDate = testDateMapper.selectByPrimaryKey(1L);    System.out.println("testLocalDate:"+testDate.getTestLocalDate());    System.out.println("testLocalTime:"+testDate.getTestLocalTime());    System.out.println("testLocalDateTime:"+testDate.getTestLocalDateTime());}

image.pngnGf28資訊網(wǎng)——每日最新資訊28at.com

  • 自定義TypeHandler:如果MyBatis版本較低或者需要自定義日期時間格式,你可能需要自定義 TypeHandler 來處理 LocalDate、LocalTime 和 LocalDateTime 與數(shù)據(jù)庫字段間的轉(zhuǎn)換。關(guān)于Mybatis使用自定義TypeHandler,請移步:玩轉(zhuǎn)Mybatis:自定義TypeHandler,輕松應(yīng)對Mysql的JSON類型操作

結(jié)論

本文探討了Java 8引入的全新日期時間API相較于傳統(tǒng)的Date和Calendar類的優(yōu)勢及實際應(yīng)用。鑒于Java 8新日期時間API在設(shè)計上的先進性和易用性,強烈建議積極采納并替換掉陳舊的Date和Calendar類,轉(zhuǎn)而采用如LocalDate、LocalDateTime、ZonedDateTime等現(xiàn)代日期時間類。nGf28資訊網(wǎng)——每日最新資訊28at.com

Java 8新日期時間API提供了更為清晰、直觀的操作接口,支持不可變對象設(shè)計模式,增強了類型安全性,并具備豐富的日期時間運算、解析與格式化功能,顯著提高了代碼質(zhì)量與可讀性。此外,新API對日期時間單位的精確度控制、時區(qū)管理以及與其他日期時間規(guī)范的兼容性等方面均表現(xiàn)出卓越的表現(xiàn)力和靈活性,使得我們在處理各類復(fù)雜日期時間邏輯時能夠更加得心應(yīng)手,提升開發(fā)效率。nGf28資訊網(wǎng)——每日最新資訊28at.com

本文鏈接:http://www.www897cc.com/showinfo-26-76496-0.html還在用Calendar操作Date?Java8都被放棄了,你還不知道Java8中全新的日期時間API

聲明:本網(wǎng)頁內(nèi)容旨在傳播知識,若有侵權(quán)等問題請及時與本網(wǎng)聯(lián)系,我們將在第一時間刪除處理。郵件:2376512515@qq.com

上一篇: 想進阿里?先搞懂Spring Bean的循環(huán)依賴!

下一篇: 如何實現(xiàn)一個支持海量大并發(fā)的服務(wù)?

標(biāo)簽:
  • 熱門焦點
Top 主站蜘蛛池模板: 特克斯县| 阳东县| 榆林市| 武威市| 乡宁县| 河源市| 安化县| 天津市| 扶沟县| 清镇市| 龙口市| 长春市| 堆龙德庆县| 彰武县| 林芝县| 绥棱县| 景德镇市| 绥滨县| 通城县| 木里| 平阴县| 汶上县| 临潭县| 镇赉县| 龙岩市| 湘阴县| 罗江县| 兴海县| 怀柔区| 项城市| 新邵县| 盱眙县| 宁安市| 清水县| 琼海市| 应城市| 南康市| 宿迁市| 东方市| 收藏| 冷水江市|