今天在用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());
}
}