java Date和Calendar类

最近在无聊的看书,遇到一编程题目,问题描述以下:
 黑色星期五源于西方迷信:耶稣基督死于星期五,而13也是一个不吉利的数字。黑色星期五即该日同时是星期五又是13号,求将来几年内这样的日子。
基于该问题会涉及到java中的关于时间类的部分,故尝试经过该题目总结现阶段的java Date和calendar类的问题。
1、Date类
  查阅API文档可知,Date类源于jdk1.0版本,并在jdk1.1版本中其绝大多数方法被Calendar类中方法所代替。Date类构造函数public且未abstrct,故能够建立Date对象。
    public static void main(String[] args) {
	    Date date = new Date();
	    System.out.println(date);
    }

   运行结果为:Sat Dec 19 21:46:14 CST 2015 ,分别表示系统当期星期、月份、时间、时区、年份。java

   查看Date类构造函数源码以下,大体可了解到Date初始化获取时间戳,即系统当前时间与1970年01月01日00时00分00秒的差值,从而获取系统当前日期。编程

    public Date() {
         this(System.currentTimeMillis());
    }
    public Date(long date) {
           fastTime = date;
      }
    private transient long fastTime;

 

  依据API文档对该类介绍,可大体了解到其因为java虚拟机d主机环境没法准确描述时间,从 JDK 1.1 开始,应该使用 Calendar 类实现日期和时间字段之间转换,使用 DateFormat 类来格式化和解析日期字符串。Date 中的相应方法已废弃。app

 2、DateFormat类函数

  查看该类的API文档可知该类抽象,没法建立建立对象,但其子类SimpleDateFormat类继承该类。this

 3、SimpleDateFormat类设计

  java面向对象强调封装,将多种操做的方法封装至一类中,若是该类所表明的事务可以关联其操做方法时。此处体如今于java将日期类的格式化的全部操做封装至一类DateFormat中,并由其子类SimpleDateFormat实现全部操做方法。code

	public static void main(String[] args){
		Date date = new Date();
		String pattern = "yyyy-MM-dd";
		SimpleDateFormat sdf = new SimpleDateFormat(pattern);
		String time = sdf.format(date);
		System.out.println(time);
	}
    

  运行结果:2015-12-19   orm

  字符串pattern表示格式化的要求格式,将要求格式经过SimpleDateFormat的构造函数传入再经过调用format方法格式Date类的对象,从而获得所须要的类型。对象

  固然,针对于SimpleDateFormat类,也能够调用applyPattern将要求格式传递给sdf。  blog

      public void applyPattern(String pattern) {
            applyPatternImpl(pattern);
      }

      private void applyPatternImpl(String pattern) {
            compiledPattern = compile(pattern);
            this.pattern = pattern;
      }

  源码说明,applyPattern将要求格式pattern传递给类全局变量pattern。

  格式pattern的值则能够依据下表根据需求而定(注意大小写区别):

    字母 	日期或时间元素 	表示 	示例
    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

  4、Calendar类

  Calendar类也是抽象类,可使用其具体实现的子类GregorianCalendar建立子类对象来实现日期与时间字段间的转换。查看Calendar类,其构造函数protected,绝大多数方法使用static修饰,使用单例模式设计而成,getInstance方法返回该类的对象。 

      public static Calendar getInstance() {
            return createCalendar(TimeZone.getDefault(), Locale.getDefault(Locale.Category.FORMAT));
      }

   使用该方法获取对象后打印以下:

	public static void main(String[] args){
		Calendar cal = Calendar.getInstance();
		System.out.println(cal);
	}

   打印结果:

    java.util.GregorianCalendar[time=1450573269561,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Chongqing",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2015,MONTH=11,WEEK_OF_YEAR=52,WEEK_OF_MONTH=4,DAY_OF_MONTH=20,DAY_OF_YEAR=354,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=3,AM_PM=0,HOUR=9,HOUR_OF_DAY=9,MINUTE=1,SECOND=9,MILLISECOND=561,ZONE_OFFSET=28800000,DST_OFFSET=0]

   该类对象内以键值对形式封装了全部日期时间类信息,与Date类相比,信息更丰富完整。使用Calendar的字段属性可快速得到所对应的键值。    

	public static void main(String[] args){
		Calendar cal = Calendar.getInstance();
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH)+1;//月份从0开始计算
		int day = cal.get(Calendar.DAY_OF_MONTH);
		int week = cal.get(Calendar.DAY_OF_WEEK);//星期日默认星期开始第一天
		System.out.println(year+"-"+month+"-"+day+":"+week);
	}

   运行结果:2015-12-20:1

   除了获取当前时间外,Calendar还能够设置当前时间,和时间的自动加减。设置时间以下:

	public static void main(String[] args){
		Calendar cal = Calendar.getInstance();	
		cal.set(Calendar.YEAR, 2012);
		cal.set(Calendar.MONTH, 0);
		cal.set(Calendar.DAY_OF_MONTH,13);
		
		
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH)+1;
		int day = cal.get(Calendar.DAY_OF_MONTH);
		int week = cal.get(Calendar.DAY_OF_WEEK);
		System.out.println(year+"-"+month+"-"+day+":"+week);
	}

   运行结果:2012-1-13:6

	public static void main(String[] args){
		Calendar cal = Calendar.getInstance();	
		cal.set(Calendar.YEAR, 2012);
		cal.set(Calendar.MONTH, 0);
		cal.set(Calendar.DAY_OF_MONTH,13);
		
		
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH)+1;
		int day = cal.get(Calendar.DAY_OF_MONTH);
		int week = cal.get(Calendar.DAY_OF_WEEK);
		
		cal.add(Calendar.MONTH, 1);
		year = cal.get(Calendar.YEAR);
		month = cal.get(Calendar.MONTH)+1;
		day = cal.get(Calendar.DAY_OF_MONTH);
		week = cal.get(Calendar.DAY_OF_WEEK);
		
		System.out.println(year+"-"+month+"-"+day+":"+week);
	}

   运行结果:2012-2-13:2
   Cal.add(calendar.MONTH, 1)会实现month月份自动加一,且其增长会致使YEAR进位,即满十二进一。

  故黑色星期五的解法可以下:

	public static void method(){
		Calendar cal = Calendar.getInstance();	
		cal.set(Calendar.YEAR, 2012);
		cal.set(Calendar.MONTH, 0);
		cal.set(Calendar.DAY_OF_MONTH,13);
				
		int year = cal.get(Calendar.YEAR);
		int month = cal.get(Calendar.MONTH)+1;
		int day = cal.get(Calendar.DAY_OF_MONTH);
		int week = cal.get(Calendar.DAY_OF_WEEK);
		while(year < 2017){
			if(week == 6){
				System.out.println(year+"-"+month+"-"+day);
			}
//			month++;
			cal.add(Calendar.MONTH, 1);
			year = cal.get(Calendar.YEAR);
			month = cal.get(Calendar.MONTH)+1;
			day = cal.get(Calendar.DAY_OF_MONTH);
			week = cal.get(Calendar.DAY_OF_WEEK);
		}
//		System.out.println(year +" "+ month+" "+ day+" "+week);
		
	}

   运行结果:

      2012-1-13
      2012-4-13
      2012-7-13
      2013-9-13
      2013-12-13
      2014-6-13
      2015-2-13
      2015-3-13
      2015-11-13
      2016-5-13
相关文章
相关标签/搜索