JAVA处理日期(Date)时间(Time)以及相关类的介绍

JAVA处理日期时间常用方法:

1.    java.util.Calendar

Calendar类是一个抽象类,它为特定瞬间与一组诸如YEARMONTHDAY_OF_MONTHHOUR等 日历字段之间的转换提供了一些方法,并为操作日历字段(例如获得下星期的日期)提供了一些方法。瞬间可用毫秒值来表示,它是距历元(即格林威治标准时间1970 年 11日的00:00:00.000,格里高利历)的偏移量。

:

Calendar cal = Calendar.getInstance();//使用默认时区和语言环境获得一个日历。
cal.add(Calendar.DAY_OF_MONTH, -1);//
取当前日期的前一天.

cal.add(Calendar.DAY_OF_MONTH, +1);//取当前日期的后一天.

 

//通过格式化输出日期
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");

System.out.println("Today is:"+format.format(Calendar.getInstance().getTime()));

 

System.out.println("yesterday is:"+format.format(cal.getTime()));

得到 2007-12-25 日期:

Calendar calendar = new GregorianCalendar(2007, 11, 25,0,0,0);
Date date = calendar.getTime();
System.out.println("2007 Christmas is:"+format.format(date));

//java
月份是从0-11,月份设置时要减1.

//GregorianCalendar
构造方法参数依次为:年,月-1,日,时,分,秒.

取日期的部分:

int year =calendar.get(Calendar.YEAR);

int month=calendar.get(Calendar.MONTH)+1;

int day =calendar.get(Calendar.DAY_OF_MONTH);

int hour =calendar.get(Calendar.HOUR_OF_DAY);

int minute =calendar.get(Calendar.MINUTE);

int seconds =calendar.get(Calendar.SECOND);

取月份要加1.

判断当前月份的最大天数:
Calendar cal = Calendar.getInstance();
int day=cal.getActualMaximum(Calendar.DAY_OF_MONTH);
System.out.println(day);

2.    java.util.Date

Date表示特定的瞬间,精确到毫秒。JDK 1.1开始,应该使用Calendar类实现日期和时间字段之间转换,使用DateFormat类来格式化和分析日期字符串。Date中的相应方法已废弃。

尽管Date类打算反映协调世界时(UTC),但无法做到如此准确,这取决于Java虚拟机的主机环境。当前几乎所有操作系统都假定1 = 24 × 60 × 60 = 86400秒。但对于UTC,大约每一两年出现一次额外的一秒,称为闰秒。闰秒始终作为当天的最后一秒增加,并且始终在1231日或630日增加。例如,1995年的最后一分钟是61秒,因为增加了闰秒。大多数计算机时钟不是特别的准确,因此不能反映闰秒的差别。

一些计算机标准是按照格林威治标准时(GMT)定义的,格林威治标准时和世界时(UT)是相等的。GMT是标准的民间名称;UT是相同标准的科学名称。UTCUT的区别是:UTC是基于原子时钟的,UT是基于天体观察的,两者在实际应用中难分轩轾。因为地球的旋转不是均匀的(它以复杂的方式减速和加速),所以UT始终不是均匀地流过。闰秒是根据需要引入UTC的,以便把UTC保持在UT10.9秒之内,UT1是应用了某些更正的UT版本。还有其他的时间和日期系统;例如,基于卫星的全球定位系统(GPS)使用的时间刻度与UTC同步,但没有 针对闰秒进行调整。有关更多信息的一个有趣来源是美国海军天文台,特别是Directorate of Time的网址:

    http://tycho.usno.navy.mil

 

还有它们对"Systems of Time"的定义,网址为:

    http://tycho.usno.navy.mil/systime.html

 

在类Date所有可以接受或返回年、月、日期、小时、分钟和秒值的方法中,将使用下面的表示形式:

  • 年份 y由整数 y - 1900表示。
  • 月份由从011的整数表示;0是一月、1是二月等等;因此11是十二月。
  • 日期(一月中的某天)按通常方式由整数131表示。
  • 小时由从023的整数表示。因此,从午夜到1 a.m.的时间是0点,从中午到1 p.m.的时间是12点。
  • 分钟按通常方式由059的整数表示。
  • 秒由061的整数表示;值6061只对闰秒发生,尽管那样,也只用在实际正确跟踪闰秒的Java实现中。于按当前引入闰秒的方式,两个闰秒在同一分钟内发生是极不可能的,但此规范遵循ISO C的日期和时间约定。

在所有情形中,针对这些目的赋予方法的参数不需要在指定的范围内;例如,可以把日期指定为132日,并把它解释为21日的相同含义。

java.util.Date today=new java.util.Date();
System.out.println("Today is "+formats.format(today));

取当月的第一天:
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-01");
java.util.Date firstDay=new java.util.Date();
System.out.println("the month first day is "+formats.format(firstDay));
取当月的最后一天:
Calendar cal = Calendar.getInstance();
int maxDay=cals.getActualMaximum(Calendar.DAY_OF_MONTH);
java.text.Format formatter3=new java.text.SimpleDateFormat("yyyy-MM-"+maxDay);
System.out.println(formatter3.format(cal.getTime()));

求两个日期之间相隔的天数:
java.text.SimpleDateFormat format = new java.text.SimpleDateFormat("yyyy-MM-dd");
java.util.Date beginDate= format.parse(" 2007-12-24 ");
java.util.Date endDate= format.parse(" 2007-12-25 ");
long day=(date.getTime()-mydate.getTime())/(24*60*60*1000);
System.out.println("
相隔的天数="+day);
一年前的日期:
java.text.Format formatter=new java.text.SimpleDateFormat("yyyy-MM-dd");
java.util.Date todayDate=new java.util.Date();
long beforeTime=(todayDate.getTime()/1000)-60*60*24*365;
todayDate.setTime(beforeTime*1000);
String beforeDate=formatter.format(todayDate);
System.out.println(beforeDate);
一年后的日期:
java.text.Format formatter=new java.text.SimpleDateFormat("yyyy-MM-dd");
java.util.Date todayDate=new java.util.Date();
long afterTime=(todayDate.getTime()/1000)+60*60*24*365;
todayDate.setTime(afterTime*1000);
String afterDate=formatter.format(todayDate);
System.out.println(afterDate);

10小时后的时间
java.util.Calendar Cal=java.util.Calendar.getInstance();
Cal.setTime(dateOper);
Cal.add(java.util.Calendar.HOUR_OF_DAY,10);
System.out.println("date:"+forma.format(Cal.getTime()));

10小时前的时间

java.util.Calendar Cal=java.util.Calendar.getInstance();
Cal.setTime(dateOper);
Cal.add(java.util.Calendar.HOUR_OF_DAY,-10);
System.out.println("date:"+forma.format(Cal.getTime()));

3.java.sql.Date
继承自java.util.Date,是操作数据库用的日期类型

一个包装了毫秒值的瘦包装器(thin wrapper),它允许JDBC将毫秒值标识为SQL DATE值。毫秒值表示自19701100:00:00 GMT以来经过的毫秒数。为了与SQL DATE的定义一致,由 java.sql.Date实例包装的毫秒值必须通过将时间、分钟、秒和毫秒设置为与该实例相关的特定时区中的零来规范化

 java.sql.Date sqlDate = new java.sql.Date(java.sql.Date.valueOf(" 2007-12-25 ").getTime());
日期比较:简单的比较可以以字符串的形式直接比较,也可使用
java.sql.Date.valueOf(" 2007-03-08 ").compareTo(java.sql.Date.valueOf(" 2007-03-18 "))
方式来比较日期的大小.也可使用java.util.Date.after(java.util.Date)来比较.

 

4java.util.GregorianCalendar 
   

 GregorianCalendarCalendar的一个具体子类,提供了世界上大多数国家/地区使用的标准日历系统。

GregorianCalendar是一种混合日历,在单一间断性的支持下同时支持儒略历和格里高利历系统,在默认情况下,它对应格里高利日历创立时的格里高利历日期(某些国家/地区是在1582 年 10 15日创立,在其他国家/地区要晚一些)。可由调用方通过调用 setGregorianChange()来更改起始日期。

历史上,在那些首先采用格里高利历的国家/地区中,1582104日(儒略历)之后就是15821015日(格里高利历)。此日历正确地模拟了这些变化。在开始格里高利历之前,GregorianCalendar实现的是儒略历。格里高利历和儒略历之间的惟一区别就是闰年规则。儒略历指定每4年就为闰年,而格里高利历则忽略不能被400整除的世纪年。

GregorianCalendar可实现预期的 格里高利历和儒略历。也就是说,可以通过在时间上无限地向后或向前外推当前规则来计算日期。因此,对于所有的年份,都可以使用 GregorianCalendar来生成有意义并且一致的结果。但是,采用现代儒略历规则时,使用 GregorianCalendar得到的日期只在历史上从公元431日之后是准确的。在此日期之前,闰年规则的应用没有规则性,在45 BC之前,甚至不存在儒略历。

在格里高利历创立以前,新年是325日。为了避免混淆,此日历始终使用11日为新年。如果想要格里高利历转换之前并且处于11日和324日之间的日期,则可以进行手动调整。

WEEK_OF_YEAR字段所计算的值的范围从153。一年的第一个星期始于 getFirstDayOfWeek()的最早7天,至少包含该年的 getMinimalDaysInFirstWeek()各天。这取决于 getMinimalDaysInFirstWeek()getFirstDayOfWeek()的值以及11日是星期几。一年的第一个星期和下一年的第一个星期之间的各个星期按顺序从25253(根据需要)进行编号。

例如,199811日是星期四。如果 getFirstDayOfWeek()MONDAY,并且 getMinimalDaysInFirstWeek()4(这些值反映了ISO 8601和很多国家/地区标准),则1998年的第一个星期开始于19971229日,结束于199814日。但是,如果 getFirstDayOfWeek()SUNDAY,那么1998年的第一个星期开始于199814日,结束于1998110日;1998年头三天是1997年第53个星期的一部分。

WEEK_OF_MONTH字段所计算的值的范围从06。一个月的第一个星期(WEEK_OF_MONTH = 1的日期)是该月至少连续 getMinimalDaysInFirstWeek()天中的最早日期,结束于 getFirstDayOfWeek()的前一天。与一年的第一个星期不同,一个月的第一个星期可能短于 7天,也不必从 getFirstDayOfWeek()这一天开始,并且不包括前一个月的日期。在第一个星期之前该月日期的 WEEK_OF_MONTH0

5. java.text.DateFormat

DateFormat是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并分析日期或时间。日期/时间格式化子类(如SimpleDateFormat)允许进行格式化(也就是日期->文本)、分析(文本->日期)和标准化。将日期表示为Date对象,或者表示为从GMT(格林尼治标准时间)1970年, 1 100:00:00这一刻开始的毫秒数。

DateFormat提供了很多类方法,以获得基于默认或给定语言环境和多种格式化风格的默认日期/时间Formatter。格式化风格包括FULLLONGMEDIUMSHORT。方法描述中提供了使用这些风格的更多细节和示例。

DateFormat可帮助进行格式化并分析任何语言环境的日期。对于月、星期,甚至日历格式(阴历和阳历),其代码可完全与语言环境的约定无关。

要格式化一个当前语言环境下的日期,可使用某个静态工厂方法:

 myString = DateFormat.getDateInstance().format(myDate);

 

如果格式化多个日期,那么获得该格式并多次使用它是更为高效的做法,这样系统就不必多次获取有关环境语言和国家/地区约定的信息了。

 DateFormat df = DateFormat.getDateInstance();

 for (int i = 0; i < myDate.length; ++i) {

   output.println(df.format(myDate[i]) + "; ");

 }

 

要格式化不同语言环境的日期,可在getDateInstance()的调用中指定它。

 DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, Locale.FRANCE);

 

还可使用DateFormat进行分析。

 myDate = df.parse(myString);

 

使用getDateInstance来获得该国家/地区的标准日期格式。另外还提供了一些其他静态工厂方法。使用getTimeInstance可获得该国家/地区的时间格式。使用getDateTimeInstance可获得日期和时间格式。可以将不同选项传入这些工厂方法,以控制结果的长度(从SHORTMEDIUMLONG再到FULL)。确切的结果取决于语言环境,但是通常:

  • SHORT完全为数字,如12.13.523:30pm
  • MEDIUM较长,如Jan 12, 1952
  • LONG更长,如January 12, 19523:30:32pm
  • FULL是完全指定,如Tuesday, April 12, 1952 AD3:30:42pm PST

如果愿意,还可以在格式上设置时区。如果想对格式化或分析施加更多的控制(或者给予用户更多的控制),可以尝试将从工厂方法所获得的DateFormat强制转换为SimpleDateFormat。这适用于大多数国家/地区;只是要记住将其放入一个try代码块中,以防遇到特殊的格式。

还可以使用借助ParsePositionFieldPosition的分析和格式化方法形式来

  • 逐步地分析字符串的各部分。
  • 对齐任意特定的字段,或者找出字符串在屏幕上的选择位置。
6. java.text.SimpleDateFormat

SimpleDateFormat是一个以与语言环境相关的方式来格式化和分析日期的具体类。它允许进行格式化(日期->文本)、分析(文本->日期)和规范化。

SimpleDateFormat使得可以选择任何用户定义的日期-时间格式的模式。但是,仍然建议通过 DateFormat中的 getTimeInstancegetDateInstancegetDateTimeInstance来新的创建日期-时间格式化程序。每一个这样的类方法都能够返回一个以默认格式模式初始化的日期/时间格式化程序。可以根据需要使用 applyPattern方法来修改格式模式。有关使用这些方法的更多信息,请参阅 DateFormat

日期和时间模式

日期和时间格式由日期和时间模式 字符串指定。在日期和时间模式字符串中,未加引号的字母 'A''Z''a''z'被解释为模式字母,用来表示日期或时间字符串元素。文本可以使用单引号(')引起来,以免进行解释。"''"表示单引号。所有其他字符均不解释;只是在格式化时将它们简单复制到输出字符串,或者在分析时与输入字符串进行匹配。

定义了以下模式字母(所有其他字符 'A''Z''a''z'都被保留):

字母

日期或时间元素

表示

示例

G

Era标志符

Text

AD

y

Year

1996;96

M

年中的月份

Month

July;Jul;07

w

年中的周数

Number

27

W

月份中的周数

Number

2

D

年中的天数

Number

189

d

月份中的天数

Number

10

F

月份中的星期

Number

2

E

星期中的天数

Text

Tuesday;Tue

a

Am/pm标记

Text

PM

H

一天中的小时数(0-23

Number

0

k

一天中的小时数(1-24

Number

24

K

am/pm中的小时数(0-11

Number

0

h

am/pm中的小时数(1-12

Number

12

m

小时中的分钟数

Number

30

s

分钟中的秒数

Number

55

S

毫秒数

Number

978

z

时区

General time zone

Pacific Standard Time;PST;GMT-08:00

Z

时区

RFC 822 time zone

-0800

模式字母通常是重复的,其数量确定其精确表示:

  • Text:对于格式化来说,如果模式字母的数量大于或等于4,则使用完全形式;否则,在可用的情况下使用短形式或缩写形式。对于分析来说,两种形式都是可接受的,与模式字母的数量无关。
  • Number:对于格式化来说,模式字母的数量是最小的数位,如果数位不够,则用0填充以达到此数量。对于分析来说,模式字母的数量被忽略,除非必须分开两个相邻字段。
  • Year:对于格式化来说,如果模式字母的数量为2,则年份截取为2位数,否则将年份解释为 number

对于分析来说,如果模式字母的数量大于2,则年份照字面意义进行解释,而不管数位是多少。因此使用模式"MM/dd/yyyy",将" 01/11/12 "分析为公元12111日。

在分析缩写年份模式("y""yy")时,SimpleDateFormat必须相对于某个世纪来解释缩写的年份。这通过将日期调整为 SimpleDateFormat实例创建之前的80年和之后20年范围内来完成。例如,在"MM/dd/yy"模式下,如果 SimpleDateFormat实例是在199711日创建的,则字符串" 01/11/12 "将被解释为2012111日,而字符串"05/04/64"将被解释为196454日。在分析时,只有恰好由两位数字组成的字符串(如 Character.isDigit(char)所定义的)被分析为默认的世纪。其他任何数字字符串将照字面意义进行解释,例如单数字字符串,3个或更多数字组成的字符串,或者不都是数字的两位数字字符串(例如"-1")。因此,在相同的模式下,"01/02/3""01/02/003"解释为公元312日。同样,"01/02/-3"分析为公元前412日。

  • Month:如果模式字母的数量为3或大于3,则将月份解释为 text;否则解释为 number
  • General time zone:如果时区有名称,则将它们解释为 text。对于表示GMT偏移值的时区,使用以下语法:
 ·                
      GMTOffsetTimeZone:
 ·                
              GMT Sign Hours : Minutes
 ·                
      Sign: one of
 ·                
              + -
 ·                
      Hours:
 ·                
              Digit
 ·                
              Digit Digit
 ·                
      Minutes:
 ·                
              Digit Digit
 ·                
      Digit: one of
             0 1 2 3 4 5 6 7 8 9

Hours必须在023之间,Minutes必须在0059之间。格式是与语言环境无关的,并且数字必须取自Unicode标准的Basic Latin块。

对于分析来说,RFC 822 time zones也是可接受的。

 ·                
      RFC822TimeZone:
 ·                
              Sign TwoDigitHours Minutes
 ·                
      TwoDigitHours:
             Digit Digit

TwoDigitHours必须在0023之间。其他定义请参阅 general time zones

对于分析来说,general time zones也是可接受的。

SimpleDateFormat还支持本地化日期和时间模式 字符串。在这些字符串中,以上所述的模式字母可以用其他与语言环境有关的模式字母来替换。SimpleDateFormat不处理除模式字母之外的文本本地化;而由类的客户端来处理。

示例

以下示例显示了如何在美国语言环境中解释日期和时间模式。给定的日期和时间为美国太平洋时区的本地时间2001-07-04 12:08:56

日期和时间模式

结果

"yyyy.MM.dd G 'at' HH:mm:ss z"

2001.07.04 AD at 12:08:56 PDT

"EEE, MMM d, ''yy"

Wed, Jul 4, '01

"h:mm a"

12:08 PM

"hh 'o''clock' a, zzzz"

12 o'clock PM, Pacific Daylight Time

"K:mm a, z"

0:08 PM, PDT

"yyyyy.MMMMM.dd GGG hh:mm aaa"

02001.July.04 AD 12:08 PM

"EEE, d MMM yyyy HH:mm:ss Z"

Wed, 4 Jul 2001 12:08:56 -0700

"yyMMddHHmmssZ"

010704120856-0700

"yyyy-MM-dd'T'HH:mm:ss.SSSZ"

2001-07-04 T12:08:56.235-0700

同步

日期格式是不同步的。建议为每个线程创建独立的格式实例。如果多个线程同时访问一个格式,则它必须是外部同步的。


  
    
  

 

 

 

 

 

 

 

 

 

 

 

 

 

 

版权声明:本文为xiaojianpitt原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。