日期

JAVA日期时间小结 收藏

<script type="text/javascript"> </script> <script type="text/javascript"> </script> Java /juxinsishui 

Java 语言的 CalendarGregorianCalendar ( 日历 ),Date( 日期 ), DateFormat( 日期格式 ) 组成了 Java 标准的一个基本但是非常重要的部分 日期是商业逻辑计算一个关键的部分 所有的开发者都应该能够计算未来的日期 定制日期的显示格式 并将文本数据解析成日期对象。学习日期 日期格式 日期的解析和日期的计算。  
我们将讨论下面的类
1
   具体类 ( 和抽象类相对 )java.util.Date 
2
   抽象类 java.text.DateFormat  和它的一个具体子类 ,java.text.SimpleDateFormat 
3
   抽象类 java.util.Calendar  和它的一个具体子类 ,java.util.GregorianCalendar 
具体类可以被实例化 但是抽象类却不能 你首先必须实现抽象类的一个具体子类 .
1.   java.util.Date
及其格式化
Date 
类从 Java  开发包 (JDK) 1.0  就开始进化 当时它只包含了几个取得或者设置一个日期数据的各个部分的方法 比如说月 和年 这些方法现在遭到了批评并且已经被转移到了 Calendar 类里去了 我们将在本文中进一步讨论它 这种改进旨在更好的处理日期数据的国际化格式 就象在 JDK 1.1 中一样 , Date  类实际上只是一个包裹类 它包含的是一个长整型数据 表示的是从 GMT( 格林尼治标准时间 )1970, 1  100:00:00 这一刻之前或者是之后经历的毫秒数
1.1. 
创建 java.util.Date
Java
统计从 197011 日起的毫秒的数量表示日期。也就是说,例如, 197012 日,是在 11 日后的 86400000 毫秒。同样的, 19691231 日是在 197011 日前 86400000 毫秒。 JavaDate 类使用 long 类型纪录这些毫秒值 . 因为 long 是有符号整数,所以日期可以在 197011 日之前,也可以在这之后。 Long 类型表示的最大正值和最大负值可以轻松的表示 290000000 年的时间,这适合大多数人的时间要求。
让我们看一个使用系统的当前日期和时间创建一个日期对象并返回一个长整数的简单例子 这个时间通常被称为 Java  虚拟机 (JVM) 主机环境的系统时间
import java.util.Date; 
public class DateExample1 { 
public static void main(String[] args) { 
// Get the system date/time 
Date date = new Date(); 
// 
打印出具体的年,月,日,小时,分钟,秒钟以及时区
System.out.println(date.getTime()); 
}   

在星期六 , 2001929 下午大约是 6:50 的样子 上面的例子在系统输出设备上显示的结果是  1001803809710.  在这个例子中 , 值得注意的是我们使用了 Date  构造函数创建一个日期对象 这个构造函数没有接受任何参数 而这个构造函数在内部使用了 System.currentTimeMillis()  方法来从系统获取日期
//1
年前日期
   java.util.Date myDate=new java.util.Date();  
   long myTime=(myDate.getTime()/1000)-60*60*24*365;
   myDate.setTime(myTime*1000);
   String mDate=formatter.format(myDate);
//
明天日期
   myDate=new java.util.Date(); 
   myTime=(myDate.getTime()/1000)+60*60*24;
   myDate.setTime(myTime*1000);
   mDate=formatter.format(myDate);
//
两个时间之间的天数
   SimpleDateFormat myFormatter = new SimpleDateFormat("yyyy-MM-dd");
   java.util.Date date= myFormatter.parse("2003-05-1"); 
   java.util.Date mydate= myFormatter.parse("1899-12-30");
   long  day=(date.getTime()-mydate.getTime())/(24*60*60*1000);
//
加半小时
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
java.util.Date date1 = format.parse("2002-02-28 23:16:00");
long Time=(date1.getTime()/1000)+60*30;
date1.setTime(Time*1000);
String mydate1=formatter.format(date1);
//
年月周求日期
SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM F E");
java.util.Date date2= formatter2.parse("2003-05 5 
星期五 "); 
SimpleDateFormat formatter3 = new SimpleDateFormat("yyyy-MM-dd");
String mydate2=formatter3.format(date2);
//
求是星期几
mydate= myFormatter.parse("2001-1-1");
SimpleDateFormat formatter4 = new SimpleDateFormat("E");
String mydate3=formatter4.format(mydate);
1.2. Date
格式化
能以一种用户明白的格式来显示这个日期呢 在这里类 java.text.SimpleDateFormat  和它的抽象基类  java.text.DateFormat 。那么 现在我们已经知道了如何获取从 197011 日开始经历的毫秒数了 我们如何才 format  就派得上用场了
// 
我们能不能用下面的代码构件出  2001/8/8 8:8
    import java.io.*;
    import java.util.*;
    public class WhatIsDate
    {
        public static void main(String[] args) {
            Date date = new Date(2001, 8, 8, 8, 8, 8);
            System.out.println(date);
        }
    }
Java 
的编译器竟然报如下信息  (Sun JDK1.3, Windows 2000  中文下 )
注意:
WhatIsDate.java 
使用或覆盖一个不鼓励使用的 API
注意:
使用 -deprecation 重新编译,以得到详细信息。!
那么  Date  对象究竟是为了满足哪个需求呢?看来它不是用来实现基于年 // 日小时 : 分钟   的时间表述。我们查看  Java  的文档,我们看到有  getTime()  方法,它返回的竟然是一个  long  值。
文档进一步又告诉我们这个值代表了当前系统的时间离 1970/1/1 0:0  的毫秒差,而且是在  GMT  时区下 ( 也被称为  EPOC) 。如果我们指定的时间是在此之前的,那它将返回一个负数值。
这个发现让我们对  Date  对象有了一个全新的认识 -Date  存放的是与  EPOC  的偏差值。换而言之我们也可通过  long  类型来表示时间?对了,这个猜想是得到了  Java  的支持:
   // 
第二种获得当前时间的方法
    long dateInMilliSeconds = System.currentTimeMillis();
    // 
这时候打印出的只是一串数字而已
    System.out.println(dateInMilliSeconds);
对程序执行效率敏感的程序员可以发现这个方法只是生成一个  Java  的原始类型  (primitive type) long,  不需要实例化一个对象。因此如果我们对时间的处理只是在内部进行时,可以用  long  来代替  Date  对象。
最典型的应用就是在一段代码开始和结束时 , 分别获得系统当前的时间 , 然后计算出代码执行所需的时间 ( 微秒级 )
   long start = System.currentTimeMillis();
    // 
代码段
    System.out.println("
需要  "+(System.currentTimeMillis()-start)+"  微秒 ");
那么当我们要把这个  long  值已更为友好的表现形式显示处理的时候,我们可以用它来构造  Date  对象:
Date date = new Date(dateInMilliSeconds);
System.out.println(date);
我们看到了在  Java  中对时间最为基本的表示,有通过对 EPOC  的偏差值进行处理。 Date  对象是对它的一个对象的封装。我们同时也看到了,在现时世界中我们对时间的描述通常是通过 " 某年某月某日某时某分 " 来定义的。 Date  的显示 ( 实际上是  toString()  方法 ) 描述了这些信息,但  Java  并不建议我们用这种方式直接来构件  Date  对象。因此我们需要找出哪个对象可以实现这个需求。这就是我们下面就要讲述的  Calendar  对象的功能。
在我们进一步研究  Calendar  之前,请记住  Date  只是一个对  long ( 基于  GMT  时区 ) 的对象封装。它所表现出来的年 // 日小时 : 分钟时区的时间表述,只是它的  toString()  方法所提供的。千万不要为这个假象所迷惑。
假如我们希望定制日期数据的格式 比方星期六 -9-29-2001 下面的例子展示了如何完成这个工作
import java.text.SimpleDateFormat; 
import java.util.Date; 
public class DateExample2 { 
public static void main(String[] args) { 
SimpleDateFormat bartDateFormat = new SimpleDateFormat("EEEE-MMMM-dd-yyyy"); Date date = new Date(); 
System.out.println(bartDateFormat.format(date)); 
}
}
只要通过向 SimpleDateFormat  的构造函数传递格式字符串 "EEE-MMMM-dd-yyyy",  我们就能够指明自己想要的格式 你应该可以看见 格式字符串中的 ASCII  字符告诉格式化函数下面显示日期数据的哪一个部分 . EEEE 是星期 , MMMM 是月 , dd 是日 , yyyy 是年 字符的个数决定了日期是如何格式化的 . 传递 "EE-MM-dd-yy" 会显示  Sat-09-29-01.  请察看 Sun  公司的 Web  站点获取日期格式化选项的完整的指示
1.3. 
文本数据解析成日期对象  
假设我们有一个文本字符串包含了一个格式化了的日期对象 而我们希望解析这个字符串并从文本日期数据创建一个日期对象 我们将再次以格式化字符串 "MM-dd-yyyy"  调用 SimpleDateFormat 但是这一次 我们使用格式化解析而不是生成一个文本日期数据 我们的例子 显示在下面 将解析文本字符串 "9-29-2001" 并创建一个值为 001736000000  的日期对象
通过 parse() 方法, DateFormat 能够以一个字符串创立一个 Date 对象。这个方法能抛出 ParseException 异常,所以你必须使用适当的异常处理技术。
例子程序
import java.text.SimpleDateFormat; 
import java.util.Date; 
public class DateExample3 { 
public static void main(String[] args) { 
// Create a date formatter that can parse dates of 
// the form MM-dd-yyyy. 
SimpleDateFormat bartDateFormat = new SimpleDateFormat("MM-dd-yyyy"); 
// Create a string containing a text date to be parsed. 
String dateStringToParse = "
9-29-2001 "; 
try { 
// Parse the text version of the date. 
// We have to perform the parse method in a 
// try-catch construct in case dateStringToParse 
// does not contain a date in the format we are expecting. 
Date date = bartDateFormat.parse(dateStringToParse); 
// Now send the parsed date as a long value 
// to the system output. 
System.out.println(date.getTime()); 
}catch (Exception ex) { 
System.out.println(ex.getMessage()); 
}


1.4. 
使用标准的日期格式化过程  
既然我们已经可以生成和解析定制的日期格式了 让我们来看一看如何使用内建的格式化过程 方法  DateFormat.getDateTimeInstance()  让我们得以用几种不同的方法获得标准的日期格式化过程 在下面的例子中 我们获取了四个内建的日期格式化过程 它们包括一个短的 中等的 长的 和完整的日期格式
import java.text.DateFormat; 
import java.util.Date; 
public class DateExample4 { 
public static void main(String[] args) { 
Date date = new Date(); 
DateFormat shortDateFormat = DateFormat.getDateTimeInstance( 
DateFormat.SHORT, DateFormat.SHORT); 
DateFormat mediumDateFormat = DateFormat.getDateTimeInstance( 
DateFormat.MEDIUM, DateFormat.MEDIUM); 
DateFormat longDateFormat = DateFormat.getDateTimeInstance( 
DateFormat.LONG, DateFormat.LONG); 
DateFormat fullDateFormat = DateFormat.getDateTimeInstance( 
DateFormat.FULL, DateFormat.FULL); 
System.out.println(shortDateFormat.format(date)); System.out.println(mediumDateFormat.format(date)); System.out.println(longDateFormat.format(date)); System.out.println(fullDateFormat.format(date)); 


注意我们在对  getDateTimeInstance 的每次调用中都传递了两个值 第一个参数是日期风格 而第二个参数是时间风格 它们都是基本数据类型 int( 整型 ).  考虑到可读性 我们使用了 DateFormat  类提供的常量 : SHORT, MEDIUM, LONG,  FULL.  要知道获取时间和日期格式化过程的更多的方法和选项 请看 Sun  公司 Web  站点上的解释
运行我们的例子程序的时候 它将向标准输出设备输出下面的内容
9/29/01 8:44 PM 
Sep 29, 2001 8:44:45 PM 
September 29, 2001 8:44:45 PM EDT 
Saturday, September 29, 2001 8:44:45 PM EDT 
2.   Calendar 
日历类  
首先请记住  Calendar  只是一个抽象类 也就是说你无法直接获得它的一个实例,换而言之你可以提供一个自己开发的  Calendar  对象。
那究竟什么是一个  Calendar  呢?中文的翻译就是日历,那我们立刻可以想到我们生活中有阳 () 历、阴 () 历之分。它们的区别在哪呢?
比如有:
月份的定义  - `()  一年 12  个月,每个月的天数各不同;阴 () 历,每个月固定 28, 每周的第一天  - () 历星期日是第一天;阴 () 历,星期一是第一天
实际上,在历史上有着许多种纪元的方法。它们的差异实在太大了,比如说一个人的生日是 " 八月八日 那么一种可能是阳 () 历的八月八日,但也可以是阴 () 历的日期。所以为了计时的统一,必需指定一个日历的选择。那现在最为普及和通用的日历就是  "Gregorian Calendar" 。也就是我们在讲述年份时常用  " 公元几几年 "Calendar  抽象类定义了足够的方法,让我们能够表述日历的规则。 Java  本身提供了对  "Gregorian Calendar"  规则的实现。我们从  Calendar.getInstance()  中所获得的实例就是一个  "GreogrianCalendar"  对象 ( 与您通过  new GregorianCalendar()  获得的结果一致 )
下面的代码可以证明这一点:
   import java.io.*;
    import java.util.*;
    public class WhatIsCalendar
    {
        public static void main(String[] args) {
            Calendar calendar = Calendar.getInstance();
            if (calendar instanceof GregorianCalendar)
                System.out.println("It is an instance of GregorianCalendar");
        }
    }
Calendar 
 Java  中是一个抽象类 (Abstract Class)GregorianCalendar  是它的一个具体实现。
Calendar 
 Date  的转换非常简单:
   Calendar calendar = Calendar.getInstance();
    // 
从一个  Calendar  对象中获取  Date  对象
    Date date = calendar.getTime();
    // 
 Date  对象反应到一个  Calendar  对象中,
    // Calendar/GregorianCalendar 
没有构造函数可以接受  Date  对象
    // 
所以我们必需先获得一个实例,然后设置  Date  对象
    calendar.setTime(date);
Calendar 
对象在使用时,有一些值得注意的事项:
1. Calendar 
 set()  方法
set(int field, int value) - 
是用来设置 "/// 小时 / 分钟 // 微秒 " 等值
field 
的定义在  Calendar 
set(int year, int month, int day, int hour, int minute, int second) 
但没有 set(int year, int month, int day, int hour, int minute, int second, int millisecond)  前面  set(int,int,int,int,int,int)  方法不会自动将  MilliSecond  清为  0
另外,月份的起始值为0而不是1,所以要设置八月时,我们用7而不是 8
calendar.set(Calendar.MONTH, 7);
我们通常需要在程序逻辑中将它清为  0 ,否则可能会出现下面的情况:
   import java.io.*;
    import java.util.*;
    public class WhatIsCalendarWrite
    {
        public static void main(String[] args) throws Exception{
            ObjectOutputStream out =
                new ObjectOutputStream(
                    new FileOutputStream("calendar.out"));
            Calendar cal1 = Calendar.getInstance();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值