当前位置: 代码迷 >> 综合 >> Date的使用(SimpleDateFormat,DateFormat)
  详细解决方案

Date的使用(SimpleDateFormat,DateFormat)

热度:26   发布时间:2023-11-01 14:39:18.0
public class Date
extends Object
implements Serializable, Cloneable, Comparable<Date>

Date类的使用

在JDK 1.1之前, Date有两个附加功能。 它允许将日期解释为年,月,日,小时,分钟和第二个值。 它还允许格式化和解析日期字符串。 不幸的是,这些功能的API不适合国际化。 从JDK 1.1开始, Calendar类应该用于在日期和时间字段之间进行转换,并且DateFormat类应用于格式化和解析日期字符串。 在相应的方法Date被弃用。

尽管Date类旨在反映协调的世界时间(UTC),但根据Java虚拟机的主机环境的不同,可能不会这样做。 几乎所有的现代操作系统都假设在所有情况下1天= 24×60×60 = 86400秒。 然而,在UTC的时候,大概每一两年会有一秒钟的时间,叫做“闰秒”。 闰秒总是作为一天的最后一秒,总是在12月31日或6月30日。例如,1995年的最后一分钟是61秒,由于增加了闰秒。 大多数计算机时钟不够准确,不能反映出闰秒的区别。

一些计算机标准是根据格林尼治标准时间(GMT)定义的,相当于世界时间(UT)。 GMT是标准的“民用”名称; UT是同一标准的“科学”名称。 UTC和UT之间的区别是UTC是基于原子钟,UT是基于天文观测,对于所有的实际目的来说,这是一个看不见的细毛。 因为地球的旋转不均匀(减速并以复杂的方式加速),UT并不总是均匀地流动。 根据需要,将时差引入到UTC中,以使UT在UT1的0.9秒内保持UTC,这是UT的版本,并应用了某些修正。 还有其他的时间和日期系统; 例如,基于卫星的全球定位系统(GPS)使用的时间尺度与UTC同步,但不对闰秒进行调整。

在类的所有方法Date接收或返回年,月,日,小时,分钟和秒值,以下表述中使用:

  • y年代表整数y - 1900 。
  • 一个月由0到11的整数表示; 0是1月,1是2月,等等; 11月12日。
  • 日期(月的一天)以通常的方式从1到31的整数表示。
  • 一小时由0到23之间的整数表示。因此,从午夜到凌晨1点的时间是小时0,从中午到下午1点的小时是12小时。
  • 一般以0?59的整数表示。
  • 第二个由0到61的整数表示; 值60和61仅发生在闰秒上,甚至仅在实际上正确跟踪闰秒的Java实现中发生。 由于目前引入闰秒的方式,在同一分钟内不会发生两个闰秒,但是本规范遵循ISO C的日期和时间约定。

在所有情况下,为这些目的而提供的方法的论证不必在指定范围内; 例如,可以将日期指定为1月32日,并将其解释为2月1日。

public class GetTime {
//调用系统内部的时间格式;public static void main(String[] args) {Date date=new Date();System.out.println("默认时间的格式:"+date);System.out.println("两位24小时制的小时:"+String.format("%tH", date));System.out.println("两位12小时制的小时:"+String.format("%tl", date));System.out.println("24制的小时:"+String.format("%tk", date));System.out.println("12制的小时:"+String.format("%tl", date));System.out.println("两位小时中的分钟:"+String.format("%tM", date));System.out.println("两位分钟的中秒:"+String.format("%tS", date));System.out.println("表示时区缩写形式:"+String.format("%tZ", date));System.out.println("上午还是下午:"+String.format("%tp", date));System.out.println("日期时间组合格式化:");System.out.println("默认时间的格式:"+date);System.out.println("24小时制的时间,被格式化为小时和分钟:"+String.format("%tR", date));System.out.println("24小时制的时间,被格式化为小时和分钟,秒"+String.format("%tT", date));System.out.println("12制的时间:"+String.format("%tr", date));System.out.println("日期被格式化:"+String.format("%tD", date));System.out.println("ISO 8601格式的完整日期:"+String.format("%tF", date));System.out.println("日期和时间格式化为:"+String.format("%tc", date));}}
//调用系统内部的 一些方式:public static void main(String[] args) {Date today=new Date();String a=String.format(Locale.US, "%tb", today);String b=String.format(Locale.US, "%tB", today);String c=String.format("%ta", today);//指定语言中的星期几的简称String d=String.format("%tA", today);//指定语言中的星期几的全称String e=String.format("%tY", today);//四位年份String f=String.format("%ty", today);//两位年份String g=String.format("%tm", today);//月份String h=String.format("%td", today);//一个月中的第几天String i=String.format("%te", today);//一个月中的某一天String k=String.format("%tc", today);//包括全部的日期和时间String l=String.format("%tj", today);//一年中的第几天System.out.println("格式化后的字符串的英文缩写:"+a);System.out.println("格式化后的字符串的英文全写:"+b);System.out.println("月格式化后的字符串为星期:"+c);System.out.println("格式化后的字符串为星期:"+d);System.out.println("格式化后的字符串为4位的年份值:"+e);System.out.println("格式化后的字符串为4位的年份值:"+f);System.out.println("格式化后的字符串为2位的月份值:"+g);System.out.println("格式化后的字符串为2位的日期值:"+h);System.out.println("格式化后的字符串为1位的日期值:"+i);System.out.println("日期值:"+k);System.out.println("当年中的第几天:"+l);}

日期比较

Java使用以下三种方法来比较两个日期:

  • 使用 getTime() 方法获取两个日期(自1970年1月1日经历的毫秒数值),然后比较这两个值。
  • 使用方法 before(),after() 和 equals()。例如,一个月的12号比18号早,则 new Date(99, 2, 12).before(new Date (99, 2, 18)) 返回true。
  • 使用 compareTo() 方法,它是由 Comparable 接口定义的,Date 类实现了这个接口。

DateFormat类:

DateFormat是日期/时间格式化子类的抽象类,它以语言无关的方式格式化和分析日期或时间。 日期/时间格式化子类(如SimpleDateFormat )允许格式化(即日期文本),解析(文本日期)和归一化。 该日期表示为一个Date对象,或自1970年1月1日00:00:00 GMT以来的毫秒。

DateFormat提供了许多类方法,用于根据默认或给定的区域设置和多个格式化样式获取默认的日期/时间格式化程序。 格式化风格包括FULL , LONG , MEDIUMSHORT 。 方法说明中提供了更多细节和使用这些样式的示例。

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获取日期和时间格式。 您可以将不同的选项传递给这些工厂方法来控制结果的长度; 从SHORTMEDIUMLONGFULL 。 确切的结果取决于语言环境,但通常是:

  • SHORT是完全数字的,如12.13.523:30pm
  • MEDIUM较长,如Jan 12, 1952
  • LONG较长,如January 12, 19523:30:32pm
  • FULL是完全指定的,如Tuesday, April 12, 1952 AD or 3:30:42pm PST 。

您也可以根据需要设置格式的时区。 如果你想在格式或分析更精确的控制,(或者希望给用户更多的控制),可以尝试铸造DateFormat你从工厂方法到获得SimpleDateFormat 。 这将适用于大多数国家; 只要记住把它放在一个try块中,以防万一你遇到不寻常的一个。

以下代码是对这些的简单使用具体的可以查看API:

public static void main(String[] args) {Date p=new Date();p.getTime();//System.out.println(p.getTime());
//date Format类
//		美式
//		 日期DateFormat df1=DateFormat.getDateInstance();String string=df1.format(new Date());System.out.println(string);
//		日期和时间一起显示精确到秒DateFormat df2=DateFormat.getDateTimeInstance();System.out.println(df2.format(new Date()));
//		中式
//		年日期DateFormat df3=DateFormat.getDateInstance(DateFormat.YEAR_FIELD,new Locale("zh","CN"));System.out.println(df3.format(new Date()));
//		年月日上下午秒DateFormat df4=DateFormat.getDateTimeInstance(DateFormat.YEAR_FIELD,DateFormat.ERA_FIELD,new Locale("zh","CN"));System.out.println(df4.format(new Date()));
//		simpleDateFormate类Date now=new Date();String s="北京时间:yyy年MM月dd日,E,HH:mm:ss";SimpleDateFormat f=new SimpleDateFormat(s);System.out.println(f.format(now));}

SimpleDateFormat:

SimpleDateFormat是一个具体的类,用于以区域设置敏感的方式格式化和解析日期。 它允许格式化(日期文本),解析(文本日期)和归一化。

SimpleDateFormat允许您从选择日期时间格式化的任何用户定义的模式开始。 不过,建议您创建一个日期-时间格式有两种getTimeInstance , getDateInstance ,或getDateTimeInstanceDateFormat 。 这些类方法中的每一个都可以返回使用默认格式模式初始化的日期/时间格式化程序。 您可以根据需要使用applyPattern方法修改格式模式。 有关使用这些方法的更多信息,请参见DateFormat 。

日期和时间模式

日期和时间格式由日期和时间模式字符串指定。 在日期和时间模式字符串中,从'A''Z'和从'a''z'的非引号的字母被解释为表示日期或时间字符串的组件的模式字母。 可以使用单引号( ' )引用文本,以避免解释。 "''"代表单引号。 所有其他字符不被解释; 在格式化过程中,它们只是复制到输出字符串中,或者在解析过程中与输入字符串匹配。

定义了以下图案字母(所有其他字符从'A''Z'和从'a''z'被保留):

Letter Date or Time Component Presentation Examples
G Era designator Text AD
y Year Year 199696
Y Week year Year 200909
M Month in year (context sensitive) Month JulyJul07
L Month in year (standalone form) Month JulyJul07
w Week in year Number 27
W Week in month Number 2
D Day in year Number 189
d Day in month Number 10
F Day of week in month Number 2
E Day name in week Text TuesdayTue
u Day number of week (1 = Monday, ..., 7 = Sunday) Number 1
a Am/pm marker Text PM
H Hour in day (0-23) Number 0
k Hour in day (1-24) Number 24
K Hour in am/pm (0-11) Number 0
h Hour in am/pm (1-12) Number 12
m Minute in hour Number 30
s Second in minute Number 55
S Millisecond Number 978
z Time zone General time zone Pacific Standard TimePSTGMT-08:00
Z Time zone RFC 822 time zone -0800
X Time zone ISO 8601 time zone -08-0800-08:00

模式字母通常重复,因为它们的数字确定了准确的表示:

  • Text:对于格式化,如果模式字母的数量是4以上,则使用完整的形式; 否则,如果有的话,使用简短或缩写形式。 对于解析,两种形式都是接受的,与模式字母的数量无关。 
     
  • Number:对于格式化,模式字母的数量是最小位数,而较短的数字将零填充到此数量。 对于解析,模式字母的数量将被忽略,除非需要分隔两个相邻的字段。 
     
  • Year:如果格式化程序的Calendar是公历,则应用以下规则。 
    • 对于格式化,如果模式字母数为2,那么年份将被截断为2位数; 否则被解释为number 。
    • 对于解析,如果模式字母的数量大于2,则年份将按字面解释,而不管数字的数量。 所以使用“MM / dd / yyyy”模式,“01/11/12”解析到公元12年1月11日
    • 为了使用缩写年份模式(“y”或“yy”)进行解析, SimpleDateFormat必须解释相对于某个世纪的缩写年份。 它是通过将日期调整为在创建SimpleDateFormat实例之后的80年之前和20年之后进行的。 例如,使用1997年1月1日创建的“MM / dd / yy”模式和SimpleDateFormat实例,字符串“01/11/12”将被解释为2012年1月11日,而字符串“05/04 / 64“将被解释为1964年5月4日。在解析期间,只有由Character.isDigit(char)定义的两个数字组成的字符串将被解析为默认世纪。 任何其他数字字符串,例如一位数字字符串,三位或三位以上数字字符串,或两位数字字符串(不全部为数字)(例如“-1”),均按字面解释。 所以“01/02/3”或“01/02/003”的解析方式与公元3年1月2日相同。 同样,“01/02 / -3”在公元前4年1月2日被解析。
    否则,将应用日历系统特定的表单。 对于格式化和解析两者,如果模式字母数为4以上,则使用特定日历long form 。 否则,使用一个特定日历short or abbreviated form 。 

    如果周年'Y'被指定,并且calendar不支持任何week years ,则使用日历年( 'y' )。 可以通过致电getCalendar()测试周年的支持。 isWeekDateSupported() 。 
     
  • Month:如果模式字母数为3以上,则该月份被解释为text ; 否则,它被解释为number 。 
    • 字母M产生上下文相关的月份名称,例如嵌入的名称形式。 如果DateFormatSymbols已经与构造明确设置SimpleDateFormat(String, DateFormatSymbols)或方法setDateFormatSymbols(DateFormatSymbols) ,由给定月份名称DateFormatSymbols被使用。
    • L字母生成独立形式的月份名称。
  • General time zone:如果他们有姓名,时区将被解释为text 。 对于表示GMT偏移值的时区,

SimpleDateFormat还支持本地化的日期和时间模式字符串。 在这些字符串中,上述的图案字母可以被替换为其他与区域相关的图案字母。 SimpleDateFormat不处理除图案字母之外的文本的本地化;这取决于课堂的客户。

例子

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

Date and Time Pattern Result
"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-04T12:08:56.235-0700
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX" 2001-07-04T12:08:56.235-07:00
"YYYY-'W'ww-u" 2001-W27-3

Synchronization

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

Calendar类

我们现在已经能够格式化并创建一个日期对象了,但是我们如何才能设置和获取日期数据的特定部分呢,比如说小时,日,或者分钟? 我们又如何在日期的这些部分加上或者减去值呢? 答案是使用Calendar 类。

Calendar类的功能要比Date类强大很多,而且在实现方式上也比Date类要复杂一些。

Calendar类是一个抽象类,在实际使用时实现特定的子类的对象,创建对象的过程对程序员来说是透明的,只需要使用getInstance方法创建即可。

创建一个代表系统当前日期的Calendar对象

Calendar c = Calendar.getInstance();//默认是当前日期

创建一个指定日期的Calendar对象

使用Calendar类代表特定的时间,需要首先创建一个Calendar的对象,然后再设定该对象中的年月日参数来完成。

//创建一个代表2009年6月12日的Calendar对象
Calendar c1 = Calendar.getInstance();
c1.set(2009, 6 - 1, 12);

Calendar类对象字段类型

Calendar类中用以下这些常量表示不同的意义,jdk内的很多类其实都是采用的这种思想

常量 描述
Calendar.YEAR 年份
Calendar.MONTH 月份
Calendar.DATE 日期
Calendar.DAY_OF_MONTH 日期,和上面的字段意义完全相同
Calendar.HOUR 12小时制的小时
Calendar.HOUR_OF_DAY 24小时制的小时
Calendar.MINUTE 分钟
Calendar.SECOND
Calendar.DAY_OF_WEEK 星期几

Calendar类对象信息的设置

Set设置

如:

Calendar c1 = Calendar.getInstance();

调用:

public final void set(int year,int month,int date)
c1.set(2009, 6, 12);//把Calendar对象c1的年月日分别设这为:2009、6、12

利用字段类型设置

如果只设定某个字段,例如日期的值,则可以使用如下set方法:

public void set(int field,int value)

把 c1对象代表的日期设置为10号,其它所有的数值会被重新计算

c1.set(Calendar.DATE,10);

把c1对象代表的年份设置为2008年,其他的所有数值会被重新计算

c1.set(Calendar.YEAR,2008);

其他字段属性set的意义以此类推

Add设置

Calendar c1 = Calendar.getInstance();

把c1对象的日期加上10,也就是c1也就表示为10天后的日期,其它所有的数值会被重新计算

c1.add(Calendar.DATE, 10);

把c1对象的日期减去10,也就是c1也就表示为10天前的日期,其它所有的数值会被重新计算

c1.add(Calendar.DATE, -10);

其他字段属性的add的意义以此类推

Calendar类对象信息的获得

Calendar c1 = Calendar.getInstance(); // 获得年份 int year = c1.get(Calendar.YEAR); // 获得月份 int month = c1.get(Calendar.MONTH) + 1; // 获得日期 int date = c1.get(Calendar.DATE); // 获得小时 int hour = c1.get(Calendar.HOUR_OF_DAY); // 获得分钟 int minute = c1.get(Calendar.MINUTE); // 获得秒 int second = c1.get(Calendar.SECOND); // 获得星期几(注意(这个与Date类是不同的):1代表星期日、2代表星期1、3代表星期二,以此类推) int day = c1.get(Calendar.DAY_OF_WEEK);

这里主要是进行对API的回顾基本上不涉及什么具体的编程思想和面向对象的特殊思想。。。

  相关解决方案