Java Date 与时区

Java 中,一个 Date 类对象内部包含2个信息:

  • 绝对时间,即从1970-1-1 00:00:00.000 经过的毫秒数,表示为long类型
  • 时区

绝对时间与时区无关。假设同一时刻,地球东西半球各有一位程序狗执行了以下代码,TA们将各自看到2行输出,其中第一行是相同的数值,而第二行则(极有可能)显示出不同的时间读数:

1 Date now = new Date();
2
3 System.out.println(now.getTime());
4 System.out.println(now);

构造Date对象时,使用构造函数 new Date(long) 获得的对象其内部绝对时间是没有歧义的,就是构造函数参数。但是如果使用其它需要给定年/月/日/...等日期/时间读数的构造函数所获得的对象,在不同的时区,其内部绝对时间将不一定相同。反过来,如果不同时区的Date对象,其内部绝对时间相同,但通过Date.getYear()/Date.getMonth()/...方法获取到的读书也将可能不同(上例就是这种情况)。对Date类,所有年/月/日/...读数,不管是getter方法返回值还是setter方法/构造函数参数,都是代表本地时间,最终其内部绝对时间取决于所在的时区。

通过Date.getTimezoneOffset() 方法可以获得时区。该方法返回本地时间与UTC/GMT之间的差值,单位为分钟。例如我国时区为+08:00,也即我们的本地时间比UTC提前8小时(=480分钟),例如,对于同一个时间描述“x年x月x日x时x分x秒x毫秒”,本地时间发生得UTC早480分钟,也即绝对时间要比UTC小480分钟,因此,Date.getTimezoneOffset()返回值为-480。

如果要构造一个给定UTC年/月/日/...时间读数的Date对象,可借助 Date.UTC()方法先获得其绝对时间,然后再通过new Date(long)构造函数获得Date对象。注意,这样获得的Date对象,其getYear()/getMonth()/...等方法返回的日期/时间数值,已经转换为本地时间,不(一定)同于先前给定的UTC时间。

如果要获取某一个Date对象 that 所代表的绝对时间的UTC年/月/日/...日期/时间读数,可如此构造一个新的Date对象:new Date(that.getTime() - 60000 * that.getTimezoneOffset()),然后调用其 getYear()/getMonth()/...等方法即可。

如果以MVC模式作为类比,Date对象的内部绝对时间是Model,其年/月/日/...读数是View;同一个Model,在不同的时区,展现出来的View不同。如果需要在本地时间与UTC之间进行转换,记住一个公式,对于同一View:

本地时间 - UTC = timezoneOffset

时间: 2024-08-09 12:51:19

Java Date 与时区的相关文章

Date, TimeZone, MongoDB, java中date的时区问题

打印new Date(),Fri Aug 12 13:37:51 CST 2016. 显示Asia/Shanghai的时区,但是date toString 的时区简写却是CST.更坑爹的是,Google CST结果出来是Central Standard Time. 表示North American Central Standard Time. 还以为jdk的date类有问题,debug date toString发现确实是将Asia/Shanghai的name 简写成CST. 接着google,

java Date和Calendar类

最近在无聊的看书,遇到一编程题目,问题描述如下: 黑色星期五源于西方迷信:耶稣基督死于星期五,而13也是一个不吉利的数字.黑色星期五即该日同时是星期五又是13号,求未来几年内这样的日子. 基于该问题会涉及到java中的关于时间类的部分,故尝试通过该题目总结现阶段的java Date和calendar类的问题. 一.Date类 查阅API文档可知,Date类源于jdk1.0版本,并在jdk1.1版本中其绝大多数方法被Calendar类中方法所代替.Date类构造函数public且未abstrct,

常用的Java Date 方法

常用的Java Date 方法 1.计算某一月份的最大天数: Calendar time=Calendar.getInstance(); time.clear(); time.set(Calendar.YEAR,year); //year为int time.set(Calendar.MONTH,i-1);//注意,Calendar对象默认一月为0 int day=time.getActualMaximum(Calendar.DAY_OF_MONTH);//本月份的天数 注:在使用set方法之前,

java Date函数总结

java.util.Date为java时间接口,已知的实现类包括Date,Time,TimeStamp Calendar calendar=Calendar.getInstance(); DateFormat df=new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); Date dateA=new Date(); //初始化dataA为当前时间 //将Date转化为String String dateAString=df.format(dateA);

Java 获取各时区时间,获取当前时间到格林威治时间1970年01月01日00时00分00秒的秒数

格林威治时间即UTC/GMT时间,1970年01月01日00时00分00秒(即UTC+8的北京时间1970年01月01日08时00分00秒)计算代码如下: 1 /** 2 * 获取指定时间到格林威治时间的秒数 3 * UTC:格林威治时间1970年01月01日00时00分00秒(UTC+8北京时间1970年01月01日08时00分00秒) 4 * @param time 5 * @return 6 */ 7 public static long diffSeconds(String time){

jackson/fastjson、mybatis、mysql date/datatime/timestamp、java Date/Timestamp关系详解

jackson/fastjson序列化/反序列化: 默认情况下,jackson/fastjson将java Date/Timestamp类型序列化为时间戳,也就是1970年1月1日0点以来的毫秒数.如果要显示为用户友好表示: Jackson 可以: SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); objectMapper.setDateFormat(sdf)或者:@JsonFormat(locale

Java Date类和Calendar类的一个控制台打印日期的小程序

Java Date类和Calendar类的一个打印日期的小程序,可以直接用. package com.boy.Idate.calendar; import java.text.ParseException; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Date; /** * 控制台可视化日历 * @author 田硕 */ public class VisualCalendar {

Java Date, Calendar and Time API - Tutorial

Java Date and Time API This article explains the API for using Calendar, Date and Time in Java and how to format the output of a date. Table of Contents 1. Overview 2. Format date 3. Working with Dates and Calendars 3.1. Calendar 3.2. Date and Date C

Java Date Classes

The main change in the Java 8 date time API is that date and time is now no longer represented by a single number of milliseconds since Jan. 1st 1970, but by the number of seconds and nanoseconds since Jan. 1st 1970. The number of seconds can be both