如何日期和时间转换为用户时区

问题描述:

Calendar cal = Calendar.getInstance(); 
cal.setTimeZone(TimeZone.getTimeZone("PST")); 
cal.setTime(new Date()); 

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss a"); 

Date resultdate = new Date(cal.getTimeInMillis()); 
sdf.setTimeZone(TimeZone.getTimeZone("PST")); 

System.out.println("String date:"+sdf.format(resultdate)); 
System.out.println("Date:"+sdf.parse(sdf.format(resultdate))); 

输出:如何日期和时间转换为用户时区

String date:2011-12-29 09:01:58 PM            
Date:Fri Dec 30 10:31:58 IST 2011 

问题:

  1. sdf.format(resultdate)返回正确的日期和时间为每个时区。但是,
  2. sdf.parse(sdf.format(resultdate))不按照时区返回正确的日期和时间,如何解决这个问题?
+0

你可以只使用[乔达时间](http://joda-time.sourceforge.net/)? – 2011-12-30 05:13:00

Unfortunatley Java日期以GMT格式返回时间。如果您想要在前端或某处显示,则需要使用step1中生成的格式化字符串。

Date这个类仅仅是围绕“时代”(1970年1月1日,格林威治标准时间00:00:00)毫秒数的薄包装。它不存储任何时区信息。在上次调用中,您将一个日期实例添加到String,这隐含地调用toString()方法。 toString()方法将使用默认时区来创建代表实例的String(因为它不存储任何时区信息)。尝试修改最后一行以避免使用toString()方法。

System.out.println("Date:" + sdf.format(sdf.parse(sdf.format(resultdate)))); 

尝试使用joda-Time api为了您的方便。例子是here

请尝试下面的代码,它会工作。

Calendar cal = Calendar.getInstance(); 
cal.setTimeZone(TimeZone.getTimeZone("PST")); 
cal.setTime(new Date()); 

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss a"); 
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss a"); 

Date resultdate = new Date(cal.getTimeInMillis()); 
sdf.setTimeZone(TimeZone.getTimeZone("PST")); 

System.out.println("String date:"+sdf.format(resultdate)); 
System.out.println("Date:"+sdf2.parse(sdf.format(resultdate))); 

三字母时区代码

避免使用三字母时区代码。它们既不标准也不唯一。例如,IST表示爱尔兰标准时间印度标准时间。此外,这些代码旨在区分夏令时(DST),但这只会让事情混淆不清。

使用正确的descriptive time zone names来检索包含DST和其他问题的时区对象。

乔达时间

与Java捆绑与java.util.Date & Calendar类是出了名的麻烦。避免它们。使用Joda-Time或与Java 8捆绑的新java.time。*包。

在JodaTime中,DateTime对象真正知道它自己的时区(与java.util.Date不同)。通常我们使用Joda-Time中的不可变类。因此,我们不是在DateTime对象中更改时区,而是基于旧的但具有指定的差异的DateTime对象创建新的新的对象。不同的时区可能就是这种差异。

以下是一些示例代码。

DateTimeZone timeZone_India = DateTimeZone.forID("Asia/Kolkata"); 
DateTimeZone timeZone_Ireland = DateTimeZone.forID("Europe/Dublin"); 
DateTimeZone timeZone_US_West_Coast = DateTimeZone.forID("America/Los_Angeles"); 

DateTime now = new DateTime(timeZone_India); 

System.out.println("now in India: " + now); 
System.out.println("now in Ireland: " + now.withZone(timeZone_Ireland)); 
System.out.println("now in US West Coast: " + now.withZone(timeZone_US_West_Coast)); 
System.out.println("now in UTC/GMT: " + now.withZone(DateTimeZone.UTC)); 

当运行...

now in India: 2014-02-10T13:52:27.875+05:30 
now in Ireland: 2014-02-10T08:22:27.875Z 
now in US West Coast: 2014-02-10T00:22:27.875-08:00 
now in UTC/GMT: 2014-02-10T08:22:27.875Z 

的Java。时间

使用取代Joda-Time的java.time类的相同想法。

Instant类代表UTC中的时间轴上的一个时刻,分辨率为nanoseconds(最多九(9)位小数)。

Instant instant = Instant.now(); 

应用时区。

ZoneId z = ZoneId.of("America/Montreal"); 
ZonedDateTime zdt = instant.atZone(z); 

instantzdt代表同一时刻,在时间轴上的相同点。通过不同区域的镜头wall-clock time可以看到每个镜头。

通过指定格式化模式或让java.time自动进行本地化来生成字符串。

要本地化,指定:

  • FormatStyle确定字符串应该多长或缩写是。
  • Locale确定(a)翻译日期名称,月份名称等的人类语言,以及(b)确定缩写,大写,标点等问题的文化规范。

例子:

Locale l = Locale.CANADA_FRENCH ; 
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime(FormatStyle.FULL).withLocale(l); 
String output = zdt.format(f);