配色: 字号:
学习Java中的日期和时间处理及Java日历小程序的编写
2016-10-17 | 阅:  转:  |  分享 
  
学习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是星期一,依次类推。





















献花(0)
+1
(本文系白狐一梦首藏)