1.TimeZone
TimeZone的作用1是用于代表时区,其内部存储的是所创时区和GMT的时差,所以TimeZone能获得和GMT的时差
TimeZone的作用2是计算夏令时,这个我也不太清楚
2.Locale
这个在javadoc中的解释如下:
Locale对象表示特定的地理、政治或文化区域。需要一个地区来执行其任务的操作称为本地敏感的,并使用区域设置来为用户定制信息。例如,显示一个数字是一种本地敏感的操作——该数字应该根据用户的本国、地区或文化的习惯和惯例进行格式化。
这个说的很好,Locale之所以会出现在跟时间有关的Calendar类中,正是因为Calendar是一种地区操作,不同时区的时间并不相同。
我自己也看了下,Locale利用Locale.getAvailableLocales()能够输出很多国家名(但我很奇怪,没有东帝汶?就算这个国家比较小。。),所以这个可能不是全的,也就是说可能只是涵盖了世界上的主要国家。
3.Instant
javadoc:
在时间线上的瞬时点。
所以说 Instant的存储结构分为两部分,即秒级时间(epoch-seconds)和纳秒级时间(nanosecond-of-second),这两个结合在一起就组成了具体时间。
和Date比较起来呢,显然Instant的精度要更高。
4.Date
javadoc:类日期表示时间上的特定瞬间,毫秒精度。
个人观点人为,Date是作为类似c语言中“结构(struct)”的存在,他的意义主要在于存储数据,。
通过对Date内部函数的观察,可以发现Date曾经具有很多对时间操作的函数,但随着java的发展很多函数都已经被废弃了,Date的功能变得更加专一化,正如我所说他更像是一个单纯的“结构 ”了。
那么单纯具有结构而缺少函数,如何对他进行操作呢,主要是通过Calendar类进行操作。
5.Calendar
先搬来javadoc的解释:
Calendar类是一个抽象类,它提供了在时间和日历字段(例如年、月、日、月、小时等等)之间转换的方法,以及用于操作日历字段,例如获取下一周的日期。在时间上的瞬间可以用毫秒值表示,这是一种偏移,从1970年1月1日,格林尼治时间1月1日。
对于这个类,我的观点是Calendar是以Date所存储时间为核心,以其他数据类型来完善和明确时间的一个类。
我们可以通过Calendar中的toString()函数的输出结果来佐证我上面的观点。下面是输出结果:
java.util.GregorianCalendar[time=1505553599446,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.ca
lendar.ZoneInfo[id="Asia/Shanghai",offset=28800000,dstSavings=0,useDaylight=false,transitions=19,lastRule=null],fir
stDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2017,MONTH=8,WEEK_OF_YEAR=37,WEEK_OF_MONTH=3,DAY_OF_MONTH=16,DAY_
OF_YEAR=259,DAY_OF_WEEK=7,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=19,SECOND=59,MILLISECOND=446,
ZONE_OFFSET=28800000,DST_OFFSET=0]
其中time值就是时间,而其他变量比如ZoneInfo(地区信息),useDaylingt(是否使用夏令时)等变量都是用来完善和明确时间信息。
(其中的lenient的含义:指定日期/时间解释是否宽大。宽大的解释,如“1996年2月942日”这样的日期将被视为相当于1996年2月1日之后的第941天。对于严格的(非宽松的)解释,这样的日期将导致抛出异常。缺省值是宽容。)
学习期间发现了个BUG,即Calendar c = Calendar.getInstance(TimeZone.getTimeZone("***")); ***处无论填什么都会以本地时区创建Calendar对象
解决办法:利用TimeZone.setDefault();函数修改默认本地函数。即TimeZone.setDefault(TimeZone.getTimeZone("GMT+1"));Calendar c = Calendar.getInstance();
(话说问题还是没有解决吧?是的,这只是绕过这个问题。。)
最后贴一段乱七八糟的代码:
import java.time.Instant;
import java.time.ZoneId;
import java.util.*;
public class Y2017Sep15a {
public static void main(String args[])
{
//GMT和UTC相同啦
//TimeZone的作用1是用于代表时区,其内部存储的是所创时区和GMT的时差,所以TimeZone能获得和GMT的时差
//TimeZone的作用2是计算夏令时,这个我也不太清楚
//默认创建当前时区的TimeZone
TimeZone timeZone = TimeZone.getDefault();
//获得GMT时间
Date date = new Date(System.currentTimeMillis()-timeZone.getRawOffset());
System.out.println("GMT 时间:"+date);
//getOffset(Long date)_在指定的日期从UTC返回此时区的偏移量。如果日光节约时间在规定的时间内生效,则用夏令时调整抵消值。
//getOffset(Long date)和getRawOffset()的区别在于是否计算夏令时
//getRawOffset()不计算夏令时
System.out.println("计算夏令时:"+timeZone.getOffset(new Date().getTime()));
System.out.println("不计算夏令时:"+timeZone.getRawOffset());
//不过从结果上看,两个函数的结果没有区别,也许是我对于getOffset(Long date)的使用方法不对
Locale l = Locale.getDefault();
System.out.println("国家:"+l.getCountry()+" 语言:"+l.getLanguage()
+" 地区变换代码:"+l.getVariant()+" 显示友好的国家名:"+l.getDisplayCountry()
+" 显示友好的名称:"+l.getDisplayName());
//通过now()函数生成一个对象
Instant i = Instant.now();
//输出秒数
long lll = i.getEpochSecond();
//输出纳秒数
long ll = i.getNano();
long llll = i.toEpochMilli();
System.out.println("秒数:"+lll+" 纳秒数:"+ll+" 转换后获得毫秒数:"+llll);
//默认创建当前时间的Calendar
Calendar c = Calendar.getInstance();
//我的观点是Calendar是以Date所存储时间为核心,以其他数据类型来完善和明确时间的一个类
//该类提供了众多对时间操作的接口
System.out.println(c);
System.out.println("输出时间:"+c.getTime());
//输出日期之类的
System.out.println("Calendar_DATE:"+c.get(Calendar.DATE)
+" 输出今天是本年的第"+c.get(Calendar.DAY_OF_YEAR)+"天"
);
//还可以设置日期时间什么的
c.set(Calendar.HOUR_OF_DAY, 0);
System.out.println("输出时间:"+c.getTime());
}
}
输出结果
GMT 时间:Sun Sep 17 09:45:22 CST 2017
计算夏令时:28800000
不计算夏令时:28800000
国家:CN 语言:zh 地区变换代码: 显示友好的国家名:中国 显示友好的名称:中文 (中国)
秒数:1505641522 纳秒数:461000000 转换后获得毫秒数:1505641522461
java.util.GregorianCalendar[time=1505641522462,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=8,WEEK_OF_YEAR=38,WEEK_OF_MONTH=4,DAY_OF_MONTH=17,DAY_OF_YEAR=260,DAY_OF_WEEK=1,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=5,HOUR_OF_DAY=17,MINUTE=45,SECOND=22,MILLISECOND=462,ZONE_OFFSET=28800000,DST_OFFSET=0]
输出时间:Sun Sep 17 17:45:22 CST 2017
Calendar_DATE:17 输出今天是本年的第260天
输出时间:Sun Sep 17 00:45:22 CST 2017
个人见解,如有不妥,望指正,谢谢!