详解Java中的时区类TimeZone的用法_java

一、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的默认时间区域。并且一旦设置好,就可以确保所有的这些类都将使用同一个默认的时间区域。

以上是小编为您精心准备的的内容,在的博客、问答、公众号、人物、课程等栏目也有的相关内容,欢迎继续使用右上角搜索按钮进行搜索java
, timezone
, 时区
时间
java vector用法详解、java中map的用法详解、timezone 中国时区、0时区时间 timezone、timezone 时区,以便于您获取更多的相关知识。

时间: 2024-09-09 01:20:08

详解Java中的时区类TimeZone的用法_java的相关文章

详解java中的Collections类_java

一般来说课本上的数据结构包括数组.单链表.堆栈.树.图.我这里所指的数据结构,是一个怎么表示一个对象的问题,有时候,单单一个变量声明不堪大用,比如int,String,double甚至一维数组.二维数组无法完全表达你要表达的东西,而定义一个类Class有太过麻烦,这时候,你可以考虑一下用Java中的Collections类.使用Collections类,必须在文件头声明import java.util.*; 一.动态.有序.可变大小的一维数组Vector与ArrayList  Collectio

详解Java中使用ImageIO类对图片进行压缩的方法_java

最近做项目需要图片压缩处理,网上找的方法大都使用了 com.sun.image.codec.jpeg.* 这个包中的JPEGImageEncoder类,引入这个包后一直报错,各种google百度,尝试了各种方法,包括手动引jre中的rt.jar,以及在eclipse中把受访问限制的API提示从ERROR改为WARNING,等等,然而这些都是不好使的,因为后来我发现我的java-7-openjdk-amd64中的rt.jar里边根本就没有com.sun.image.*,貌似这个类在java7中已经

详解Java中的数组与字符串相关知识_java

Java数组的定义和使用 如果希望保存一组有相同类型的数据,可以使用数组. 数组的定义和内存分配 Java 中定义数组的语法有两种: type arrayName[]; type[] arrayName; type 为Java中的任意数据类型,包括基本类型和组合类型,arrayName为数组名,必须是一个合法的标识符,[ ] 指明该变量是一个数组类型变量.例如: int demoArray[]; int[] demoArray; 这两种形式没有区别,使用效果完全一样,读者可根据自己的编程习惯选择

详解Java中的正则表达式

详解Java中的正则表达式,并列出常用的正则表达式语法和一些常用的场景. 判断一个字符串是否是由数字组成: 当不使用正则表达式的时候的实现代码: public class RegexDemo01 { public static void main(String[] args) { String s = "23432324"; char c[] = s.toCharArray();//将字符串转换成字符数组 for (int i = 0; i < c.length; i++) {

Java中StringUtils工具类的一些用法实例

  这篇文章主要介绍了Java中StringUtils工具类的一些用法实例,本文着重讲解了isEmpty和isBlank方法的使用,另外也讲解了trim.strip等方法的使用实例,需要的朋友可以参考下 StringUtils 方法的操作对象是 java.lang.String 类型的对象,是 JDK 提供的 String 类型操作方法的补充,并且是 null 安全的(即如果输入参数 String 为 null 则不会抛出 NullPointerException ,而是做了相应处理,例如,如果

详解Java中的指针、引用及对象的clone

对象|详解 Java语言的一个优点就是取消了指针的概念,但也导致了许多程序员在编程中常常忽略了对象与引用的区别,本文会试图澄清这一概念.并且由于Java不能通过简单的赋值来解决对象复制的问题,在开发过程中,也常常要要应用clone()方法来复制对象.本文会让你了解什么是影子clone与深度clone,认识它们的区别.优点及缺点.看到这个标题,是不是有点困惑:Java语言明确说明取消了指针,因为指针往往是在带来方便的同时也是导致代码不安全的根源,同时也会使程序的变得非常复杂难以理解,滥用指针写成的

详解Java中用于查找对象哈希码值的hashCode()函数_java

理解hashCode() 的作用是获取哈希码,也称为散列码:它实际上是返回一个int整数.这个哈希码的作用是确定该对象在哈希表中的索引位置. hashCode() 定义在JDK的Object.java中,这就意味着Java中的任何类都包含有hashCode() 函数. 虽然,每个Java类都包含hashCode() 函数.但是,仅仅当创建并某个"类的散列表"(关于"散列表"见下面说明)时,该类的hashCode() 才有用(作用是:确定该类的每一个对象在散列表中的位

java-求解Java中import和package的各种用法

问题描述 求解Java中import和package的各种用法 不同目录下的Java文件,每个文件我都给建立了一个包,在其中一个Java文件中访问另一个的时候,import了另一个包,并且也修改了环境变量,把另一个包所在的目录加了进去,结果编译还是错误,说是找不到那个包,包这块还是挺混乱的,哪位给讲讲,请不吝赐教,能不能很系统全面的给说说 解决方案 java中import,package的用法JAVA 中import和 package的用法java中import,package的用法 解决方案二

详解Java中的File文件类以及FileDescriptor文件描述类_java

File File 是"文件"和"目录路径名"的抽象表示形式. File 直接继承于Object,实现了Serializable接口和Comparable接口.实现Serializable接口,意味着File对象支持序列化操作.而实现Comparable接口,意味着File对象之间可以比较大小:File能直接被存储在有序集合(如TreeSet.TreeMap中).1. 新建目录的常用方法方法1:根据相对路径新建目录. 示例代码如下(在当前路径下新建目录"d