认识时间与日期
时间的度量
- 格林威治标准时间:GMT,通过观察太阳而得
- 世界时:UT,通过观测远方星体跨过子午线而得
- 国际原子时:TAI,将秒定义为铯原子辐射振动9192631770周耗费的时间,时间从UT的1958年开始同步
- 世界协调时间:UTC,采用了闰秒修正
- Unix时间:用以表达时间轴上某一瞬间
- epoch:某个特定时代的开始,时间轴上某一瞬间
实际上谈到时间指的是UTC时间
秒的单位定义是基于TAI,也就是铯原子辐射振动次数
UTC考虑了地球自转越来越慢而有闰秒修正
Unix时间是1970.1.1.00:00:00为起点经过的秒数,不考虑闰秒
年历简介
- 儒略历:修正了罗马历三年设置一闰年的错误,改为四年一闰
- 格里高利历:改革了儒略历
- ISO 8601标准:用以统一时间日期的数据交换格式
认识时区:
为了让人们对时间的认知符合作息,因而设置了UTC偏移,大致来说,经度每15度是偏移一小时,考虑了UTC偏移的时间表示上,通常会标识Z符号
认识Date与Calendar
时间轴上瞬间的Date
取得系统时间的方法之一是使用System.currentTimeMills()方法,返回long类型整数,该方法取得的是机器的时间观点,代表时间轴上某一瞬间,但是却不是人类的时间观点,因此有人会使用Date实例来取得系统时间描述,不过Date也是偏向机器的时间观点。
import java.util.*;
import static java.lang.System.*;
public class DateDemo {
public static void main(String[] args) {
Date date1 = new Date(currentTimeMillis());
Date date2 = new Date();
out.println(date1.getTime());
out.println(date2.getTime());
}
}
从代码中可以看出,Date有两个构造函数可用,一个用epoch毫秒数构建,另一个不用自变量构建,但其内部也是使用System.currentTimeMillis()取得epoch毫秒数,调用getTime()可取得内部保存的epoch毫秒数值。
格式化时间日期的DateFormat
因为Date实例基本上建议只用来当作时间轴上的某一瞬间,所以有关字符串时间格式的处理,都交给java.text.DateFormat,DateFormat是个抽象类,其操作类是java.text.SimpleDateFormat,可以直接构建SimpleDateFormat实例,或使用DateFormat的getDateInstance()、getTimeInstance()、getDateTimeInstance()等静态方法,用不同需求取得SimpleDateFormat实例。
import java.util.*;
import static java.lang.System.out;
import static java.text.DateFormat.*;
public class DateFormatDemo {
public static void main(String[] args) {
Date date = new Date();
dateInstanceDemo(date);
timeInstanceDemo(date);
dateTimeInstanceDemo(date);
}
static void dateInstanceDemo(Date date) {
out.println("getDateInstance() demo");
out.printf("\tSHORT: %s%n",getDateInstance(LONG).format(date));
out.printf("\tSHORT: %s%n",getDateInstance(SHORT).format(date));
}
static void timeInstanceDemo(Date date) {
out.println("getTimeInstance() demo");
out.printf("\tLONG: %s%n",getTimeInstance(LONG).format(date));
out.printf("\tMEDIUM: %s%n",getTimeInstance(MEDIUM).format(date));
out.printf("\tSHORT: %s%n",getTimeInstance(SHORT).format(date));
}
static void dateTimeInstanceDemo(Date date) {
out.println("getDateTimeInstance() demo");
out.printf("\tLONG:%s%n",getDateTimeInstance(LONG,LONG).format(date));
out.printf("\tMEDIUM:%s%n",getDateTimeInstance(SHORT,MEDIUM).format(date));
out.printf("\tSHORT:%s%n",getDateTimeInstance(SHORT,SHORT).format(date));
}
}
这三种静态方法主要是取得了不同详细程度的日期时间,用到了重载。
而直接构建SimpleDateFormat的好处是可使用模式字符串自定义格式。
import java.text.*;
import java.util.*;
public class CurrentTime {
public static void main(String[] args) {
DateFormat dateFormat = new SimpleDateFormat(args.length == 0 ? "EE-MM-dd-yyyy" : args[0]);
System.out.println(dateFormat.format(new Date()));
}
}
DateFormat可进行日期时间格式化,java.text.NumberFormat可用来进行数字格式化,都是java.text.Format子类。
处理时间日期的Calendar
如果要取得某个时间日期信息或者对时间日期进行操作,可以使用Calendar实例。Calendar是个抽象类,java.util.GregorianCalendar是其子类。通过Calendar的getInstance()取得的Calendar实例,默认就是取得GregorianCalendar实例。
Calendar calendar = Calendar.getInstance();
取得Calendar实例后,可以使用getTime()取得Date实例,如果想要取得年月日等日期时间字段,可以使用get方法并指定Calendar上的字段枚举常数。Calendar.get(Calendar.MONTH)取得的月份对应的是Calendar在月份上的列举值,列举值的一月从0开始。
设定字段也应该使用Calendar:
Calendar calendar = Calendar.getInstance();
calendar.set(2014,Calendar.MAY,26); 2014//5/26
out.println(calendar.get(Calendar.MONTH)); //4
在取得一个Calendar实例后,可以使用add()方法来改变Calendar的时间。
calendar.add(Calendar.MONTH,1); //加一个月
calendar.add(Calendar.HOUR,3); //加三个小时
calendar.add(Calendar.YEAR,-2); //减两年
calendar.add(Calendar.DATE,3); //加三天
只针对某个日期中某个字段加减,则可以使用roll()方法,只处理某字段
calendar.roll(Calendar.DATE,1);
比较时间日期先后可以使用after()或before()。
设定TimeZone
可以使用java.util.TimeZone的getDefault()来取得默认时区信息。
TimeZone timeZone = TimeZone.getDefault();
out.println(timeZone.getDisplayName());
out.println("\t 时区ID:" + timeZone.getID());
out.println("\t 日光节约时数:" + timeZone.getDSTSavings());
out.println("\t UTC偏移毫秒数:" + timeZone.getRawOffset());
指定时区:
TimeZone taipeiTz = TimeZone.getTimeZone("Asia/Taipei");