JAVA网页编程之Java API的Date, Calendar日期处置相干...
你说是sun公司对她研究的透还是微软?针对自己工具开发的.net性能上肯定会站上风的。calendar简介在盘算机程序中准确的处置日期是坚苦的。不但有不言而喻的(英语:January,法语:Janvier,德语:Januar,等)国际化需求,并且得思索分歧的日期体系(并不是一切的文明都用基督耶稣的诞辰作为编年的入手下手)。若有高精度或十分年夜范围的工夫必要被处置,就有分外的方面必要被注重,好比闰秒或工夫体系的变更。(公历(阳历,格里高利历法)在东方被广泛承受是在1582年,但并不是一切的国度在统一天承受!)
只管有关于闰秒,时区,夏令时,农历的成绩,器度工夫倒是一个十分复杂的观点:工夫的举行是线性的很简单被疏忽。一旦工夫轴的地区被界说,任什么时候间点被从出发点工夫的流逝就能够断定。这和地舆地位或外地时区是自力的C对恣意指定的工夫点,对恣意区域,从出发点的历程是不异的(疏忽绝对论的改正)。
--------------------------------------------------------------------------------
可当我们试图依据某些日历注释这一工夫点的时分坚苦来了,好比,依据月,日,大概年来暗示它。在这一步上地舆信息变得相干:在工夫上的统一个点对应分歧的天的某一工夫,依附于地区(好比:时区)。基于注释日期的修改常常是需要的(明天一个月今后是哪一天?)而且增添了分外的坚苦:上溢和下溢(12月15号的后一个月是下一年),且不明白(1月30号后的一个月是哪一天?).
在最后的JDK1.0,一个工夫点,经由过程把它注释为java.util.Date类,它被盘算在一同来暗示.固然绝对简单处置,但它其实不撑持国际化;从JDK1.1.4或JDK1.1.5,多样的卖力处置日期的职责被分派到以下类中:
java.util.Date
代表一个工夫点.
abstractjava.util.Calendar
java.util.GregorianCalendarextendsjava.util.Calendar
注释和处置Date.
abstractjava.util.TimeZone
java.util.SimpleTimeZoneextendsjava.util.TimeZone
代表一个恣意的从格林威治的偏移量,也包括了合用于夏令时(daylightsavingsrules)的信息.
abstractjava.text.DateFormatextendsjava.text.Format
java.text.SimpleDateFormatextendsjava.text.DateFormat
变形到格局优秀的,可打印的String,反之亦然.
java.text.DateFormatSymbols
月份,礼拜等的翻译,作为从Locale获得信息的一种替换选择.
java.sql.Dateextendsjava.util.Date
java.sql.Timeextendsjava.util.Date
java.sql.Timestampextendsjava.util.Date
代表工夫点,同时为了在sql语句中利用也包括得当的格局.
注重:DateFormat和相干的类在java.text.*包.一切的java.sql.*包中日期处置相干类承继了java.util.Date类.一切的别的类在java.util.*包中.
这些"新"类来自三个分别的承继条理,其顶层类(Calendar,TimeZone,andDateFormat)是笼统的.针对每个笼统类,Java尺度类库供应了一个详细的完成.
java.util.Date
类java.util.Date代表一个工夫点.在很多使用中,此种笼统被称为"TimeStamp."在尺度的Java类库完成中,这个工夫点代表Unix纪元January1,1970,00:00:00GMT入手下手的毫秒数.因此观点下去说,这个类是long的复杂封装.
依据此种注释,类中唯一的没有过时的(除那些毫秒数的get和set办法)是那些排序办法.
这个类依托System.currentTimeMillis()来获得以后的工夫点.因而它的正确度和精度由System的完成和它所挪用底层(实质是操纵体系)决意.
Thejava.util.DateAPI
在最后的Date类利用中名字和商定引发了无尽的搅浑.但是用0-11盘算月,从1900盘算年的决意仿照了C尺度类库的习气,挪用函数getTime()前往肇端于Unix纪元的毫秒数和getDate()前往礼拜的决意明显是Java类计划者本人的.
java.util.Calendar
语义
Calendar代表一个工夫点(一个"Date"),用以在特定的地区和时区得当的注释器.每个Calendar实例有一个包括了自纪元入手下手的代表工夫点的long变量.
这意味着Calendar不是一个(无形态)变更者或注释器,也不是一个修正dates的工场.它不撑持以下体例:
MonthInterpreter.getMonth(inputDate)or
DateFactory.addMonth(inputDate)
Instead,Calendar实例必需被初始化到特定的Date.此Calendar实例能够被修正或查询interpreted属性.
奇异的是,此类的instances老是被初始化为以后工夫.取得一个初始化为恣意Date的Calendar实例是不成能的―API强迫程序员经由过程一系列的在实例上的办法挪用,好比setTime(date)来显式的设置日期.
会见Interpreted字段和类常量
Calendar类服从一不经常使用的体例来会见interpreteddate实例的单个字段.而不是供应一些dedicated属性getters和setters办法(好比getMonth()),它仅供应了一个,利用一个标示作为参数来猎取哀求的属性的办法:
intget(Calendar.MONTH)等等.
注重这个函数老是前往一个int!
这些字段的标示符被界说为Calendar类的publicstaticfinal变量.(这些identifiers是raw的整数,没有被封装为一个列举笼统.)
除对应这些字段标示(键值),Calendar类界说了很多附加的publicstaticfinal变量来保留这些字段的值.因而,为测试某一特定date(由Calendar的实例calendar暗示)是不是在一年的第一个月,会有像以下的代码:
if(calendar.get(Calendar.MONTH)==Calendar.JANUARY){...}
注重月份被叫做JANUARY,FEBRUARY,等等,不论location(绝对更中性的名字好比:MONTH_1,MONTH_2,等等).也有一个字段UNDECIMBER,被一些(非公历(阳历,格里高利历法))日历利用,代表一年的第十三个月.
不幸的是,键值和值既没有经由过程名字也没分构成嵌套的inerface来辨别.
处置
Calendar供应了三种举措来修正以后实例代表的日期:set(),add(),和roll().set()办法复杂的设置特定的字段为希冀的值.add()和roll()的分歧在于它们处置over-andunderflows:add()传送变动到"较小"或"较年夜"的字段,而roll()不影响别的字段.好比,当给代表12月15号的Calendar实例增添一个月,当add()利用年会增添,但利用roll()不会产生任何变更.为每种case对应一个函数的决意的念头是,它们大概在GUI中分歧的利用情况.
因为Calendar的完成的体例,它包括冗余的数据:一切的字段都能够从给定的时区和纪元入手下手的毫秒数盘算出来,反之亦然.这个类为这些操纵分离界说了笼统办法computeFields()和computeTime(),又界说了complete()办法实行完整的往返路程.由于有两套冗余的数据,这两套数据大概分歧步.依据类的JavaDoc文档,当产生变动的时分依附的数据以lazily的体例从头盘算.当从头盘算必要的时分,子类必需保护一套脏数据标记作为标记.
--------------------------------------------------------------------------------
完成的Leakage
关于一个”新”的日期相干处置类,不能不说完成的细节在某种水平上被泄露到了API中.在这点上,这是它们成心用作基类的自界说开辟的反应,但它也偶尔看出是不充实明晰计划一个大众接口的了局.Calendar笼统是不是保护两个冗余数据汇合完整是一个完成的细节,因此应该对客户类埋没.这也包含盘算经由过程承继来重用此类.
附加的功效
Calendar基类供应的附加功效分红三类.几个静态的工场办法来取得用恣意时区和locales初始化的实例.如后面提到的,一切以这类体例取得实例已被初始化为以后工夫.没有工场办法被供应来取得初始化为恣意工夫点的实例.
第二组包括before(Object)和after(Object)办法.它们承受Object范例的参数,因此同意这些办法被子类以恣意范例的参数掩盖失落.
最初,有很多附加的办法来取得设置附加的属性,好比以后的时区.傍边有几个用以查询特定字段在以后Calendar完成下的大概和实践的最年夜、最小值.
java.util.GregorianCalendar
GregorianCalendar是唯一可用的Calendar的子类.它供应了基本Calendar笼统合适于依据在东方的习气注释日期的完成.它增添了很多public的机关函数,也有针关于GregorianCalendars的办法,好比isLeapYear().
java.util.TimeZone和java.util.SimpleTimeZone
TimeZone类和其子类是帮助类,被Calendar用以依据选择的时区来注释日期.按字面意义来讲,一个时区暗示加到GMT上后到以后时区的必定的偏移.明显,这个偏移在夏令时无效的时分会产生变更.因此为了盘算关于给定日期和工夫的当地工夫,TimeZone笼统不但必要分明当DST无效时的分外偏移,并且还需分明甚么时分DST无效的划定规矩.
笼统基类TimeZone供应了基础的处置"raw"(没有思索夏令时)实践偏移(用毫秒数!)的办法,但任何干于DST划定规矩的功效完成被留给了子类,好比SimpleTimeZone.后者供应了很多办法来指定把持DST入手下手和停止的划定规矩,好比在一个月中明白的某一天或某一天随后的周几.每个TimeZone有一个可读的,当地有关的显现名.显现名以两种作风:LONG和SHORT出现.
礼拜的入手下手?
Calendar的文档投进了相称的笔墨来准确的盘算月或年中的weeks.weekday被以为是一周的入手下手在因国度的分歧而分歧.在美国,一周一般被以为从周日入手下手.在部分欧洲国度一周从周一入手下手停止于周日.这将影响到哪一周被以为是在一年(或月)第一个完全的周,和盘算一年的周数.
时区由一标示字符串明白的决意.基类供应静态办法String[]getAvailableIDs()来取得一切已知安装(JDK内带有)的尺度时区.(在我的安装内有557个,JDK1.4.1)假设必要,JavaDoc界说了严厉的创建自界说时区标示符的语法.也供应了静态工场办法用以猎取―指定ID或缺省确当前时区的TimeZone实例.SimpleTimeZone供应了一些私有的机关函数,奇异的是关于一个笼统类,如TimeZone.(JavaDoc写到"子类机关函数挪用."明显,应当声明为protected.)
java.text.DateFormat
只管Calendar和相干类处置locale-specific日期的注释,仍有DateFormat类帮助日期和(人类)可浏览字符串之间的变更.暗示一个工夫点时,会呈现附加的当地化成绩:不单单在言语,并且日期格局是区域自力的(美国:Month/Day/Year,德国:Day.Month.Year,等等).DateFormat全力地为程序员办理这些分歧.
笼统基类DateFormat不必要(且不同意)恣意的,程序员界说的日期格局.作为替换,它界说了四种格局化作风:SHORT,MEDIUM,LONG,和FULL(以冗余增添的按次).对一给定locale和style,程序员可依托此类猎取得当的日期格局.
笼统基类DateFormat没有界说静态办法来完成文本和日期之间的格局化和转换.作为替换,它界说了几个静态工场办法来猎取被初始化为给定locale和选定style的实例.既然尺度的格局化老是包括日期和工夫,附加工场办法可用来猎取仅处置工夫或日期部分的实例.Stringformat(Date)和Dateparse(String)办法然后实行变形.注重详细的子类能够选择冲破这类习气.
在其外部利用,注释日期的Calendar对象是可会见和修正的,TimeZone和NumberFormat对象也一样.但是,一旦DateFormat被实例化locale和style就不克不及再修正.
亦有可用的(笼统的)用以拼接的字符串剖析和格局化的办法,分离承受分外的ParsePosition或FieldPosition参数.这些办法的每个都有两个版本.一个承受或前往Date实例另外一个承受或前往一般的Object,来同意在子类中有选择性的处置Date.它界说了一些以_FIELD开头的publicstatic变量来标示多种大概和FieldPosition一同利用的变量(cf.java.util.Format的Javadoc).
唯一且最经常使用的DateFormat类的详细完成是SimpleDateFormat.它供应了一切上述的功效,且同意界说恣意的工夫格局.有一套丰厚语法来指定格局化形式;JavaDoc供应了一切细节.形式能够被指定为机关函数的参数或显式的设置.
PrintingaTimestamp:ACut-and-PasteExample
设想你要用用户界说的格局打印以后的工夫;好比,到log文件.以下就是做这些的:
//创立以下格局的形式:Hour(0-23):Minute:Second
SimpleDateFormatformatter=newSimpleDateFormat("HH:mm:ss");
Datenow=newDate();
StringlogEntry=formatter.format(now);
//从后端读进
try{
Datesometime=formatter.parse(logEntry);
}catch(ParseExceptionexc){
exc.printStackTrace();
}
注重必要被catch的ParseException.当输出的字符串不克不及被parse的时分被抛出.
java.sql.*相干类
在java.sql.*包中的日期工夫处置类都承继了java.util.Date.现实上它们三个反应了三种尺度SQL92模子的范例必要DATE,TIME,andTIMESTAMP.
像java.util.Date,SQL包中的这三个类是暗示一个工夫点的数字的复杂封装.分离地Date和Time类疏忽关于一天中的工夫或日历的日期.
可Timestamp类,不但包括到毫秒精度,一般的工夫和日期,并且同意存储附加的准确到纳秒精度的工夫点的数据.(纳秒是一秒的十亿分之一)
除暗射对应的SQL数据范例,这些类处置与SQL分歧的字符串暗示的转换.在这一点,这三个类中的每个掩盖了toString()办法.别的,每一个类供应了静态的工场办法,valueOf(String),前往被初始化为传送参数字符串暗示的工夫确当前挪用类的实例.这三个办法的字符串暗示的格局已被SQL尺度选定,且不克不及被程序员改动.
存储纳秒必要的分外数据,没有很好的与在Timestamp中别的一般的工夫和日期信息的暗示分歧.好比,在Timestamp实例上挪用getTime()将前往自Unix纪元入手下手的毫秒数,疏忽了纳秒数据.复杂地,依据JavaDoc文档,hashCode()办法在子类中没有被掩盖,因此也疏忽了纳秒数据.
java.sql.Timestamp的JavaDoc指出"inheritancerelationship(...)实践暗示完成的承继,而不是范例承继(这违背了承继的初志).但即便这句话是毛病的,既然Java没有公有承继的观点(也即承继完成).一切java.sql.*包中的类应当被计划为封装一个java.util.Date对象,而不是承继它,仅表露必要的办法―最最少,办法好比hashCode()应当被得当的掩盖.
最初一个批评是关于数据库引擎的时区的处置.在java.sql.*包中的类不同意显式的设置时区.数据库服务器(或驱动)可自在的根据服务器server确当地时区注释这些信息,且其大概被影响而变更(好比,由于夏令时).
总结
经由过程后面的会商,很分明,Java的日期处置相干类并不是很庞大,可是没有被很好计划.封装被疏漏,APIs布局庞大且没有被很好的构造,且十分见的思绪常常被无启事的利用.完成更有别的的莫名奇奥(发起看看Calendar.getInstance(Locale)关于一切可用locale实践前往对象的范例!)另外一方面,theclassesmanagetotreatallofthedifficultiesinherentininternationalizeddatehandlingand,inanycase,areheretostay.但愿这篇文章对匡助你弄清它们的用法有所匡助.
CallMeByMyTrueNames
AsalastexampleofthewonderfulconsistencyandorthogonalityofJavasAPIs,Iwouldliketolistthree(maybetherearemore!)differentmethodstoobtainthenumberofmillisecondssincethestartoftheUnixepoch:
longjava.util.Date.getTime()
longjava.util.Calendar.getTimeInMillis()(NewwithJDK1.4.1.Notethatjava.util.Calendar.getTime()returnsaDateobject!)
longjava.lang.System.currentTimeMillis()
感激
作者十分感激WilhelmFitzpatrick(西雅图)仔细的浏览原稿和有代价的定见.
References
InternationalCalendarsinJavaatIBM:AdetailedwhitepaperbyoneoftheoriginalauthorsonthegenesisandintendedusageofJavasdate-handlingclasses.Highlyrecommended.
IBMalphaWorks:InternationalCalendars:AdditionalsubclassesofCalendarforBuddhist,Hebrew,Muslim,andJapanesecalendarsusedtobeavailableatIBMsalphaWorks.Unfortunately,theyseemtobetemporarilyunavailable.
ReingoldonCalendars:WebsiteofEdwardM.Reingold,authorofCalendricalCalculations,thestandardreferenceoncalendars.
AbouttheCalendars:Abriefoverviewofsomeofthemorecommoninternationalcalendars.
ThreadonJavaLobby:Abrief,butinteresting,threadonJavaLobby.Apparently,somepeopleconsideredtheAPIsofJavasdateclassestobesobadthattheyfiledanofficialbug-reporttohavethemchanged.Unfortunately,therequesthasbeenrejected.
PhilippK.Janert,Ph.D.isaSoftwareProjectConsultant,serverprogrammer,andarchitect.
Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。Oracle收购Sun后Java前途未卜。 学Java必读的两个开源程序就是Jive和Pet Store.。 Jive是国外一个非常著名的BBS程序,完全开放源码。论坛的设计采用了很多先进的技术,如Cache、用户认证、Filter、XML等,而且论坛完全屏蔽了对数据库的访问,可以很轻易的在不同数据库中移植。论坛还有方便的安装和管理程序,这是我们平时编程时容易忽略的一部份(中国程序员一般只注重编程的技术含量,却完全不考虑用户的感受,这就是我们与国外软件的差距所在)。 在全球云计算和移动互联网的产业环境下,Java更具备了显著优势和广阔前景。 你就该学一学Servlet了。Servlet就是服务器端小程序,他负责生成发送给客户端的HTML文件。JSP在执行时,也是先转换成Servlet再运行的。虽说JSP理论上可以完全取代Servlet,这也是SUN推出JSP的本意,可是Servlet用来控制流程跳转还是挺方便的,也令程序更清晰。接下来你应该学习一下Javabean了,可能你早就看不管JSP在HTML中嵌Java代码的混乱方式了,这种方式跟ASP又有什么区别呢? 关于设计模式的资料,还是向大家推荐banq的网站 http://www.jdon.com/,他把GOF的23种模式以通俗易懂的方式诠释出来,纯Java描述,真是经典中的经典。 如果要向java web方向发展也要吧看看《Java web从入门到精通》学完再到《Struts2.0入门到精通》这样你差不多就把代码给学完了。有兴趣可以看一些设计模块和框架的包等等。 科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。 还好,SUN提供了Javabean可以把你的JSP中的 Java代码封装起来,便于调用也便于重用。 科学超级计算机、移动电话和互联网,同时拥有全球最大的开发者专业社群。 是一种由美国SUN计算机公司(Sun Microsystems, Inc.)所研究而成的语言 Java语言支持Internet应用的开发,在基本的Java应用编程接口中有一个网络应用编程接口(java net),它提供了用于网络应用编程的类库,包括URL、URLConnection、Socket、ServerSocket等。Java的RMI(远程方法激活)机制也是开发分布式应用的重要手段。 Pet Store.(宠物店)是SUN公司为了演示其J2EE编程规范而推出的开放源码的程序,应该很具有权威性,想学J2EE和EJB的朋友不要 错过了。 你可以去承接一些项目做了,一开始可能有些困难,可是你有技术积累,又考虑周全,接下项目来可以迅速作完,相信大家以后都会来找你的,所以Money就哗啦啦的。。。。。。 J2SE开发桌面应用软件比起 VC,VB,DEPHI这些传统开发语言来说,优势好象并不明显。J2ME对于初学者来说,好象又有点深奥,而且一般开发者很难有开发环境。 如果你学过HTML,那么事情要好办的多,如果没有,那你快去补一补HTML基础吧。其实JSP中的Java语法也不多,它更象一个脚本语言,有点象ASP。 是一种由美国SUN计算机公司(Sun Microsystems, Inc.)所研究而成的语言 你现在最缺的是实际的工作经验,而不是书本上那些凭空想出来的程序。 http://www.jdon.com/去下载,或到同济技术论坛的服务器ftp://nro.shtdu.edu.cn去下,安装上有什么问题,可以到论坛上去提问。 Sun公司看见Oak在互联网上应用的前景,于是改造了Oak,于1995年5月以Java的名称正式发布。Java伴随着互联网的迅猛发展而发展,逐渐成为重要的网络编程语言。 Java 不同于一般的编译执行计算机语言和解释执行计算机语言。它首先将源代码编译成二进制字节码(bytecode),然后依赖各种不同平台上的虚拟机来解释执行字节码。从而实现了“一次编译、到处执行”的跨平台特性。
页:
[1]