java对世界各个时区(TimeZone)的通用转换处理方法
在进行国际性软件项目开发的过程中,有时候会碰到一些比较特殊的要求。比如:比如说,你做的是个购物网站(假设服务器放在中国上海),当全世界客户在你的网站上下订单买东西后,往往希望看到客户所在地下单时间,比如说我是个美国纽约人,我在你的网站上下单后,你给我看到一个上海的下单时间,会觉得非常的奇怪。众所周知,纽约时间相对上海时间大约要晚13小时,如果让客户看到本地时区的时间,将变得更加符合客户的时间观念,使得客户理解比较方便。
其实,java中早已考虑过世界时区(TimeZone)这个问题,并给出了比较合理的解决方法,可以比较方便的进行世界时区时间的转化,将一个时区的时间转换成另一个时区的时间。可以看看下面的的实际例子(运行例子的main()方法)。
关于如何知道客户所在的时区,可以根据客户所在的ip或者用户注册提供的国家来计算出所在的时区。
/*
* Created on 2005-6-10
* Author stephen
* Email zhoujianqiang AT gmail DOT com
* CopyRight(C)2005-2008 , All rights reserved.
*/
package com.soft4j.utility; import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.TimeZone;
import java.util.Vector; import com.soft4j.log.Log; /**
* 与日期、时间相关的一些常用工具方法.
* <p>
* 日期(时间)的常用格式(formater)主要有: <br>
* yyyy-MM-dd HH:mm:ss <br>
*
* @author stephen
* @version 1.0.0
*/
public final class DateTool { /**
* 对日期(时间)中的日进行加减计算. <br>
* 例子: <br>
* 如果Date类型的d为 2005年8月20日,那么 <br>
* calculateByDate(d,-10)的值为2005年8月10日 <br>
* 而calculateByDate(d,+10)的值为2005年8月30日 <br>
*
* @param d
* 日期(时间).
* @param amount
* 加减计算的幅度.+n=加n天;-n=减n天.
* @return 计算后的日期(时间).
*/
public static Date calculateByDate(Date d, int amount) {
return calculate(d, GregorianCalendar.DATE, amount);
} public static Date calculateByMinute(Date d, int amount) {
return calculate(d, GregorianCalendar.MINUTE, amount);
} public static Date calculateByYear(Date d, int amount) {
return calculate(d, GregorianCalendar.YEAR, amount);
} /**
* 对日期(时间)中由field参数指定的日期成员进行加减计算. <br>
* 例子: <br>
* 如果Date类型的d为 2005年8月20日,那么 <br>
* calculate(d,GregorianCalendar.YEAR,-10)的值为1995年8月20日 <br>
* 而calculate(d,GregorianCalendar.YEAR,+10)的值为2015年8月20日 <br>
*
* @param d
* 日期(时间).
* @param field
* 日期成员. <br>
* 日期成员主要有: <br>
* 年:GregorianCalendar.YEAR <br>
* 月:GregorianCalendar.MONTH <br>
* 日:GregorianCalendar.DATE <br>
* 时:GregorianCalendar.HOUR <br>
* 分:GregorianCalendar.MINUTE <br>
* 秒:GregorianCalendar.SECOND <br>
* 毫秒:GregorianCalendar.MILLISECOND <br>
* @param amount
* 加减计算的幅度.+n=加n个由参数field指定的日期成员值;-n=减n个由参数field代表的日期成员值.
* @return 计算后的日期(时间).
*/
private static Date calculate(Date d, int field, int amount) {
if (d == null)
return null;
GregorianCalendar g = new GregorianCalendar();
g.setGregorianChange(d);
g.add(field, amount);
return g.getTime();
} /**
* 日期(时间)转化为字符串.
*
* @param formater
* 日期或时间的格式.
* @param aDate
* java.util.Date类的实例.
* @return 日期转化后的字符串.
*/
public static String date2String(String formater, Date aDate) {
if (formater == null || "".equals(formater))
return null;
if (aDate == null)
return null;
return (new SimpleDateFormat(formater)).format(aDate);
} /**
* 当前日期(时间)转化为字符串.
*
* @param formater
* 日期或时间的格式.
* @return 日期转化后的字符串.
*/
public static String date2String(String formater) {
return date2String(formater, new Date());
} /**
* 获取当前日期对应的星期数.
* <br>1=星期天,2=星期一,3=星期二,4=星期三,5=星期四,6=星期五,7=星期六
* @return 当前日期对应的星期数
*/
public static int dayOfWeek() {
GregorianCalendar g = new GregorianCalendar();
int ret = g.get(java.util.Calendar.DAY_OF_WEEK);
g = null;
return ret;
} /**
* 获取所有的时区编号. <br>
* 排序规则:按照ASCII字符的正序进行排序. <br>
* 排序时候忽略字符大小写.
*
* @return 所有的时区编号(时区编号已经按照字符[忽略大小写]排序).
*/
public static String[] fecthAllTimeZoneIds() {
Vector v = new Vector();
String[] ids = TimeZone.getAvailableIDs();
for (int i = 0; i < ids.length; i++) {
v.add(ids[i]);
}
java.util.Collections.sort(v, String.CASE_INSENSITIVE_ORDER);
v.copyInto(ids);
v = null;
return ids;
} /**
* 测试的main方法.
*
* @param argc
*/
public static void main(String[] argc) { String[] ids = fecthAllTimeZoneIds();
String nowDateTime =date2String("yyyy-MM-dd HH:mm:ss");
System.out.println("The time Asia/Shanhai is " + nowDateTime);//程序本地运行所在时区为[Asia/Shanhai]
//显示世界每个时区当前的实际时间
for(int i=0;i <ids.length;i++){
System.out.println(" * " + ids[i] + "=" + string2TimezoneDefault(nowDateTime,ids[i]));
}
//显示程序运行所在地的时区
System.out.println("TimeZone.getDefault().getID()=" +TimeZone.getDefault().getID());
} /**
* 将日期时间字符串根据转换为指定时区的日期时间.
*
* @param srcFormater
* 待转化的日期时间的格式.
* @param srcDateTime
* 待转化的日期时间.
* @param dstFormater
* 目标的日期时间的格式.
* @param dstTimeZoneId
* 目标的时区编号.
*
* @return 转化后的日期时间.
*/
public static String string2Timezone(String srcFormater,
String srcDateTime, String dstFormater, String dstTimeZoneId) {
if (srcFormater == null || "".equals(srcFormater))
return null;
if (srcDateTime == null || "".equals(srcDateTime))
return null;
if (dstFormater == null || "".equals(dstFormater))
return null;
if (dstTimeZoneId == null || "".equals(dstTimeZoneId))
return null;
SimpleDateFormat sdf = new SimpleDateFormat(srcFormater);
try {
int diffTime = getDiffTimeZoneRawOffset(dstTimeZoneId);
Date d = sdf.parse(srcDateTime);
long nowTime = d.getTime();
long newNowTime = nowTime - diffTime;
d = new Date(newNowTime);
return date2String(dstFormater, d);
} catch (ParseException e) {
Log.output(e.toString(), Log.STD_ERR);
return null;
} finally {
sdf = null;
}
} /**
* 获取系统当前默认时区与UTC的时间差.(单位:毫秒)
*
* @return 系统当前默认时区与UTC的时间差.(单位:毫秒)
*/
private static int getDefaultTimeZoneRawOffset() {
return TimeZone.getDefault().getRawOffset();
} /**
* 获取指定时区与UTC的时间差.(单位:毫秒)
*
* @param timeZoneId
* 时区Id
* @return 指定时区与UTC的时间差.(单位:毫秒)
*/
private static int getTimeZoneRawOffset(String timeZoneId) {
return TimeZone.getTimeZone(timeZoneId).getRawOffset();
} /**
* 获取系统当前默认时区与指定时区的时间差.(单位:毫秒)
*
* @param timeZoneId
* 时区Id
* @return 系统当前默认时区与指定时区的时间差.(单位:毫秒)
*/
private static int getDiffTimeZoneRawOffset(String timeZoneId) {
return TimeZone.getDefault().getRawOffset()
- TimeZone.getTimeZone(timeZoneId).getRawOffset();
} /**
* 将日期时间字符串根据转换为指定时区的日期时间.
*
* @param srcDateTime
* 待转化的日期时间.
* @param dstTimeZoneId
* 目标的时区编号.
*
* @return 转化后的日期时间.
* @see #string2Timezone(String, String, String, String)
*/
public static String string2TimezoneDefault(String srcDateTime,
String dstTimeZoneId) {
return string2Timezone("yyyy-MM-dd HH:mm:ss", srcDateTime,
"yyyy-MM-dd HH:mm:ss", dstTimeZoneId);
} }
本文转自:http://stephen830.iteye.com/blog/260343
java对世界各个时区(TimeZone)的通用转换处理方法的更多相关文章
- Java不同时区(timezone)之间时间转换
最近出现一个问题是这样的:我们的系统在国外打印的日志时间由于时差关系和国内不一致,看起来不方便,希望国外的日志和国内保持一致,即:需要对不同时区的时间做转换调整,统一为国内时间. 一.关于时区的一些概 ...
- java中字符数组与字符串之间互相转换的方法
public static void main(String[] args) { //1.字符数组 转换成 字符串 //(1)直接在构造String时转换 char[] array = new cha ...
- JAVA中java.util.Date、java.sql.Timestamp和String之间的互相转换
java.util.Date与的String互转 java.util.Date---->String /** * 将java.util.Date对象转化为String字符串 * @param d ...
- 新霸哥带你进入java的世界
新霸哥从近期大家的留言中注意到了大家对基础知识比较重视,很多的朋友希望多讲一些入门的知识,为了满足广大开发爱好者的需求,新霸哥决定从最基础的做起,一点一点的帮助大家一起走进云计算的世界.下面新霸哥首先 ...
- Java连接MySQL数据库增删改查通用方法
版权声明:本文为博主原创文章,未经博主允许不得转载. Java连接MySQL数据库增删改查通用方法 运行环境:eclipse+MySQL 以前我们Java连接MySQL数据库都是一个数据库写一个类,类 ...
- Centos7 修改系统时区timezone
Centos7 修改系统时区timezone 注意:修改Linux系统的时区以后,再安装jvm,jvm默认会使用系统的时区.如果系统时区设置错误,安装jvm后,再修改系统的时区,但jvm的时区仍然用不 ...
- Java -- JDBC_利用反射及 JDBC 元数据编写通用的查询方法
先利用 SQL 进行查询,得到结果集: 利用反射创建实体类的对象:创建对象: 获取结果集的列的别名: 再获取结果集的每一列的值, 结合 3 得到一个 Map,键:列的别名,值:列的值: 再利用反射为 ...
- Java中使用最频繁及最通用的Java工具类
在Java中,工具类定义了一组公共方法,Java中使用最频繁及最通用的Java工具类. 一. org.apache.commons.io.IOUtils closeQuietly:关闭一个IO流.so ...
- <五>JDBC_利用反射及JDBC元数据编写通用的查询方法
此类针对javaBean类写了一个通用的查询方法,List<javaBean> 通用查询更新中...:通过学习,深刻体会到学会反射就等于掌握了java基础的半壁江山! 一.使用JDBC驱动 ...
随机推荐
- PHP网站常见安全漏洞 及相应防范措施总结
一.常见PHP网站安全漏洞 对于PHP的漏洞,目前常见的漏洞有五种.分别是Session文件漏洞.SQL注入漏洞.脚本命令执行漏洞.全局变量漏洞和文件漏洞.这里分别对这些漏洞进行简要的介绍. 1.se ...
- 小明同学喜欢体育锻炼,他常常去操场上跑步。跑道是一个圆形,在本题中,我们认为跑道是一个半径为R的圆形,设圆心的坐标原点(0,0)。小明跑步的起点坐标为(R,0),他沿着圆形跑道跑步,而且一直沿着一个方向跑步。回到家后,他查看了自己的计步器,计步器显示他跑步的总路程为L。小明想知道自己结束跑步时的坐标,但是他忘记自己是沿着顺时针方向还是逆时针方向跑的了。他想知道在这两种情况下的答案分别是多少。
include "stdafx.h" #include<iostream> #include<vector> #include<string> ...
- git是一种分布式代码管理工具,git通过树的形式记录文件的更改历史,比如: base'<--base<--A<--A' ^ | --- B<--B' 小米工程师常常需要寻找两个分支最近的分割点,即base.假设git 树是多叉树,请实现一个算法,计算git树上任意两点的最近分割点。 (假设git树节点数为n,用邻接矩阵的形式表示git树:字符串数组matrix包含n个字符串,每个字符串由字符'0
// ConsoleApplication10.cpp : 定义控制台应用程序的入口点. // #include "stdafx.h" #include <iostream& ...
- 【BZOJ2427】[HAOI2010]软件安装 Tarjan+树形背包
[BZOJ2427][HAOI2010]软件安装 Description 现在我们的手头有N个软件,对于一个软件i,它要占用Wi的磁盘空间,它的价值为Vi.我们希望从中选择一些软件安装到一台磁盘容量为 ...
- 【BZOJ2597】[Wc2007]剪刀石头布 最小费用流
[BZOJ2597][Wc2007]剪刀石头布 Description 在一些一对一游戏的比赛(如下棋.乒乓球和羽毛球的单打)中,我们经常会遇到A胜过B,B胜过C而C又胜过A的有趣情况,不妨形象的称之 ...
- linux自动ftp上传与下载文件的简单脚本
#!/bin/sh cd /data/backup/55mysql DATE=`date +'%Y%m%d'`file="55_mysql_"$DATE"03*.rar& ...
- HTML5(lufylegend.js练习)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding= ...
- 九度OJ 1013:开门人和关门人 (排序)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:5052 解决:2563 题目描述: 每天第一个到机房的人要把门打开,最后一个离开的人要把门关好.现有一堆杂乱的机房签到.签离记录,请 ...
- JS性能优化——加载和执行
JavaScript 在浏览器中的性能,可以认为是开发者所面临得最严重的可用性问题.这个问题因JavaScript的阻塞特性变得复杂, 也就是说当浏览器在执行JavaScript代码时,不能同时做其他 ...
- API的理解和使用——有序集合
有序集合常用的命令 命令 功能 zadd key score member [score member ... ] 添加元素 zcard key 计算成员个数 zscore key member 计算 ...