Java基礎類庫:Date、Calendar類
今天在用Java寫一道去年寒假用C語言刷過的一道特別簡單的水題的時候,用到了Java類庫的Date、Calendar類,不妨寫個總結以便下次複習~
題目是這樣的:
給定一個日期,輸出這個日期是該年的第幾天
Input
輸入資料有多組,每組佔一行,資料格式為YYYY/MM/DD組成
Output
對於每組輸入資料,輸出一行,表示該日期是該年的第幾天
Sample Input
1985/1/20
2006/3/12
Sample Output
20
71
這是當時用C語言寫的程式碼…雖然AC了但是這樣寫真的很麻煩= =
#include<stdio.h>
int main()
{
int year,mon,day,sum;
while(scanf("%d/%d/%d",&year,&mon,&day)!=EOF)
{
sum=0;
switch(mon)
{
case 1:sum=day;break;
case 2:sum=31+day;break;
case 3:sum=59+day;break;
case 4:sum=90+day;break;
case 5:sum=120+day;break;
case 6:sum=151+day;break;
case 7:sum=181+day;break;
case 8:sum=212+day;break;
case 9:sum=243+day;break;
case 10:sum=273+day;break;
case 11:sum=304+day;break;
case 12:sum=334+day;break;
}
if(((year%4==0&&year%100!=0)||year%400 ==0)&&mon>2)
printf("%d\n",sum+1);
else
printf("%d\n",sum);
}
return 0;
}
因為Java提供了Date、Calendar來處理日期、時間,所以就方便了很多:
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner scan = new Scanner(System.in);
while (scan.hasNext()) {
String date = scan.nextLine();
//建立date物件得到輸入的字串
SimpleDateFormat demo = new SimpleDateFormat("yyyy/MM/dd");
//建立demo物件,根據特定的日期格式在Date和字串之間轉換
Date inputDate = null;
//建立Date類的inputDate物件
try {
inputDate = demo.parse(date);
//parse方法用於將字串型別的日期時間解析為Date型別
//執行該方法需要處理異常
} catch (Exception e) {
e.printStackTrace();
}
Calendar cal = Calendar.getInstance();
//建立Calendar類的cal物件
cal.setTime(inputDate);
//因為Calendar沒有建構函式可以接收Date物件,必須先獲得一個Calendar例項再呼叫其setTime()方法
int whichday = cal.get(Calendar.DAY_OF_YEAR);
//返回當年的第幾天
System.out.println(whichday);
}
}
}
SimpleDateFormat
SimpleDateFormat根據特定的日期格式在Date和字串之間轉換
※常用方法:
String format(Date date):將日期按照指定格式轉換成字串
Date parse(String str):將字串按照指定格式轉換成Date
△繼承關係:
java.lang.Object
|
+----java.text.Format
|
+----java.text.DateFormat
|
+----java.text.SimpleDateFormat
○符號意義:
G 年代標誌符
y 年
M 月
d 日
h 時 在上午或下午 (1~12)
H 時 在一天中 (0~23)
m 分
s 秒
S 毫秒
E 星期
D 一年中的第幾天
F 一月中第幾個星期幾
w 一年中第幾個星期
W 一月中第幾個星期
a 上午 / 下午 標記符
k 時 在一天中 (1~24)
K 時 在上午或下午 (0~11)
z 時區
示例程式碼:
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatDemo {
public static void main(String[] args) {
SimpleDateFormat myFmt = new SimpleDateFormat("yyyy年MM月dd日 HH時mm分ss秒");
//2018年03月17日 21時19分33秒
SimpleDateFormat myFmt1 = new SimpleDateFormat("yy/MM/dd HH:mm");
//18/03/17 21:19
SimpleDateFormat myFmt2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
//2018-03-17 21:19:33
SimpleDateFormat myFmt3 = new SimpleDateFormat("yyyy年MM月dd日 HH時mm分ss秒 E");
//2018年03月17日 21時19分33秒 星期六
SimpleDateFormat myFmt4 = new SimpleDateFormat("一年中的第D天,一年中第w個星期,一月中第W個星期,在一天中k時z時區");
//一年中的第76天,一年中第11個星期,一月中第3個星期,在一天中21時CST時區
Date now= new Date();
System.out.println(myFmt.format(now));
System.out.println(myFmt1.format(now));
System.out.println(myFmt2.format(now));
System.out.println(myFmt3.format(now));
System.out.println(myFmt4.format(now));
System.out.println(now.toString());
//Sat Mar 17 21:19:33 CST 2018
}
}
接下來進入正題,說說Java中的Date、Calendar類~
Date類
Java提供了Date類來處理日期、時間(此處的Date是指java.util包下的Date類,而不是java.sql包下的Date類)。但因為其歷史悠久,所以大部分構造器、方法已經過時,不再推薦使用了,以下不再列出。
兩個構造器:
Date():生成一個代表當前時期時間的Date物件
Date(long date):根據指定的long型整數來生成一個Date物件
四個方法:
boolean after(Date when):判斷該日期是否在指定日期when後
boolean before(Date when):判斷該日期是否在指定日期when前
long getTime():返回該時間對應的long型整數
void setTime(long time):設定該Date物件的時間
示例程式碼:
import java.util.Date;
public class DateDemo {
public static void main(String[] args) {
Date date = new Date();
long now = date.getTime();
//getTime():返回的時間是距離1970年的毫秒數.值不受setTime()的影響
//date值受setTime()的影響
System.out.println(now);//1521292091214
System.out.println(date);//Sat Mar 17 21:08:11 CST 2018
long time = now + 1000*60*60*24;//時間設定為明日此時
date.setTime(time);
System.out.println(date.getTime());//1521378491214
System.out.println(now);//1521292091214
System.out.println(date);//Sun Mar 18 21:08:11 CST 2018
}
}
Calendar類
Calendar類能更好地處理日期和時間,主要用來對時間分量進行計算。Calendar類本身是一個抽象類,它是所有日曆類的模版,並提供了一些所有日曆通用的方法;但因為它本身不能直接例項化,只能通過它的靜態方法來獲取Calendar物件。
1)Calendar與Date的轉換:
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
//建立一個預設的Calendar物件,從Calendar物件中取出Date物件
Calendar cal2 = Calendar.getInstance();
cal2.setTime(date);
//通過Date物件獲得相應的Calendar物件
2)常用方法:
void add(int field, int amount):根據日曆的規則,為給定的日曆欄位新增或減去指定的時間量
int get(int field):返回指定日曆欄位的值
int getActualMaximum(int field):返回指定日曆欄位可能擁有的最大值
int getActualMinimum(int field):返回指定日曆欄位可能擁有的最小值
void roll(int field, int amount):與add類似,區別在於加上amount後超過了該欄位所能表示的最大範圍時,也不會向上一個欄位進位
void set(int field, int value):給指定的日曆欄位設定為給定值
void set(int year, int month, int date):設定年月日3個欄位的值
void set(int year, int month, int date, int hourOfDay, int minute, int second):設定年月日時分秒6個欄位的值
/*
* 和天相關的時間分量
* DATE,DAY_OF_MONTH:是一致的,表示月中的第幾天
* DAY_OF_YEAR:表示年中的天
* DAY_OF_WEEK:表示週中的天
* MONTH:是從0開始的!
* */
示例程式碼:
import java.util.Calendar;
public class CalendarDemo {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
System.out.println(cal.get(Calendar.YEAR)); //2018
System.out.println(cal.get(Calendar.MONTH)); //2
System.out.println(cal.get(Calendar.DATE)); //17
cal.set(2003, 10, 23, 12, 32, 23); //設定年月日時分秒
System.out.println(cal.getTime()); //Sun Nov 23 12:32:23 CST 2003
cal.add(Calendar.YEAR, -1); //向前推1年
System.out.println(cal.getTime()); //Sat Nov 23 12:32:23 CST 2002
cal.roll(Calendar.MONTH, 8); //向前推8個月
System.out.println(cal.getTime()); //Tue Jul 23 12:32:23 CST 2002
}
}
3)設定Calendar的容錯性
呼叫Calendar物件的set()方法來改變指定時間欄位的值,有可能傳入一個不合法的引數,例如,為MONTH欄位設定13,這會導致怎樣的後果呢?
import java.util.Calendar;
public class LenientTest {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.set(Calendar.MONTH, 13); //設定MONTH為13,結果為YEAR+1,MONTH為1
System.out.println(cal.getTime());
cal.setLenient(false); //關閉容錯性
cal.set(Calendar.MONTH, 13); //導致執行時異常
System.out.println(cal.getTime());
}
}
Calendar提供了一個setLenient()用於設定它的容錯性,Calendar預設支援較好的容錯性,通過setLenient(false)可以關閉Calendar的容錯性,讓它進行嚴格的引數檢查
Calendar有兩種解釋日曆欄位的模式:lenient和non-lenient。當Calendar處於lenient模式時,每個時間欄位可接受超出它允許範圍的值;反之,程式會拋異常。
4)set()方法延遲修改
set(f, value)方法將日曆欄位f更改為value,此外還設定了一個內部成員變數,以指示日曆欄位f已經被更改,儘管f是立即更改的,但是Calendar所代表的時間卻不會立即修改,直到下次呼叫get()、getTime()、getTimeInMillis()、add()或roll()時才會重新計算日曆的時間。這被稱為set()方法的延遲修改,採用延遲修改的優勢是多次呼叫set()不會觸發多次不必要的計算。
public class LazyTest {
public static void main(String[] args) {
Calendar cal = Calendar.getInstance();
cal.set(2003, 7, 31);
//將月份設為9,但9月31日不存在
//如果立即修改,系統將把cal自動調整到10月1日
cal.set(MONTH, 8);
//下面的程式碼輸出10月1日
//System.out.println(cal.getTime());
//設定Date欄位為5
cal.set(DATE, 5);
System.out.println(cal.getTime());
}
}