最近在无聊的看书,遇到一编程题目,问题描述以下: 黑色星期五源于西方迷信:耶稣基督死于星期五,而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