浅谈java基本库中关于时间的那几个类

本文介绍了Java中处理时间的几个核心类:TimeZone用于表示时区并计算夏令时;Locale代表地理、政治或文化区域,影响日期格式化;Instant表示时间线上的精确瞬间,精度高于Date;Date存储时间瞬间,现在更多作为数据结构使用,通过Calendar进行操作;Calendar是抽象类,提供日期和时间字段的转换及操作,包括时间、时区、夏令时等信息。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


1.TimeZone

TimeZone的作用1是用于代表时区,其内部存储的是所创时区和GMT的时差,所以TimeZone能获得和GMT的时差
TimeZone的作用2是计算夏令时,这个我也不太清楚


2.Locale

这个在javadoc中的解释如下:

Locale对象表示特定的地理、政治或文化区域。需要一个地区来执行其任务的操作称为本地敏感的,并使用区域设置来为用户定制信息。例如,显示一个数字是一种本地敏感的操作——该数字应该根据用户的本国、地区或文化的习惯和惯例进行格式化。

这个说的很好,Locale之所以会出现在跟时间有关的Calendar类中,正是因为Calendar是一种地区操作,不同时区的时间并不相同。

我自己也看了下,Locale利用Locale.getAvailableLocales()能够输出很多国家名(但我很奇怪,没有东帝汶?就算这个国家比较小。。),所以这个可能不是全的,也就是说可能只是涵盖了世界上的主要国家。


3.Instant

javadoc:

在时间线上的瞬时点。

这个类模型在时间线上有一个瞬时点。这可能用于在应用程序中记录事件时间戳。
一个瞬间的范围需要存储一个大于一个long的数字。为了实现这一点,类存储了一个long表示时间秒(epoch-seconds)和一个表示纳秒秒(nanosecond-of-second)的int数,它总是在0到999,999,999之间。从1970 -01-01 - 01t00:00 z的标准Java时代开始,在这个时代有积极的价值观,而早期的instants有消极的价值观。

所以说 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


个人见解,如有不妥,望指正,谢谢!


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值