1. 程式人生 > >Java基礎類庫:Date、Calendar類

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());
    }
}