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

一、TimeZone 简介

TimeZone 表示时区偏移量,也可以计算夏令时。

在操作 Date, Calendar等表示日期/时间的对象时,经常会用到TimeZone;因为不同的时区,时间不同。

下面说说TimeZone对象的 2种常用创建方式。
1.获取默认的TimeZone对象
使用方法:

TimeZone tz = TimeZone.getDefault()

2.使用 getTimeZone(String id) 方法获取TimeZone对象
使用方法:

  1. // 获取 “GMT+08:00”对应的时区

  2.  

    TimeZone china = TimeZone.getTimeZone("GMT+:08:00");

  3.  

    // 获取 “中国/重庆”对应的时区

  4.  

    TimeZone chongqing = TimeZone.getTimeZone("Asia/Chongqing");

关于 getTimeZone(String id) 这种方式支持的全部id参数的取值,可以通过以下方式查找:

  1. String[] ids = TimeZone.getAvailableIDs();

  2.  

    for (String id:ids)

  3.  

    System.out.printf(id+", ");

输出结果:

Etc/GMT+12, Etc/GMT+11, Pacific/Midway, Pacific/Niue ....等等

例如,创建上面第2个打印值“Etc/GMT+11”对应的TimeZone。方法如下:

  1. TimeZone tz = TimeZone.getTimeZone("Etc/GMT+11");

  2.  

    TimeZone的函数接口

  3.  

    // 构造函数

TimeZone():

  1. Object clone()

  2.  

    synchronized static String[] getAvailableIDs()

  3.  

    synchronized static String[] getAvailableIDs(int offsetMillis)

  4.  

    int getDSTSavings()

  5.  

    synchronized static TimeZone getDefault()

  6.  

    final String getDisplayName(Locale locale)

  7.  

    String getDisplayName(boolean daylightTime, int style, Locale locale)

  8.  

    final String getDisplayName()

  9.  

    final String getDisplayName(boolean daylightTime, int style)

  10.  

    String getID()

  11.  

    abstract int getOffset(int era, int year, int month, int day, int dayOfWeek, int timeOfDayMillis)

  12.  

    int getOffset(long time)

  13.  

    abstract int getRawOffset()

  14.  

    synchronized static TimeZone getTimeZone(String id)

  15.  

    boolean hasSameRules(TimeZone timeZone)

  16.  

    abstract boolean inDaylightTime(Date time)

  17.  

    synchronized static void setDefault(TimeZone timeZone)

  18.  

    void setID(String id)

  19.  

    abstract void setRawOffset(int offsetMillis)

  20.  

    abstract boolean useDaylightTime()

  21.  

  22.  

二、TimeZone示例:
下面通过示例演示在Date中使用TimeZone。

参考代码如下(TimeZoneTest.java):

  1. import java.text.DateFormat;

  2.  

    import java.util.Date;

  3.  

    import java.util.TimeZone;

  4.  

  5.  

    /**

  6.  

    * TimeZone的测试程序

  7.  

    */

  8.  

    public class TimeZoneTest {

  9.  

  10.  

    public static void main(String[] args) {

  11.  

  12.  

    // 测试创建TimeZone对象的3种方法

  13.  

    showUsageOfTimeZones() ;

  14.  

  15.  

    // 测试TimeZone的其它API

  16.  

    testOtherAPIs() ;

  17.  

  18.  

    // 打印getTimeZone(String id)支持的所有id

  19.  

    //printAllTimeZones() ;

  20.  

    }

  21.  

  22.  

  23.  

    /**

  24.  

    * 测试创建TimeZone对象的3种方法

  25.  

    */

  26.  

    public static void showUsageOfTimeZones() {

  27.  

    TimeZone tz;

  28.  

  29.  

    // (01) 默认时区

  30.  

    tz = TimeZone.getDefault();

  31.  

    printDateIn(tz) ;

  32.  

  33.  

    // (02) 设置时区为"GMT+08:00"

  34.  

    tz = TimeZone.getTimeZone("GMT+08:00");

  35.  

    printDateIn(tz) ;

  36.  

  37.  

    // (03) 设置时区为""

  38.  

    tz = TimeZone.getTimeZone("Asia/Chongqing");

  39.  

    printDateIn(tz) ;

  40.  

    }

  41.  

  42.  

    /**

  43.  

    * 打印 tz对应的日期/时间

  44.  

    */

  45.  

    private static void printDateIn(TimeZone tz) {

  46.  

    // date为2013-09-19 14:22:30

  47.  

    Date date = new Date(113, 8, 19, 14, 22, 30);

  48.  

    // 获取默认的DateFormat,用于格式化Date

  49.  

    DateFormat df = DateFormat.getInstance();

  50.  

    // 设置时区为tz

  51.  

    df.setTimeZone(tz);

  52.  

    // 获取格式化后的字符串

  53.  

    String str = df.format(date);

  54.  

  55.  

    System.out.println(tz.getID()+" :"+str);

  56.  

    }

  57.  

  58.  

    /**

  59.  

    * 测试TimeZone的其它API

  60.  

    */

  61.  

    public static void testOtherAPIs() {

  62.  

    // 默认时区

  63.  

    TimeZone tz = TimeZone.getDefault();

  64.  

  65.  

    // 获取“id”

  66.  

    String id = tz.getID();

  67.  

  68.  

    // 获取“显示名称”

  69.  

    String name = tz.getDisplayName();

  70.  

  71.  

    // 获取“时间偏移”。相对于“本初子午线”的偏移,单位是ms。

  72.  

    int offset = tz.getRawOffset();

  73.  

    // 获取“时间偏移” 对应的小时

  74.  

    int gmt = offset/(3600*1000);

  75.  

  76.  

    System.out.printf("id=%s, name=%s, offset=%s(ms), gmt=%s\n",

  77.  

    id, name, offset, gmt);

  78.  

    }

  79.  

  80.  

    /**

  81.  

    * 打印getTimeZone(String id)支持的所有id

  82.  

    */

  83.  

    public static void printAllTimeZones() {

  84.  

  85.  

    String[] ids = TimeZone.getAvailableIDs();

  86.  

    for (String id:ids) {

  87.  

    //int offset = TimeZone.getTimeZone(avaIds[i]).getRawOffset();

  88.  

    //System.out.println(i+" "+avaIds[i]+" "+offset / (3600 * 1000) + "\t");

  89.  

    System.out.printf(id+", ");

  90.  

    }

  91.  

    System.out.println();

  92.  

    }

  93.  

    }

  94.  

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

--------------------- 本文来自 earthchinagl 的CSDN 博客 ,全文地址请点击:https://blog.csdn.net/earthchinagl/article/details/71404061?utm_source=copy

原文地址:https://www.cnblogs.com/miaow/p/9753013.html

时间: 2024-11-03 14:50:07

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

详解Java中代码块和继承

本文发表于个人GitHub主页,原文请移步详解Java中代码块和继承 阅读. 概念 1.代码块 局部代码块 用于限定变量生命周期,及早释放,提高内存利用率 静态代码块 对类的数据进行初始化,仅仅只执行一次. 构造代码块 把多个构造方法中相同的代码可以放到这里,每个构造方法执行前,首先执行构造代码块. 2.继承 继承是已有的类中派生出新的类,新的类能够吸收已有类的数据属性和行为,并能扩展新的功能. 代码块的执行顺序 public class Test {    public String name

详解mysql中的Using与On的用法

多用才可以体会各个关键字的用法啊... 原文来自[http://bbs.php100.com/read-htm-tid-148469.html] 在用Join进行多表联合查询时,我们通常使用On来建立两个表的关系.其实还有一个更方便的关键字,那就是Using.那么这两个关键字在使用上有啥区别呢?往下看.假设有如下两张表:    mysql> select * from pets; +---------+---------+--------+-----------+ | pets_id | ani

详解Linux中的cat文本输出命令用法

作系统 > LINUX > 详解Linux中的cat文本输出命令用法 Linux命令手册   发布时间:2016-01-14 14:14:35   作者:张映    我要评论 这篇文章主要介绍了Linux中的cat文本输出命令用法,是Linux入门学习中的基础知识,需要的朋友可以参考下 cat命令是linux下的一个文本输出命令,通常是用于观看某个文件的内容的.一.功能cat主要有三大功能:1.一次显示整个文件. 复制代码 代码如下: $ cat filename 2.从键盘创建一个文件. 复

详解java中clone方法

原文地址:http://leihuang.net/2014/11/14/java-clone/ In java, it essentially means the ability to create an object with similar state as the original object. 什么是clone 字典中的意思就是复制(强调跟原来的一模一样). *By default, java cloning is 'field by field copy' *.因为Object类不知

干货——详解Java中的关键字

在平时编码中,我们可能只注意了这些static,final,volatile等关键字的使用,忽略了他们的细节,更深层次的意义. 本文总结了Java中所有常见的关键字以及一些例子. static 关键字 概述: 当static修饰类的属性或者方法时,那么就可以在没有创建对象的情况下使用该属性或方法. 静态块也是static的一个应用,用于初始化类时的一些操作. 静态方法和静态变量 划重点 被static修饰后的属性或者方法,使用时不需要new 一个类,用类.属性名或方法名访问. 比如java.la

详解Java中格式化日期的DateFormat与SimpleDateFormat类

DateFormat其本身是一个抽象类,SimpleDateFormat 类是DateFormat类的子类,一般情况下来讲DateFormat类很少会直接使用,而都使用SimpleDateFormat类完成,下面我们具体来看一下两个类的用法: DateFormat1. DateFormat 介绍DateFormat 的作用是 格式化并解析“日期/时间”.实际上,它是Date的格式化工具,它能帮助我们格式化Date,进而将Date转换成我们想要的String字符串供我们使用不过DateFormat

【Java学习笔记之三十三】详解Java中try,catch,finally的用法及分析

这一篇我们将会介绍java中try,catch,finally的用法 以下先给出try,catch用法: try { //需要被检测的异常代码 } catch(Exception e) { //异常处理,即处理异常代码 } 代码区如果有错误,就会返回所写异常的处理. 首先要清楚,如果没有try的话,出现异常会导致程序崩溃.而try则可以保证程序的正常运行下去,比如说: try { int i = 1/0; } catch(Exception e) { ........ } 一个计算的话,如果除数

详解Java中的clone方法

转载自:http://blog.csdn.net/zhangjg_blog/article/details/18369201 Java中对象的创建 clone顾名思义就是复制, 在Java语言中, clone方法被对象调用,所以会复制对象.所谓的复制对象,首先要分配一个和源对象同样大小的空间,在这个空间中创建一个新的对象.那么在java语言中,有几种方式可以创建对象呢? 1 使用new操作符创建一个对象 2 使用clone方法复制一个对象 那么这两种方式有什么相同和不同呢? new操作符的本意是

详解Java中Map用法

Map以按键/数值对的形式存储数据,这里要特别说明( Map.Entry,是Map的内部类,它用来描述Map中的键/值对). Map是一个接口,我们平时多用它的实现类HashMap. 用例如下: public static void main(String args[]) { HashMap hashmap = new HashMap(); hashmap.put("Item0", "Value0"); hashmap.put("Item1",