标签:
最近在无聊的看书,遇到一编程题目,问题描述如下: 黑色星期五源于西方迷信:耶稣基督死于星期五,而13也是一个不吉利的数字。黑色星期五即该日同时是星期五又是13号,求未来几年内这样的日子。 基于该问题会涉及到java中的关于时间类的部分,故尝试通过该题目总结现阶段的java Date和calendar类的问题。 一、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 ,分别表示系统当期星期、月份、时间、时区、年份。
查看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
中的相应方法已废弃。
二、DateFormat类
查看该类的API文档可知该类抽象,无法创建创建对象,但其子类SimpleDateFormat类继承该类。
三、SimpleDateFormat类
java面向对象强调封装,将多种操作的方法封装至一类中,如果该类所代表的事务能够关联其操作方法时。此处体现在于java将日期类的格式化的所有操作封装至一类DateFormat中,并由其子类SimpleDateFormat实现所有操作方法。
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
字符串pattern表示格式化的要求格式,将要求格式通过SimpleDateFormat的构造函数传入再通过调用format方法格式Date类的对象,从而得到所需要的类型。
当然,针对于SimpleDateFormat类,也可以调用applyPattern将要求格式传递给sdf。
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
四、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
标签:
原文地址:http://www.cnblogs.com/yidiudiu/p/5059934.html