java里的日期时间
为了更好理解java的日期时间类,在这里我们先介绍一下关于历法、标准时间的一些概念。
历法有很多种,我们大中华上下五千年,自然也有自己的历法,生活中我们通常把自己传统的历法叫做农历,也有人叫它阴历或夏历。注意,这个“夏历”的“夏”和“夏令时间”的“夏”不是一个含义。“夏历”的“夏”是夏朝的“夏”,因为据说我们现在使用的这套农历在我国上古时期的夏朝时就已经发展得很完备了。
当然了,不只是中国有自己的历法,很多民族很多古文明国家都有过自己的历法。比如,格里高里历,它其实就是我们生活中使用和称作阳历或公历的这套历法。格里高利历是公历的标准名称,是一种源自于西方社会的历法。它先由意大利阿洛伊修斯·里利乌斯(约1519-1576)与克拉乌等学者在儒略历的基础上加以改革,后由教皇格里高利十三世于1582年颁布。我国是在辛亥革命后根据临时政府通电,从1912年1月1日正式使用格里高利历的。1949年9月27日,经中国人民政治协商会议第一届全体会议通过,中华人民共和国使用国际社会多数国家通用的西历和西元作为历法和纪年。
标准时间(Standard Time)有世界标准时间(World Standard Time,WST)和中国标准时间(China Standard Time,CST)。中国标准时间就是我们经常提到的北京时间,北京时间采用东八时区的区时作为标准时间。而世界标准时间即格林威治时间(GreenwichMeanTime,GMT),指位于英国伦敦郊区的皇家格林尼治天文台(1675年,当时,英国的航海事业发展很快,为了解决在海上测定经度的需要,英国当局在伦敦东南郊距市中心约20多千米,泰晤士河畔的皇家格林尼治花园中建立了这个天文台)的标准时间,本初子午线就被定义在那里,格林尼治标准时间的正午是指当太阳横穿格林尼治本初子午线时的时间。北京时间(中国标准时间)和格林威治时间(世界标准时间)相差整整八小时,即北京时间=格林威治时间+8小时。北京时间,东京时间,纽约时间这些标准时间都是在格林威治时间的基础上计算得来的。
java类库里有一个GregorianCalendar类,就是我们的格里高利历法类,它用这个类代表或者说包装了格里高利历法。因为GregorianCalendar这个类还和上面提到的儒略历也有关系,所以接下来我们把格里高利历和儒略历的关系也简单介绍一下。
儒略历是格里高利历(公历)的前身,于公元前46年,由当时的罗马统帅儒略·恺撒在天文学家索西琴尼的帮助下制订并执行。儒略历以回归年为基本单位,是一部纯粹的阳历,它比回归年365.2422日长0.0078日,400年要多出3.12日。1500年后由于误差较大,被罗马教皇格里高利十三世于1582年进行改善与修订,变为格里历,即沿用至今的世界通用的公历。格里高利历的历年平均长度为365日5时49分12秒,比回归年长26秒,虽然照此计算,3000年后仍存在1天的误差,但这样的精确度已经相当了不起了。由于它内容简洁,而且精度较高,因此它逐步为各国政府所采用。
注意:格里高利历1582年10月4日之前,应用的是儒略历。
1582年3月1日,格里高利颁发了改历命令,内容是:
一、1582年10月4日后的一天是10月15日,而不是10月5日,但星期序号仍然连续计算,10月4日是星期四,第二天10月15日是星期五。这样,就把1500年以来积累的老账一笔勾销了。
二、改闰年方法为: 凡公元年数能被4整除的是闰年,但当公元年数后边是带两个“0”的“世纪年”时,必须能被400整除的年才是闰年。
进入主题!!!
java里有一个Calendar抽象类(历法抽象类),其常用的实现类为GregorianCalendar类(格里高利历法类)。
注意java里的GregorianCalendar类在1582年10月4日之前,应用的也是儒略历。我们可以通过代码运用反证法来验证,我们知道,在格里高利历和儒略历的体系里是没有1582年10月5日、6日、7日这几个日期的,那我们就故意给java的GregorianCalendar类的对象赋值为1582年10月7日,看看它运行的结果到底是什么样子的?
1 import java.text.ParseException; 2 import java.text.SimpleDateFormat; 3 import java.util.Date; 4 5 public class JulianCalendar { 6 public static void main(String[] args) throws ParseException { 7 String str = "1582-10-07 00:00:00"; 8 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 9 Date date = sdf.parse(str); 10 System.out.println(date); 11 } 12 }
1 Sun Oct 17 00:00:00 CST 1582
从上面的代码运行结果看,我们肯定地得出结论,java的GregorianCalendar类包装的是格里高利历法和儒略历法。
如果我们想要实例化Calendar类,可以调用其静态方法getInstance(),该方法会根据当前系统所在地区返回一个实现类,大部分地区都是公历,即GregorianCalendar类。并且这个GregorianCalendar实现类默认表示当前系统时间,也就是windows操作系统桌面右下角的时间,对于我们来说就是阳历北京时间某年某月某日某时某分某秒……
1 import java.util.Calendar; 2 3 public class CalendarDemo { 4 public static void main(String[] args) { 5 Calendar calendar = Calendar.getInstance(); 6 System.out.println(calendar); 7 } 8 }
java.util.GregorianCalendar[time=1490616294512,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2017,MONTH=2,WEEK_OF_YEAR=13,WEEK_OF_MONTH=5,DAY_OF_MONTH=27,DAY_OF_YEAR=86,DAY_OF_WEEK=2,DAY_OF_WEEK_IN_MONTH=4,AM_PM=1,HOUR=8,HOUR_OF_DAY=20,MINUTE=4,SECOND=54,MILLISECOND=512,ZONE_OFFSET=28800000,DST_OFFSET=0]
我们看到Calendar类的toString()方法包含的内容很多,但可读性不强。
所以这个时候我们需要用到Calendar类的另外一个方法,getTime()方法,这个方法返回的是一个Date类的对象。
1 import java.util.Calendar;
2 import java.util.Date;
3
4 public class CalendarDemo {
5 public static void main(String[] args) {
6 Calendar calendar = Calendar.getInstance();
7 Date date = calendar.getTime();
8 System.out.println(date);
9 }
10 }
1 Mon Mar 27 19:38:40 CST 2017
这个格式好多了,但它也不是我们大多数时候习惯的格式。
这时可以使用JDK里的另外一个类SimpleDateFormat,该类可以按照一个指定的自定义日期格式将Date与String之间进行相互转换,通过它我们可以得到想要的任何格式的日期表现形式。
1 public class CalendarDemo { 2 public static void main(String[] args) { 3 Calendar calendar = Calendar.getInstance(); 4 Date date = calendar.getTime(); 5 SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 6 String str = sdf.format(date); 7 System.out.println(str); 8 } 9 }
1 2017-03-27 20:19:15