繁体   English   中英

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

[英]How to convert date and time to user timezone

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))未按时区返回正确的日期和时间,如何解决此问题?

Date类只是绕过“历元”(毫秒)(1970年1月1日,00:00:00 GMT)的毫秒数的精简包装。 它不存储任何时区信息。 在上一次调用中,您正在将日期实例添加到String ,该实例隐式调用toString()方法。 toString()方法将使用默认时区来创建表示实例的String (因为它不存储任何时区信息)。 尝试修改最后一行以避免使用toString()方法。

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

为了方便起见,请尝试使用joda-Time API 例子在这里

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

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),但这只会使事情变得混乱。

使用正确的描述性时区名称来检索包含DST和其他问题的时区对象。

乔达时代

与Java捆绑在一起的java.util.Date和Calendar类非常麻烦。 避免他们。 使用与Java 8捆绑在一起的Joda-Time或新的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.time

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

Instant类以UTC表示时间轴上的时刻,分辨率为纳秒 (最多十进制的九(9)位数字)。

Instant instant = Instant.now();

应用时区。

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

instantzdt代表相同的时刻,时间轴上的相同点。 每个镜头都是通过不同区域的挂钟时间的镜头看到的。

通过指定格式化模式或通过让java.time自动本地化来生成String。

要本地化,请指定:

  • FormatStyle确定字符串应为多长时间或缩写。
  • Locale来确定(一)一天的名称翻译的人类语言,一个月的名称,这样,和(b)文化规范决定的缩写,大小写,标点符号,这样的问题。

例:

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

Unfortunatley Java日期仅以GMT返回时间。 无论何时要在前端或某些位置显示,都需要使用在step1中生成的格式化字符串。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM