详解Java中的时区类TimeZone的用法
作者:log_cd 发布时间:2023-11-29 02:03:09
一、TimeZone 简介
TimeZone 表示时区偏移量,也可以计算夏令时。
在操作 Date, Calendar等表示日期/时间的对象时,经常会用到TimeZone;因为不同的时区,时间不同。
下面说说TimeZone对象的 2种常用创建方式。
1.获取默认的TimeZone对象
使用方法:
TimeZone tz = TimeZone.getDefault()
2.使用 getTimeZone(String id) 方法获取TimeZone对象
使用方法:
// 获取 “GMT+08:00”对应的时区
TimeZone china = TimeZone.getTimeZone("GMT+:08:00");
// 获取 “中国/重庆”对应的时区
TimeZone chongqing = TimeZone.getTimeZone("Asia/Chongqing");
关于 getTimeZone(String id) 这种方式支持的全部id参数的取值,可以通过以下方式查找:
String[] ids = TimeZone.getAvailableIDs();
for (String id:ids)
System.out.printf(id+", ");
输出结果:
Etc/GMT+12, Etc/GMT+11, Pacific/Midway, Pacific/Niue ....等等
例如,创建上面第2个打印值“Etc/GMT+11”对应的TimeZone。方法如下:
TimeZone tz = TimeZone.getTimeZone("Etc/GMT+11");
TimeZone的函数接口
// 构造函数
TimeZone():
Object clone()
synchronized static String[] getAvailableIDs()
synchronized static String[] getAvailableIDs(int offsetMillis)
int getDSTSavings()
synchronized static TimeZone getDefault()
final String getDisplayName(Locale locale)
String getDisplayName(boolean daylightTime, int style, Locale locale)
final String getDisplayName()
final String getDisplayName(boolean daylightTime, int style)
String getID()
abstract int getOffset(int era, int year, int month, int day, int dayOfWeek, int timeOfDayMillis)
int getOffset(long time)
abstract int getRawOffset()
synchronized static TimeZone getTimeZone(String id)
boolean hasSameRules(TimeZone timeZone)
abstract boolean inDaylightTime(Date time)
synchronized static void setDefault(TimeZone timeZone)
void setID(String id)
abstract void setRawOffset(int offsetMillis)
abstract boolean useDaylightTime()
二、TimeZone示例:
下面通过示例演示在Date中使用TimeZone。
参考代码如下(TimeZoneTest.java):
import java.text.DateFormat;
import java.util.Date;
import java.util.TimeZone;
/**
* TimeZone的测试程序
*/
public class TimeZoneTest {
public static void main(String[] args) {
// 测试创建TimeZone对象的3种方法
showUsageOfTimeZones() ;
// 测试TimeZone的其它API
testOtherAPIs() ;
// 打印getTimeZone(String id)支持的所有id
//printAllTimeZones() ;
}
/**
* 测试创建TimeZone对象的3种方法
*/
public static void showUsageOfTimeZones() {
TimeZone tz;
// (01) 默认时区
tz = TimeZone.getDefault();
printDateIn(tz) ;
// (02) 设置时区为"GMT+08:00"
tz = TimeZone.getTimeZone("GMT+08:00");
printDateIn(tz) ;
// (03) 设置时区为""
tz = TimeZone.getTimeZone("Asia/Chongqing");
printDateIn(tz) ;
}
/**
* 打印 tz对应的日期/时间
*/
private static void printDateIn(TimeZone tz) {
// date为2013-09-19 14:22:30
Date date = new Date(113, 8, 19, 14, 22, 30);
// 获取默认的DateFormat,用于格式化Date
DateFormat df = DateFormat.getInstance();
// 设置时区为tz
df.setTimeZone(tz);
// 获取格式化后的字符串
String str = df.format(date);
System.out.println(tz.getID()+" :"+str);
}
/**
* 测试TimeZone的其它API
*/
public static void testOtherAPIs() {
// 默认时区
TimeZone tz = TimeZone.getDefault();
// 获取“id”
String id = tz.getID();
// 获取“显示名称”
String name = tz.getDisplayName();
// 获取“时间偏移”。相对于“本初子午线”的偏移,单位是ms。
int offset = tz.getRawOffset();
// 获取“时间偏移” 对应的小时
int gmt = offset/(3600*1000);
System.out.printf("id=%s, name=%s, offset=%s(ms), gmt=%s\n",
id, name, offset, gmt);
}
/**
* 打印getTimeZone(String id)支持的所有id
*/
public static void printAllTimeZones() {
String[] ids = TimeZone.getAvailableIDs();
for (String id:ids) {
//int offset = TimeZone.getTimeZone(avaIds[i]).getRawOffset();
//System.out.println(i+" "+avaIds[i]+" "+offset / (3600 * 1000) + "\t");
System.out.printf(id+", ");
}
System.out.println();
}
}
三、关于TimeZone和时间校准
涉及有关时间区域信息时Java和Solaris很相似。每个时间区域都有一个时间区域ID标识符。在J2SE 1.3 and 1.4中,这个ID是个字符串,是由位于J2SE 安装程序的jre/lib子目录中的tzmappings文件这些ID列表。 J2SE 1.3 仅仅只包含tzmappings文件,但是 J2SE 1.4包含世界不同地区的时间区域数据文件。jre/lib/zi存放着这些文件。在J2SE 1.4里,sun.util.calendar.ZoneInfo从这些文件获取DST规则。在Solaris中, 这些时间区域数据文件是以二进制形式存放的,不是文本文件,因此你不能看它们。 在J2SE 1.4中的时间区域数据文件和在Solaris中是不同的。
java.util.TimeZone类中getDefault方法的源代码显示,它最终是会调用sun.util.calendar.ZoneInfo类的getTimeZone 方法。这个方法为需要的时间区域返回一个作为ID的String参数。这个默认的时间区域ID是从 user.timezone (system)属性那里得到。如果user.timezone没有定义,它就会尝试从user.country和java.home (System)属性来得到ID。 如果它没有成功找到一个时间区域ID,它就会使用一个"fallback" 的GMT值。换句话说, 如果它没有计算出你的时间区域ID,它将使用GMT作为你默认的时间区域。
注意,System属性是在java.lang.System类的initProperties方法中被初始化的。这是一个本地方法。因此源代码是不可用的----除非你深入到J2SE分发包中的本地代码库中去研究。然而,在Windows系统中,System 属性是从Windows注册表中被初始化的,而在Linux/Unix中是由环境变量来进行初始化。initProperties方法的Javadoc声明,某些属性"必须保证被定义" 且列出它们。被java.util.TimeZone类的getDefault方法使用的三个System属性中,只有java.home作为一种“保证的”属性在Javadoc中被列出。
推荐的解决方案 :
因此,你如何确保JAVA能给你正确的时间和日期呢?最好的办法是确认JAVA虚拟机(JVM)的默认TimeZone类是正确的,且是适合你的地理范围(Locale)的。你如何来确保默认TimeZone是正确的且适合的呢?这又是一个新问题了。象大多数处理的问题一样,这个也有许多解决方案。根据java.util.TimeZone.getDefault方法的源代码来看,最好的办法是正确地设置user.timezone属性。在启动JAVA虚拟机时,你能很容易的通过使用 -D 命令 -line 参数的办法来覆盖(override)在java.lang.System.initProperties方法中所设置的值。例如:
java -Duser.timezone=Asia/Shanghai DateTest
这个命令启动DateTest类,并设置 user.timezone属性到Asia/Shanghai。你也能够通过使用java.lang.System 类的setProperty方法来设置user.timezone 属性:
System.setProperty("user.timezone","Asia/Shanghai");
如果没有一个可用的时间区域ID适合你,那么就你可以创建一个自定义TimeZone 使用java.util.TimeZone 类的 setDefault 方法将它设置为默认的时间区域----就象我先前在ItsInitializer 类中所做的操作一样。
记住,在J2SE中,大多数日期和时间相关的类都包含时间区域信息,包括那些格式类,如java.text.DateFormat, 因此它们都会被JVM的默认时间区域所影响。然而,在你创建这些类的实例时,你能为它们确保正确的时间区域信息,使得你可以更容易来设置整个JVM的默认时间区域。并且一旦设置好,就可以确保所有的这些类都将使用同一个默认的时间区域。
猜你喜欢
- 1.前言在Mybatis中需要创建的配置文件有sqlMapconfig.xml,映射文件xxxMapper.xml,而这些文件在idea中并
- java中Hashmap的get方法map中存储的是键值对,也就是说通过set方法进行参数和值的存储,之后通过get“键”的形式进行值的读取
- 过滤器实现过滤器需要实现 javax.servlet.Filter 接口。重写三个方法。其中 init() 方法在服务启动时执行,destr
- 一、线程的优先级别线程优先级别的使用范例:package cn.galc.test;public class TestThread6 { p
- 本文实例为大家分享了Java实现考试系统的具体代码,供大家参考,具体内容如下说明这里的考试系统是指由学生,老师以及考试机构成的,学生通过用户
- 在实施接口中,我们利用interface语法,将interface从类定义中独立出来,构成一个主体。interface为类提供了接口规范。在
- 什么是线程池是一种基于池化思想管理线程的工具。池化技术:池化技术简单点来说,就是提前保存大量的资源,以备不时之需。比如我们的对象池,数据库连
- 前提说明之前公司有一个项目是由androidstudio接入高德地图实现导航,定位等功能,然后还有一部分登陆页面和其他逻辑都放在Unity方
- maven配置项目的jdk版本无效排查最近在配置项目的jdk的时候发现在pom.xml中配置的1.8版本无效,maven更新后就变成了1.7
- Java读取json数据并存入数据库1. pom依赖<dependency> &nbs
- 在 MyEclipse 的可视化 Swing 中,有 JTable 控件。JTable 用来显示和编辑常规二维单元表。那么,如何将 数据库S
- 异常分类可查的异常(checked exceptions):Exception下除了RuntimeException外的异常不可查的异常(u
- PermissionManage项目地址:https://github.com/why168/AndroidProjects/tree/ma
- 本文实例讲述了Android编程实现WebView添加进度条的方法。分享给大家供大家参考,具体如下:标准的XML界面<?xml ver
- 最近碰到这么个恶心的问题问题:有个arr文件被放到Module A中引用,现在Module B又依赖了Module A,则在编译过程中会发生
- 本文实例为大家分享了C语言实现贪吃蛇游戏的具体代码,供大家参考,具体内容如下IDE用的是 VS2019先看效果 代码全览game.
- 一 :问题背景问题:当查询接口较复杂时候,数据的获取都需要[远程调用],必然需要花费更多的时间。 假如查询文章详情页面,需要如下标注的时间才
- 本文实例讲述了Java Web实现添加定时任务的方法。分享给大家供大家参考,具体如下:定时任务时间控制类/** * 定时任务时间控制 * *
- 合并有序数组的实现java版本:实例代码public class Merge {//合并有序数组 public static v
- feign传输List的坑无法直接传输List错误方法1@RequestMapping(value = "/stat/mercha