学习Java中的日期和时间处理及Java日历小程序的编写
这篇文章主要介绍了学习Java中的日期和时间处理及Java日历小程序的编写,这个日历小程序仅用简单的算法实现没有用到date类等,但是带有图形界面,需要的朋友可以参考下
Java在java.util包中提供了Date类,这个类封装了当前的日期和时间。
Date类支持两种构造函数。第一个构造函数初始化对象的当前日期和时间。
Date()
下面的构造函数接收一个参数等于自1970年1月1日午夜起已经过的毫秒数
1
Date(longmillisec)
一旦有一个可用的日期对象,可以调用以下任何一种支持的方法使用时间:
SN
方法和描述
1
booleanafter(Datedate)
如果调用Date对象包含或晚于指定的日期则返回true,否则,返回false。
2
booleanbefore(Datedate)
如果调用Date对象包含或早于日期指定的日期返回true,否则,返回false。
3
Objectclone()
重复调用Date对象。
4
intcompareTo(Datedate)
调用对象的值与日期比较。如果这两个值相等返回0。如果调用对象是早于日期返回一个负值。如果调用对象迟于日期返回正值。
5
intcompareTo(Objectobj)
以相同的compareTo(Date)操作如果obj是一个类日期。否则,它会抛出一个ClassCastException。
6
booleanequals(Objectdate)
如果调用Date对象包含相同的时间及日期指定日期则返回true,否则,返回false。
7
longgetTime()
返回自1970年1月1日起已经过的毫秒数。
8
inthashCode()
返回调用对象的哈希代码。
9
voidsetTime(longtime)
设置所指定的时间,这表示从1970年1月1日从午夜的时间和日期以毫秒为单位经过的时间。
10
StringtoString()
调用Date对象转换为字符串,并返回结果。
获取当前日期和时间
在Java中容易得到当前的日期和时间。可以使用一个简单的Date对象的toString()方法,如下所示打印当前日期和时间:
1234567891011
importjava.util.Date;publicclassDateDemo{publicstaticvoidmain(Stringargs[]){//InstantiateaDateobjectDatedate=newDate();//displaytimeanddateusingtoString()System.out.println(date.toString());}}
这将产生以下结果:
1
MonMay0409:51:52CDT2009
日期比较
有以下三种方式来比较两个日期:
1.可以使用getTime()来获得自1970年1月1日午夜十二时起已经过的毫秒数,然后比较两个对象的值。
2.可以使用before(),after(),和equals()方法,由于12日在18日前,例如,newDate(99,2,12).before(newDate(99,2,18))返回值为true。
3.可以使用compareTo()方法,这是由Comparable接口定义,由Date实现。
使用SimpleDateFormat格式化日期
SimpleDateFormat是一个具体的类,以本地方式用于格式化和转换日期。SimpleDateFormat允许选择用户定义的模式为日期时间格式。例如:
12345678910111213
importjava.util.;importjava.text.;publicclassDateDemo{publicstaticvoidmain(Stringargs[]){DatedNow=newDate();SimpleDateFormatft=newSimpleDateFormat("Eyyyy.MM.dd''at''hh:mm:ssazzz");System.out.println("CurrentDate:"+ft.format(dNow));}}
这将产生以下结果:
1
CurrentDate:Sun2004.07.18at04:14:09PMPDT
简单的DateFormat格式代码
要指定时间格式,使用时间模式字符串。在这个模式中,所有的ASCII字母被保留为模式字母,其定义如下:
字符
描述
例子
G
时代指示器
AD
y
四位数年份
2001
M
年中的月份
Julyor07
d
月份中日期
10
h
时间A.M./P.M.(1~12)
12
H
天中的小时(0~23)
22
m
小时中的分钟
30
s
分钟中的秒钟
55
S
毫秒
234
E
星期中的天
Tuesday
D
年中的天
360
F
月中星期中的天
2(secondWed.inJuly)
w
年中的星期
40
W
月中的星期
1
a
A.M./P.M.标记
PM
k
天中的小时(1~24)
24
K
小时A.M./P.M.(0~11)
10
z
时区
东部标准时间
''
脱离文本
分隔符
"
单引号
`
用printf格式化日期
日期和时间格式用printf方法可以非常轻松地做到。可以使用两个字母的格式,从t开始并在下面给出的表格中的其中一个字母结束。例如:
1234567891011121314
importjava.util.Date;publicclassDateDemo{publicstaticvoidmain(Stringargs[]){//InstantiateaDateobjectDatedate=newDate();//displaytimeanddateusingtoString()Stringstr=String.format("CurrentDate/Time:%tc",date);System.out.printf(str);}}
这将产生以下结果:
1
CurrentDate/Time:SatDec1516:37:57MST2012
如果提供日期多次格式化是一种不好的做法。一个格式字符串可以指示要格式化的参数的索引。
索引必须紧跟在%之后,并必须由$终止。例如:
12345678910111213
importjava.util.Date;publicclassDateDemo{publicstaticvoidmain(Stringargs[]){//InstantiateaDateobjectDatedate=newDate();//displaytimeanddateusingtoString()System.out.printf("%1$s%2$tB%2$td,%2$tY","Duedate:",date);}}
这将产生以下结果:
1
Duedate:February09,2004
或者,也可以使用<标志。则表示相同的参数,根据前述格式规范,应再次使用。例如:
12345678910111213
importjava.util.Date;publicwww.hunanwang.netclassDateDemo{publicstaticvoidmain(Stringargs[]){//InstantiateaDateobjectDatedate=newDate();//displayformatteddateSystem.out.printf("%s%tB%
这将产生以下结果:
1
Duedate:February09,2004
日期和时间转换字符
字符
描述
例子
c
完整的日期和时间
MonMay0409:51:52CDT2009
F
ISO8601日期
2004-02-09
D
U.S.格式时间(月/日/年)
02/09/2004
T
24-时制
18:05:19
r
12-时制
06:05:19pm
R
24-时制,无秒
18:05
Y
四位数年份(用前行零列)
2004
y
年份的后两位数(用前行零列)
04
C
年份的前两位(用前行零列)
20
B
完整月份名称
February
b
缩写月份名称
Feb
m
两位数月份(用前行零列)
02
d
两位数日期(用前行零列)
03
e
两位数日期(无前行零列)
9
A
完整星期名称
Monday
a
缩写星期名称
Mon
j
年中的三位数天数(用前行零列)
069
H
两位数小时(用前行零列),00和23之间
18
k
两位数小时(无前行零列),0和23之间
18
I
两位数小时(用前行零列),01和12之间
06
l
两位数小时(无前行零列),1和12之间
6
M
两位数分钟(用前行零列)
05
S
两位数秒钟(用前行零列)
19
L
三位数毫秒(用前行零列)
047
N
九位数纳秒(用前行零列)
047000000
P
大写上下午标记
PM
p
小写上下午标记
pm
z
RFC822从GMT数字抵消
-0800
Z
时区
PST
s
从1970-01-0100:00:00的秒数GMT
1078884319
Q
从1970-01-0100:00:00的毫秒数GMT
1078884319047
有相关的日期和时间等有用的类。欲了解更多详细信息,可以参考Java标准文档。
字符串转换日期
SimpleDateFormat类有一些额外的方法,如parse(),它试图根据存储在给定SimpleDateFormat的对象的格式来转换字符串。例如:
12345678910111213141516171819202122
importjava.util.;importjava.text.;publicclassDateDemo{publicstaticvoidmain(Stringargs[]){SimpleDateFormatft=newSimpleDateFormat("yyyy-MM-dd");Stringinput=args.length==0?"1818-11-11":args[0];System.out.print(input+"Parsesas");Datet;try{t=ft.parse(input);System.out.println(t);}catch(ParseExceptione){System.out.println("Unparseableusing"+ft);}}}
上述程序的运行示例将产生以下结果:
1234
$javaDateDemo1818-11-11ParsesasWedNov1100:00:00GMT1818$javaDateDemo2007-12-012007-12-01ParsesasSatDec0100:00:00GMT2007
休眠一段时间
你可以进行任何期间的时间休眠,从一毫秒直到你的电脑的整个生命周期。例如,下面的程序会休眠10秒:
12345678910111213
importjava.util.;publicclassSleepDemo{publicstaticvoidwww.visa158.commain(Stringargs[]){try{System.out.println(newDate()+"\n");Thread.sleep(56010);System.out.println(newDate()+"\n");}catch(Exceptione){System.out.println("Gotanexception!");}}}
这将产生以下结果:
123
SunMay0318:04:41GMT2009SunMay0318:04:51GMT2009
测量执行时间
有时候,可能需要测量的时间点以毫秒为单位。因此,让我们再一次重新写上面的例子:
123456789101112131415161718
importjava.util.;publicclassDiffDemo{publicstaticvoidmain(Stringargs[]){try{longstart=System.currentTimeMillis();System.out.println(newDate()+"\n");Thread.sleep(56010);System.out.println(newDate()+"\n");longend=System.currentTimeMillis();longdiff=end-start;System.out.println("Differenceis:"+diff);}catch(Exceptione){System.out.println("Gotanexception!");}}}
这将产生以下结果:
SunMay0318:16:51GMT2009SunMay0318:16:57GMT2009Differenceis:5993
GregorianCalendar类
GregorianCalendar是一个Calendar类具体的实现,即你所熟悉的对正常Gregorian公历的实现。本教程中不讨论Calendar类,可以看看标准Java文档。
Calendar的getInstance()方法返回与当前日期和时间默认语言环境和时区初始化的一个GregorianCalendar。GregorianCalendar中定义了两个字段:AD和BC。这些代表在公历中定义的两个时代。
也有几个构造函数的GregorianCalendar对象:
SN
构造函数描述
1
GregorianCalendar()
在默认时区与默认语言环境使用当前时间构造默认的GregorianCalendar。
2
GregorianCalendar(intyear,intmonth,intdate)
在默认时区设置默认的语言环境用给定的日期构造一个GregorianCalendar
3
GregorianCalendar(intyear,intmonth,intdate,inthour,intminute)
用给定的日期和时间设置为与默认语言环境的默认时区构造一个GregorianCalendar。
4
GregorianCalendar(intyear,intmonth,intdate,inthour,intminute,intsecond)
用给定的日期和时间设置为与默认语言环境的默认时区构造一个GregorianCalendar
5
GregorianCalendar(LocaleaLocale)
基于当前时间与给定语言环境的默认时区构建一个GregorianCalendar。
6
GregorianCalendar(TimeZonezone)
基于当前时间,使用默认的语言环境在给定的时区构建一个GregorianCalendar。
7
GregorianCalendar(TimeZonezone,LocaleaLocale)
基于当前时间与给定语言环境的给定时区构建一个GregorianCalendar。
这里是由GregorianCalendar类提供的一些有用的方法的列表:
SN
方法和描述
1
voidadd(intfield,intamount)
基于日历的规则,以给定的时间字段添加指定(有符号的)时间量。
2
protectedvoidcomputeFields()
将UTC转换为毫秒时间字段值.
3
protectedvoidcomputeTime()
覆盖日历转换时间域值为UTC的毫秒.
4
booleanequals(Objectobj)
这个GregorianCalendar与一个对象引用比较.
5
intget(intfield)
获取给定时间域的值.
6
intgetActualMaximum(intfield)
返回该字段可能的最大值,给定到当前的日期.
7
intgetActualMinimum(intfield)
返回该字段可能具有的最小值,给定当前的日期.
8
intgetGreatestMinimum(intfield)
对于给定的字段中返回高最低值(如果有变化).
9
DategetGregorianChange()
获取公历更改日期.
10
intgetLeastMaximum(intfield)
对于给定的字段返回最低的最大值,如果有变化.
11
intgetMaximum(intfield)
返回给定字段中的最大值.
12
DategetTime()
获取日历的当前时间.
13
longgetTimeInMillis()
获取日历的当前时间长.
14
TimeZonegetTimeZone()
获取时区.
15
intgetMinimum(intfield)
返回给定字段中的最小值.
16
inthashCode()
重写hashCode.
17
booleanisLeapYear(intyear)
确定给定年份是闰年.
18
voidroll(intfield,booleanup)
加上或减去(上/下)的时间在给定的时间字段一个单元,不更改更大的字段.
19
voidset(intfield,intvalue)
设置时间字段与给定值.
20
voidset(intyear,intmonth,intdate)
设置为年,月,日的值.
21
voidset(intyear,intmonth,intdate,inthour,intminute)
设置为年,月,日,小时和分钟值.
22
voidset(intyear,intmonth,intdate,inthour,intminute,intsecond)
设置为字段的年,月,日,小时,分钟和秒的值.
23
voidsetGregorianChange(Datedate)
设置GregorianCalendar更改日期.
24
voidsetTime(Datedate)
设置日历的当前时间与给定日期.
25
voidsetTimeInMillis(longmillis)
从给定long值设置日历的当前时间.
26
voidsetTimeZone(TimeZonevalue)
将时区设置与给定的时区值.
27
StringtoString()
返回此日历的字符串表示形式.
示例
importjava.util.;publicclassGregorianCalendarDemo{publicstaticvoidmain(Stringargs[]){Stringmonths[]={"Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"};intyear;//CreateaGregoriancalendarinitialized//withthecurrentdateandtimeinthe//defaultlocaleandtimezone.GregorianCalendargcalendar=newGregorianCalendar();//Displaycurrenttimeanddateinformation.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));//Testifthecurrentyearisaleapyearif(gcalendar.isLeapYear(year)){System.out.println("Thecurrentyearisaleapyear");}else{System.out.println("Thecurrentyearisnotaleapyear");}}}
这将产生以下结果:
123
Date:Apr222009Time:11:25:27Thecurrentyearisnotaleapyear
日历小程序
下面我们来看一个日历小程序。这里用传统的MVC结构,设计3个类:CalendarViewer、CalendarControlller、CalendarModel。
CalendarViewer.java主要处理UI,沿用了已有代码,整理之并抽出业务逻辑,使其专注于显示层处理。
CalendarViewer.java
publicclassCalendarViewerextendsJWindowimplementsActionListener{JPanelcalendarYmPanel=null;JButtonleftButton=newJButton("<<");JButtonrightButton=newJButton(">>");LabelyearLabel=newLabel();LabelmonthLabel=newLabel();LabelpassedDaysLabel=newLabel();JPanelcalendarWdPanel=null;//是caledar_week和calendar_days的总包容体JPanelcalendarWeekPanel=null;//针对周列的布局JPanelcalendarDaysPanel=null;//针对日期列的布局JPanelcalendarExitPanel=null;JButtonquitButton=newJButton("关闭");BorderemptyBorder=BorderFactory.createEmptyBorder();CalendarControllercController=newCalendarController();publicCalendarViewer(){super();buildUI();}publicvoidbuildUI(){buildTopPanel();buildCenterPanel();buildBottomPanel();setLayout(newBorderLayout());。。。。。。}privatevoidbuildTopPanel(){。。。。。。}privatevoidbuildCenterPanel(){。。。。。。}privatevoidbuildBottomPanel(){。。。。。。}publicJPanelupdateDaysPanel(){。。。。。。}publicvoidupdatePassedDaysLabel(){。。。。。。}publicvoidactionPerformed(ActionEvente){。。。。。。}publicstaticvoidmain(String[]args){SwingUtilities.invokeLater(newRunnable(){publicvoidrun(){newCalendarViewer();}});}}
UI构造主要分3块,对应图上中下3个panel。
1.buildTopPanel();
2.buildCenterPanel();
3.buildBottomPanel();
事件监听的处理由下面方法完成。
1.actionPerformed(ActionEvente);
基于事件的UI更新由以下两个方法完成。
1234567891011121314151617181920212223242526272829303132333435363738
updateDaysPanel();updatePassedDaysLabel();CalendarController.java主要处理具体的业务逻辑,而所使用的一些与具体应用无关的日历算法逻辑则交给CalendarModel.java。CalendarModel.javapublicclassCalendarModel{privateintdaytab[][]={{0,31,28,31,30,31,30,31,31,30,31,30,31},{0,31,29,31,30,31,30,31,31,30,31,30,31}};publicbooleanisLeapYear(intyear){return((year%4==0&&year%100!=0)||year%400==0);}publicintdayOfYear(intday,intmonth,intyear){intleap=isLeapYear(year)?1:0;for(inti=1;i
建立一个二维数组,分别表示闰年与非闰年的每月天数。主要方法有:
1.booleanisLeapYear(intyear);判断闰年
2.dayOfYear(intday,intmonth,intyear);计算所提供日期为当前year的第几天
3.daysOfMonth(intmonth,intyear);返回当前月份的天数
4.dayOfWeek(intday,intmonth,intyear);计算某年某月某日是星期几,这里使用了基姆拉尔森计算公式。
基姆拉尔森计算公式
1.W=(d+2m+3(m+1)/5+y+y/4-y/100+y/400)mod7
2.d天
3.m月
4.y年
5.1月2月换算为去年的1314月计算
6.w=0是星期一,依次类推。
|
|