Java日期時間調(diào)整的幾種方式匯總
一、Calendar類
我們現(xiàn)在已經(jīng)能夠格式化并創(chuàng)建一個日期對象了,但是我們?nèi)绾尾拍茉O(shè)置和獲取日期數(shù)據(jù)的特定部分呢,比如說小時,日,或者分鐘? 我們又如何在日期的這些部分加上或者減去值呢? 答案是使用Calendar 類。
Calendar類的功能要比Date類強(qiáng)大很多,而且在實(shí)現(xiàn)方式上也比Date類要復(fù)雜一些。
Calendar類是一個抽象類,在實(shí)際使用時實(shí)現(xiàn)特定的子類的對象,創(chuàng)建對象的過程對程序員來說是透明的,只需要使用getInstance方法創(chuàng)建即可。
創(chuàng)建一個代表系統(tǒng)當(dāng)前日期的Calendar對象
Calendar c = Calendar.getInstance();//默認(rèn)是當(dāng)前日期
創(chuàng)建一個指定日期的Calendar對象
使用Calendar類代表特定的時間,需要首先創(chuàng)建一個Calendar的對象,然后再設(shè)定該對象中的年月日參數(shù)來完成。
//創(chuàng)建一個代表2009年6月12日的Calendar對象 Calendar c1 = Calendar.getInstance(); c1.set(2009, 6 - 1, 12)
Calendar類對象字段類型
Calendar類中用一下這些常量表示不同的意義,jdk內(nèi)的很多類其實(shí)都是采用的這種思想
常量 | 描述 |
---|---|
Calendar.YEAR | 年份 |
Calendar.MONTH | 月份 |
Calendar.DATE | 日期 |
Calendar.DAY_OF_MONTH | 日期,和上面的字段意義完全相同 |
Calendar.HOUR | 12小時制的小時 |
Calendar.HOUR_OF_DAY | 24小時制的小時 |
Calendar.MINUTE | 分鐘 |
Calendar.SECOND | 秒 |
Calendar.DAY_OF_WEEK | 星期幾 |
Calendar類對象信息的設(shè)置
Set設(shè)置
如:
Calendar c1 = Calendar.getInstance();
調(diào)用:
public final void set(int year,int month,int date)
c1.set(2009, 6 - 1, 12);//把Calendar對象c1的年月日分別設(shè)這為:2009、5、12
利用字段類型設(shè)置
如果只設(shè)定某個字段,例如日期的值,則可以使用如下set方法:
public void set(int field,int value)
把 c1對象代表的日期設(shè)置為10號,其它所有的數(shù)值會被重新計(jì)算
c1.set(Calendar.DATE,10);
把c1對象代表的年份設(shè)置為2008年,其他的所有數(shù)值會被重新計(jì)算
c1.set(Calendar.YEAR,2008);
其他字段屬性set的意義以此類推
Add設(shè)置
Calendar c1 = Calendar.getInstance();
把c1對象的日期加上10,也就是c1所表的日期的10天后的日期,其它所有的數(shù)值會被重新計(jì)算
c1.add(Calendar.DATE, 10);
把c1對象的日期減去10,也就是c1所表的日期的10天前的日期,其它所有的數(shù)值會被重新計(jì)算
c1.add(Calendar.DATE, -10);
其他字段屬性的add的意義以此類推
Calendar類對象信息的獲得
Calendar c1 = Calendar.getInstance(); // 獲得年份 int year = c1.get(Calendar.YEAR); // 獲得月份 int month = c1.get(Calendar.MONTH) + 1; // 獲得日期 int date = c1.get(Calendar.DATE); // 獲得小時 int hour = c1.get(Calendar.HOUR_OF_DAY); // 獲得分鐘 int minute = c1.get(Calendar.MINUTE); // 獲得秒 int second = c1.get(Calendar.SECOND); // 獲得星期幾(注意(這個與Date類是不同的):1代表星期日、2代表星期1、3代表星期二,以此類推) int day = c1.get(Calendar.DAY_OF_WEEK);
GregorianCalendar類
Calendar類實(shí)現(xiàn)了公歷日歷,GregorianCalendar是Calendar類的一個具體實(shí)現(xiàn)。
Calendar 的getInstance()方法返回一個默認(rèn)用當(dāng)前的語言環(huán)境和時區(qū)初始化的GregorianCalendar對象。GregorianCalendar定義了兩個字段:AD和BC。這些代表公歷定義的兩個時代。
下面列出GregorianCalendar對象的幾個構(gòu)造方法:
序號 | 構(gòu)造函數(shù)和說明 |
1 | GregorianCalendar() 在具有默認(rèn)語言環(huán)境的默認(rèn)時區(qū)內(nèi)使用當(dāng)前時間構(gòu)造一個默認(rèn)的 GregorianCalendar。 |
2 | GregorianCalendar(int year, int month, int date) 在具有默認(rèn)語言環(huán)境的默認(rèn)時區(qū)內(nèi)構(gòu)造一個帶有給定日期設(shè)置的 GregorianCalendar |
3 | GregorianCalendar(int year, int month, int date, int hour, int minute) 為具有默認(rèn)語言環(huán)境的默認(rèn)時區(qū)構(gòu)造一個具有給定日期和時間設(shè)置的 GregorianCalendar。 |
4 | GregorianCalendar(int year, int month, int date, int hour, int minute, int second) 為具有默認(rèn)語言環(huán)境的默認(rèn)時區(qū)構(gòu)造一個具有給定日期和時間設(shè)置的 GregorianCalendar。 |
5 | GregorianCalendar(Locale aLocale) 在具有給定語言環(huán)境的默認(rèn)時區(qū)內(nèi)構(gòu)造一個基于當(dāng)前時間的 GregorianCalendar。 |
6 | GregorianCalendar(TimeZone zone) 在具有默認(rèn)語言環(huán)境的給定時區(qū)內(nèi)構(gòu)造一個基于當(dāng)前時間的 GregorianCalendar。 |
7 | GregorianCalendar(TimeZone zone, Locale aLocale) 在具有給定語言環(huán)境的給定時區(qū)內(nèi)構(gòu)造一個基于當(dāng)前時間的 GregorianCalendar。 |
這里是GregorianCalendar 類提供的一些有用的方法列表:
序號 | 方法和說明 |
1 | void add(int field, int amount) 根據(jù)日歷規(guī)則,將指定的(有符號的)時間量添加到給定的日歷字段中。 |
2 | protected void computeFields() 轉(zhuǎn)換UTC毫秒值為時間域值 |
3 | protected void computeTime() 覆蓋Calendar ,轉(zhuǎn)換時間域值為UTC毫秒值 |
4 | boolean equals(Object obj) 比較此 GregorianCalendar 與指定的 Object。 |
5 | int get(int field) 獲取指定字段的時間值 |
6 | int getActualMaximum(int field) 返回當(dāng)前日期,給定字段的最大值 |
7 | int getActualMinimum(int field) 返回當(dāng)前日期,給定字段的最小值 |
8 | int getGreatestMinimum(int field) 返回此 GregorianCalendar 實(shí)例給定日歷字段的最高的最小值。 |
9 | Date getGregorianChange() 獲得格里高利歷的更改日期。 |
10 | int getLeastMaximum(int field) 返回此 GregorianCalendar 實(shí)例給定日歷字段的最低的最大值 |
11 | int getMaximum(int field) 返回此 GregorianCalendar 實(shí)例的給定日歷字段的最大值。 |
12 | Date getTime() 獲取日歷當(dāng)前時間。 |
13 | long getTimeInMillis() 獲取用長整型表示的日歷的當(dāng)前時間 |
14 | TimeZone getTimeZone() 獲取時區(qū)。 |
15 | int getMinimum(int field) 返回給定字段的最小值。 |
16 | int hashCode() 重寫hashCode. |
17 | boolean isLeapYear(int year) 確定給定的年份是否為閏年。 |
18 | void roll(int field, boolean up) 在給定的時間字段上添加或減去(上/下)單個時間單元,不更改更大的字段。 |
19 | void set(int field, int value) 用給定的值設(shè)置時間字段。 |
20 | void set(int year, int month, int date) 設(shè)置年、月、日的值。 |
21 | void set(int year, int month, int date, int hour, int minute) 設(shè)置年、月、日、小時、分鐘的值。 |
22 | void set(int year, int month, int date, int hour, int minute, int second) 設(shè)置年、月、日、小時、分鐘、秒的值。 |
23 | void setGregorianChange(Date date) 設(shè)置 GregorianCalendar 的更改日期。 |
24 | void setTime(Date date) 用給定的日期設(shè)置Calendar的當(dāng)前時間。 |
25 | void setTimeInMillis(long millis) 用給定的long型毫秒數(shù)設(shè)置Calendar的當(dāng)前時間。 |
26 | void setTimeZone(TimeZone value) 用給定時區(qū)值設(shè)置當(dāng)前時區(qū)。 |
27 | String toString() 返回代表日歷的字符串。 |
實(shí)例
import java.util.*; public class GregorianCalendarDemo { public static void main(String args[]) { String months[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"}; int year; // 初始化 Gregorian 日歷 // 使用當(dāng)前時間和日期 // 默認(rèn)為本地時間和時區(qū) GregorianCalendar gcalendar = new GregorianCalendar(); // 顯示當(dāng)前時間和日期的信息 System.out.print("Date: "); System.out.print(months[gcalendar.get(Calendar.MONTH)]); System.out.print(" " + gcalendar.get(Calendar.DATE) + " "); System.out.println(year = gcalendar.get(Calendar.YEAR)); System.out.print("Time: "); System.out.print(gcalendar.get(Calendar.HOUR) + ":"); System.out.print(gcalendar.get(Calendar.MINUTE) + ":"); System.out.println(gcalendar.get(Calendar.SECOND)); // 測試當(dāng)前年份是否為閏年 if(gcalendar.isLeapYear(year)) { System.out.println("當(dāng)前年份是閏年"); } else { System.out.println("當(dāng)前年份不是閏年"); } } }
以上實(shí)例編譯運(yùn)行結(jié)果如下:
Date: Apr 22 2009
Time: 11:25:27
當(dāng)前年份不是閏年
二、周期方法
周期是以年,月和日為單位的時間跨度。
支持負(fù)周期。
持續(xù)時間也是以秒和納秒為單位測量的時間跨度。
持續(xù)時間表示機(jī)器的精確納秒數(shù)。一個時期更適合人類。
1天,2個月,3天,4個月和5天都是周期的實(shí)例。2個月期間可能意味著不同的天數(shù),具體取決于不同的月份。
我們可以使用以下方法創(chuàng)建 Period
。
static Period of(int years,int months, int days) static Period ofDays(int days) static Period ofMonths(int months) static Period ofWeeks(int weeks) static Period ofYears(int years)
以下代碼顯示了如何創(chuàng)建Period。
import java.time.Period; public class Main { public static void main(String[] args) { Period p1 = Period.of(2, 3, 5); // 2 years, 3 months, and 5 days Period p2 = Period.ofDays(2); // 2 days Period p3 = Period.ofMonths(-3); // -3 months Period p4 = Period.ofWeeks(3); // 3 weeks System.out.println(p1); System.out.println(p2); System.out.println(p3); System.out.println(p4); } }
上面的代碼生成以下結(jié)果。
例2
Period支持加法,減法,乘法和求反運(yùn)算。
除法運(yùn)算執(zhí)行整數(shù)除法,例如,除以3除以7為2。
以下代碼顯示如何使用周期上的操作。
import java.time.Period; public class Main { public static void main(String[] args) { Period p1 = Period.ofDays(15); System.out.println(p1); Period p2 = p1.plusDays(12); System.out.println(p2); Period p3 = p1.minusDays(12); System.out.println(p3); Period p4 = p1.negated(); System.out.println(p4); Period p5 = p1.multipliedBy(3); System.out.println(p5); } }
上面的代碼生成以下結(jié)果。
例3
Period plus()
向另一個周期添加一個周期。
Period minus()
從另一個周期中減去一個周期。
周期normalized()方法標(biāo)準(zhǔn)化年和月。該方法確保月份值保持在0到11之間。“2年零16個月"被標(biāo)準(zhǔn)化為“3年零4個月"。
import java.time.Period; public class Main { public static void main(String[] args) { Period p1 = Period.of(2, 3, 5); Period p2 = Period.of(1, 15, 28); System.out.println(p1); System.out.println(p2); System.out.println(p1.minus(p2)); System.out.println(p1.plus(p2)); System.out.println(p1.plus(p2).normalized()); } }
上面的代碼生成以下結(jié)果。
Period Between
Date-Time API提供了計(jì)算兩個日期和時間之間的已用時間的方法。
我們可以在ChronoUnit枚舉中的一個常量上使用 between()
方法。
ChronoUnit枚舉between()方法需要兩個datetime對象并返回一個long。 如果第二個參數(shù)出現(xiàn)在第一個參數(shù)之前,它返回一個負(fù)數(shù)。
返回金額是兩個日期和時間之間的完整單位數(shù)。 例如,在06:00和09:30之間調(diào)用HOURS.between(),返回值為3,而不是3.5。 而MINUTES.在06:00至09:30之間返回210。
import java.time.LocalDate; import java.time.LocalTime; import java.time.Month; import java.time.temporal.ChronoUnit; public class Main { public static void main(String[] args) { LocalDate ld1 = LocalDate.of(2014, Month.JANUARY, 7); LocalDate ld2 = LocalDate.of(2014, Month.MAY, 21); long days = ChronoUnit.DAYS.between(ld1, ld2); System.out.println(days); LocalTime lt1 = LocalTime.of(6, 0); LocalTime lt2 = LocalTime.of(9, 30); long hours = ChronoUnit.HOURS.between(lt1, lt2); System.out.println(hours); long minutes = ChronoUnit.MINUTES.between(lt1, lt2); System.out.println(minutes); } }
上面的代碼生成以下結(jié)果。
Period Util
Date-Time API提供了計(jì)算兩個日期和時間之間的已用時間的方法。
我們可以對一個日期時間相關(guān)類使用 until(end_date_or_time,time_unit)
方法,例如LocalDate,LocalTime,LocalDateTime,ZonedDateTime等。
import java.time.LocalDate; import java.time.LocalTime; import java.time.Month; import java.time.temporal.ChronoUnit; public class Main { public static void main(String[] args) { LocalDate ld1 = LocalDate.of(2014, Month.JANUARY, 7); LocalDate ld2 = LocalDate.of(2014, Month.MAY, 18); LocalTime lt1 = LocalTime.of(7, 0); LocalTime lt2 = LocalTime.of(9, 30); long days = ld1.until(ld2, ChronoUnit.DAYS); System.out.println(days); long hours = lt1.until(lt2, ChronoUnit.HOURS); System.out.println(hours); long minutes = lt1.until(lt2, ChronoUnit.MINUTES); System.out.println(minutes); } }
上面的代碼生成以下結(jié)果。
三、Java 日期時間調(diào)整器
我們可能要將日期和時間調(diào)整為該月的第一個星期一或下一個星期二。
我們可以使用 TemporalAdjuster
界面來調(diào)整日期和時間。接口有一個方法, adjustInto()
,它接受一個時間并返回一個時間。
TemporalAdjusters
類包含返回不同類型的預(yù)定義日期調(diào)整器的靜態(tài)方法。
以下代碼顯示了如何計(jì)算2014年1月1日之后的第一個星期一:
import java.time.DayOfWeek; import java.time.LocalDate; import java.time.Month; import java.time.temporal.TemporalAdjusters; public class Main { public static void main(String[] args) { LocalDate ld1 = LocalDate.of(2014, Month.JANUARY, 1); LocalDate ld2 = ld1.with(TemporalAdjusters.next(DayOfWeek.MONDAY)); System.out.println(ld1); System.out.println(ld2); } }
上面的代碼生成以下結(jié)果。
TemporalAdjusters
TemporalAdjusters定義了一些可用于調(diào)整日期的有用方法。
- next(DayOfWeek dayOfWeek)
- nextOrSame(DayOfWeek dayOfWeek)
- previous(DayOfWeek dayOfWeek)
- previousOrSame(DayOfWeek dayOfWeek)
- firstInMonth(DayOfWeek dayOfWeek)
- lastInMonth(DayOfWeek dayOfWeek)
- dayOfWeekInMonth(int ordinal, DayOfWeek dayOfWeek)
- firstDayOfMonth()
- lastDayOfMonth()
- firstDayOfYear()
- lastDayOfYear()
- firstDayOfNextMonth()
- firstDayOfNextYear()
- ofDateAdjuster(UnaryOperator<LocalDate> dateBasedAdjuster)
以下代碼顯示了如何使用 dayOfWeekInMonth
。
import java.time.DayOfWeek; import java.time.LocalDate; import java.time.Month; import java.time.temporal.TemporalAdjusters; public class Main { public static void main(String[] args) { LocalDate ld1 = LocalDate.of(2014, Month.MAY, 21); System.out.println(ld1); LocalDate ld2 = ld1.with(TemporalAdjusters.dayOfWeekInMonth(5, DayOfWeek.SUNDAY)); System.out.println(ld2); } }
上面的代碼生成以下結(jié)果。
自定義調(diào)整
您可以使用ofDateAdjuster()方法為LocalDate創(chuàng)建自己的日期調(diào)整器。
以下代碼創(chuàng)建日期調(diào)整程序。
import java.time.LocalDate; import java.time.temporal.TemporalAdjuster; import java.time.temporal.TemporalAdjusters; public class Main { public static void main(String[] args) { // Create an adjuster that retruns a date after 3 months and 2 days TemporalAdjuster adjuster = TemporalAdjusters .ofDateAdjuster((LocalDate date) -> date.plusMonths(3).plusDays(2)); LocalDate today = LocalDate.now(); LocalDate dayAfter3Mon2Day = today.with(adjuster); System.out.println("Today: " + today); System.out.println("After 3 months and 2 days: " + dayAfter3Mon2Day); } }
上面的代碼生成以下結(jié)果:
到此這篇關(guān)于Java日期時間調(diào)整的幾種方式的文章就介紹到這了,更多相關(guān)Java日期時間調(diào)整內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java從JDK源碼角度對Object進(jìn)行實(shí)例分析
這篇文章主要介紹了Java從JDK源碼角度對Object進(jìn)行實(shí)例分析,具有一定借鑒價值,需要的朋友可以參考下。2017-12-12Java 文件傳輸助手的實(shí)現(xiàn)(單機(jī)版)
這篇文章主要介紹了Java 文件傳輸助手的實(shí)現(xiàn)(單機(jī)版),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05springboot-mongodb的多數(shù)據(jù)源配置的方法步驟
這篇文章主要介紹了springboot-mongodb的多數(shù)據(jù)源配置的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04Java?Unsafe創(chuàng)建對象的方法實(shí)現(xiàn)
Java中使用Unsafe實(shí)例化對象是一項(xiàng)十分有趣而且強(qiáng)大的功能,本文主要介紹了Java?Unsafe創(chuàng)建對象的方法實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07詳解Java中的線程讓步y(tǒng)ield()與線程休眠sleep()方法
Java中的線程讓步會讓線程讓出優(yōu)先級,而休眠則會讓線程進(jìn)入阻塞狀態(tài)等待被喚醒,這里我們對比線程等待的wait()方法,來詳解Java中的線程讓步y(tǒng)ield()與線程休眠sleep()方法2016-07-07idea2019.1.4 鼠標(biāo)放到方法上顯示注解的實(shí)現(xiàn)操作
這篇文章主要介紹了idea2019.1.4 鼠標(biāo)放到方法上顯示注解的實(shí)現(xiàn)操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-02-02