本文介绍Java API 中 Date, Calendar, TimeZone和DateFormat的使用,以及不同时区时间相互转化的方法和原理。

问题描述:

向处于不同时区的服务器发请求时需要考虑时区转换的问题。譬如,服务器位于东八区(北京时间,GMT+8:00),而身处东四区的用户想要查询当天的销售记录。则需把东四区的“今天”这个时间范围转换为服务器所在时区的时间范围。

Tips1. GMT时间:即格林威治平时(Greenwich Mean Time)。平太阳时是与视太阳时对应的,由于地球轨道非圆形,运行速度岁地球与太阳距离改变而出现变化,因此视太阳时欠缺均匀性。为了纠正这种不均匀性,天文学家计算地球非圆形轨迹与极轴倾斜对视太阳时的效应。平太阳时就是指经修订之后的视太阳时。在格林威治子午线上的平太阳时称为世界时(UTC),又叫格林威治平时(GMT)。

类Date表示特定的瞬间,精确到毫秒。获得一个表示当前时间的Date对象有两种方式:

Java代码 1. Date date = new Date();

2. Date date = Calendar.getInstance().getTime();

Date对象本身所存储的毫秒数可以通过date.getTime()方法得到;该函数返回自1970年1月1日 00:00:00 GMT以来此对象表示的毫秒数。

Calendar的getInstance()方法有参数为TimeZone和Locale的重载,可以使用指定时区和语言环境获得一个日历。无参则使用默认时区和语言环境获得日历。

TimeZone表示时区偏移量,本质上以毫秒数保存与GMT的差值。获取TimeZone可以通过时区ID,如"America/New_York",也可以通过GMT+/-hh:mm来设定。例如北京时间可以表示为GMT+8:00。

TimeZone.getRawOffset()方法可以用来得到当前时区的标准时间到GMT的偏移量。上段提到的"America/New_York"和"GMT+8:00"两个时区的偏移量分别为-18000000和28800000。

于是问题就简单了,在时区间转换时间时,首先用原时间减掉原时间所在时区相对于GMT的偏移量,得到原时间相对与GMT的值,再加上目标时区相对GMT的偏移量即可。

这样得到的结果依然是毫秒数,需要按照指定日期格式重新转换成Date对象。

Java代码 import java.text.*;

import java.util.*;

public class DateTransformer

{

public static final String DATE_FORMAT = "MM/dd/yyyy HH:mm:ss";

public static String dateTransformBetweenTimeZone(Date sourceDate, DateFormat formatter,

TimeZone sourceTimeZone, TimeZone targetTimeZone) {

Long targetTime = sourceDate.getTime() - sourceTimeZone.getRawOffset() + targetTimeZone.getRawOffset();

return DateTransformer.getTime(new Date(targetTime), formatter);

}

public static String getTime(Date date, DateFormat formatter){

return formatter.format(date);

}

public static void main(String[] args){

DateFormat formatter = new SimpleDateFormat(DATE_FORMAT);

Date date = Calendar.getInstance().getTime();

TimeZone srcTimeZone = TimeZone.getTimeZone("EST");

TimeZone destTimeZone = TimeZone.getTimeZone("GMT+8");

System.out.println(DateTransformer.dateTransformBetweenTimeZone(date, formatter, srcTimeZone, destTimeZone));

}

}

Tips2. 字面大数字赋值给long类型变量的问题

上面函数中的targetTime是计算得来的,测试用例中我们可能需要通过毫秒数来构建几个日期对象,但是在赋值long time = 1374004799999 时会提示错误“The literal1374004799999 of type int is out of range”。代码中的数字字面值是int类型,因此超出了长度。在大数字后面加个'L',long time = 1374004799999L即可正确赋值。

DateFormat是是日期/时间格式化子类的抽象类,它以与语言无关的方式格式化并解析日期或时间。日期/时间格式化子类(如 SimpleDateFormat)允许进行格式化(也就是日期 -> 文本)、解析(文本-> 日期)和标准化。将日期表示为 Date 对象,或者表示为从 GMT(格林尼治标准时间)1970 年 1 月 1 日 00:00:00 这一刻开始的毫秒数。SimpleDateFormat则是一个以与语言环境有关的方式来格式化和解析日期的具体类,可以以“日期和时间模式”字符串指定日期和时间格式。我们函数中所用模式字符串为"MM/dd/yyyy HH:mm:ss",则输出日期:"07/16/2013 04:00:00"

其他常见的模式字母定义如下:

字母

日期或时间元素

表示

示例

G

Era 标志符

AD

y

1996; 96

M

年中的月份

July; Jul; 07

w

年中的周数

27

W

月份中的周数

2

D

年中的天数

189

d

月份中的天数

10

F

月份中的星期

2

E

星期中的天数

Tuesday; Tue

a

Am/pm 标记

PM

H

一天中的小时数(0-23)

0

k

一天中的小时数(1-24)

24

K

am/pm 中的小时数(0-11)

0

h

am/pm 中的小时数(1-12)

12

m

小时中的分钟数

30

s

分钟中的秒数

55

S

毫秒数

978

z

时区

Pacific Standard Time; PST; GMT-08:00

References:

东八区转为0时区_Java时区转换及时间格式相关推荐

  1. 东八区转为0时区_踩坑记 | Flink 天级别窗口中存在的时区问题

    ❝ 本系列每篇文章都是从一些实际的 case 出发,分析一些生产环境中经常会遇到的问题,抛砖引玉,以帮助小伙伴们解决一些实际问题.本文介绍 Flink 时间以及时区问题,分析了在天级别的窗口时会遇到的 ...

  2. 东八区转为0时区_初中会考重要知识点:地理时区计算技巧全掌握

    松鼠ai德清校区 讲解一:首先给你总结简单点:  1.东加西减  不分东西经,从劣弧(较小圆心角的那部弧为劣弧)看东西方位,左西右东,知西求东用加法,求西用减法. 2.差一个时区就是差一个小时.这是区 ...

  3. 东八区转为0时区_格林尼治时间转换为北京时间

    展开全部 格林尼治时间=北京时间-8小时. "格林尼治".英国大伦敦的一32313133353236313431303231363533e4b893e5b19e3133343365 ...

  4. 东八区转为0时区_什么叫0时区

    展开全部 零时区: 7.5°W-7.5°E 时区中心线 0° .它只是一个时区,就像北京的东8区.在这个32313133353236313431303231363533e58685e5aeb93133 ...

  5. java 时区转换日期转换:东八区转为UTC零时区

    场景: 选择需要将日期:2023-03-31 13:24:51 转换为 UTC零时区格式的日期数据 思路: 采用joda.time 日期处理工具类 代码: @Testpublic void redd1 ...

  6. Linux下修改时区为东八区

    直接上干货. 首先第一步,通过命令 :date -R 查看当前系统所在时区.如是+0800,则是东八区,也就是我们当下的北京时间,如不是(如下图),做如下调整. 命令行键入命令:tzselect #这 ...

  7. 【快递100接口BUG】数据库时区为0时区,而实际时区为东八区时间,导致存入时间多出八个小时

    前些天,上线了快递100的订阅推送服务. 运行稳定,今天早上,运维忽然跟我说,快递单穿越未来了. 我愣了一下,然后运维发了一张图. 说实话,当时我是懵逼的. 因为这个12月03号,下午17:55分还没 ...

  8. [iOS 转换东八区] 将手机当前时区全都转为东八区

    // 获取当前时间 - (NSArray*)getCurrentTime{NSDate *date = [NSDate date];NSDateFormatter *format = [[NSDate ...

  9. 时区处理与东八区的程序员们

    前言 在和前端同学联调的过程中,我们通常会遇到与时间有关的场景:为什么传过来的时间落库的时候总是1970年?为什么相同的时间戳在不同的区域里转换成的时间字符串不一样?为什么不同的转换方法换成的结果一会 ...

最新文章

  1. 前端学习笔记(五)-JavaScript语法基本概念
  2. cordova 蓝牙_Ionic通过Cordova插件使用设备能力
  3. 【超详细】一文学会链表解题(建议收藏!)
  4. list多选 android,Android ExpandableListView单选以及多选实现代码
  5. 语音会议源代码_线上语音群聊神器!开会开黑都好用,免注册、免安装,还免费...
  6. python入门第四章十大歌手 手机通讯录 神奇魔方阵 青春有你
  7. tomcat + apache组合配置
  8. idea导入项目常见异常处理
  9. ad10搜索快捷键_ad快捷键有哪些 ad快捷键汇总
  10. 3串口多串口双串口以及2串口UART转WiFi多跳通讯实现二
  11. Tensorflow-saver模型参数保存及载入
  12. JRE和JDK的区别(笔记)
  13. 提问:usb摄像头无输出画面 /window下能识别摄像头,无输出图像拍摄时提示0XA00F4292(PhotoCaptureStartTimeout) /linux下不能识别
  14. 【调试】sysRq按键使用方法
  15. matlab双纵坐标的绘图命令_[转载]MATLAB画双纵坐标 plotyy的用法 对数坐标
  16. oracle 审计设置,oracle审计简单设置
  17. 如果在天堂遇见你,你还记不记得我是谁?
  18. Git三大特色之WorkFlow(工作流)
  19. 计算三角形的面积和周长
  20. 利用Web Audio API将振动数据转化为音频数据并播放

热门文章

  1. 最近的状态与王者农药
  2. Pyramid Mask Text Detector阅读笔记
  3. Linux CentOS 中安装 Redis(五)
  4. 虫儿飞,虫儿飞,你在思念谁
  5. leetcode 5. 最长回文子串 【马拉车】
  6. TikTok视频没播放,涨粉难?狠抓5点,TikTok运营so easy!
  7. 基于QEMU-aarch64学习UEFI(EDK2)-1环境搭建
  8. ITK——5. 利用ITK自身的多线程加速filter计算
  9. springcloud五大神兽之Feign
  10. mysql where 位子,mysql中 地里位置搜索 (抄)