首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将CST时区转换为必需的时区Java

将CST时区转换为必需的时区Java
EN

Stack Overflow用户
提问于 2018-11-05 21:37:21
回答 2查看 2.3K关注 0票数 0

我需要将CST中的日期转换为所需的时区。我将得到日期字符串,如"11/5/2018 12:54:20“,这是在科技委时区。我必须将其转换为作为参数传递的时区。假设让我们把它当作"GMT+0530“。上述日期的结果最好是“2018年11月6日00:24:20”。

我尝试了下面的代码,它将传递日期(11/05/ 2018 12:54:20)改为相同(2018年11月6日00:24:20)。我在一个有IST时区的系统上执行了这个命令。

代码语言:javascript
复制
    SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("GMT-0600"));
    SimpleDateFormat sdf2 = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
    sdf.setTimeZone(TimeZone.getTimeZone("GMT+0530"));
    System.out.println(sdf2.format(sdf.parse("11/5/2018 12:54:20").getTime()));

编辑:答案:

代码语言:javascript
复制
    DateTimeFormatter f = DateTimeFormatter.ofPattern( "M/d/uuuu HH:mm:ss" ) ;
    LocalDateTime ldt = LocalDateTime.parse( "11/5/2018 12:54:20" , f ) ;
    ZoneId z = ZoneId.of( "GMT-0600" ) ;
    ZonedDateTime zdt = ldt.atZone( z ) ;
    System.out.println(zdt);
    ZoneId zKolkata = ZoneId.of( "GMT+0530" ) ;
    ZonedDateTime zdtKolkata = zdt.withZoneSameInstant( zKolkata ) ;
    System.out.println(zdtKolkata);
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-11-05 21:45:36

tl;dr

代码语言:javascript
复制
LocalDateTime                                            // Represent a date and a time-of-day, without offset nor zone. So *not* a moment, *not* a point on the timeline.
.parse( 
    "11/5/2018 12:54:20" , 
    DateTimeFormatter.ofPattern( "d/M/uuuu HH:mm:ss" )   // Define a formatting pattern to match your input string.
)                                                        // Returns a `LocalDateTime`.
.atZone(                                                 // Assign a time zone, to give meaning to the `LocalDateTime` object, making it a `ZonedDateTime` object.
    ZoneId.of( "America/New_York" )                      // Define a time zone properly with `Continent/Region` naming, never 2-4 letter pseudo-zones such as CST or IST.
)                                                        // Returns a `ZonedDateTime` object.
.withZoneSameInstant(                                    // Adjust from New York time to Kolkata time. Some moment, different wall-clock time.
    ZoneId.of( "Asia/Kolkata" )
)                                                        // Returns another `ZonedDateTime` object rather than altering (“mutating”) the original, per Immutable Objects pattern.
.toString()                                              // Generate text in standard ISO 8601 format, wisely extended to append the name of the time zone in square brackets.

2018-05-11T22:24:20+05:30亚洲/加尔各答

java.time

您正在使用可怕的旧类,现在已被java.time类所取代。

将输入字符串解析为LocalDateTime,因为它缺少从UTC或时区偏移的任何指示。

定义与输入相匹配的格式模式。

代码语言:javascript
复制
DateTimeFormatter f = DateTimeFormatter.ofPattern( "d/M/uuuu HH:mm:ss" ) ;
LocalDateTime ldt = LocalDateTime.parse( "11/5/2018 12:54:20" , f ) ;

ldt.toString():2018-05-11T12:54:20

你说这是为CST设计的。你是说中国标准时间吗?还是北美的中央标准时间?

continent/region格式指定continent/region,如America/MontrealAfrica/CasablancaPacific/Auckland。不要使用2-4字母的缩写,如CSTESTIST,因为它们不是真正的时区,不标准化,甚至不是唯一的(!)。

我猜你指的是纽约时间之类的东西。

代码语言:javascript
复制
ZoneId z = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;

zdt.toString():2018-05-11T12:54:20-04:00美国/纽约

显然,你想通过不同地区、不同时区的人使用的挂钟时间的镜头看到同样的时刻。IST是指爱尔兰标准时间吗?还是印度标准时间?同样,使用实时时区而不是这些2-4字符的伪区域.

代码语言:javascript
复制
ZoneId zKolkata = ZoneId.of( "Asia/Kolkata" ) ;
ZonedDateTime zdtKolkata = zdt.withZoneSameInstant( zKolkata ) ;

zdtKolkata.toString():2018-05-11T22:24:20+05:30亚洲/加尔各答

要查看UTC中的相同时刻,请提取一个Instant

代码语言:javascript
复制
Instant instant = zdtKolkata.toInstant() ;

instant.toString():2018-05-11T16:54:20Z

所有这三个( zdtzdtKolkatainstant )都代表着时间线上相同的时刻,相同的点。

相反,ldt作为一个LocalDateTime对象并不表示时间,也不是时间线上的一个点。它没有真正的意义,直到你给它指定一个时区给它一个上下文。在划定该区域之前,我们不知道在澳大利亚、非洲或美国是否意味着中午时间。它可能意味着大约26-27个小时的任何一个,全球范围内的时区。

ISO 8601

不要发明自己的格式来交换日期-时间值作为文本,而是使用标准的ISO 8601格式。

java.time类在生成/解析字符串时默认使用ISO 8601格式。

关于java.time

http://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html框架内置到Java8和更高版本中。这些类取代了麻烦的旧遗赠日期时间类,如java.util.DateCalendarSimpleDateFormat

http://www.joda.org/joda-time/项目现在在维护模式中,建议迁移到java.time类。

要了解更多信息,请参见http://docs.oracle.com/javase/tutorial/datetime/TOC.html。并搜索堆栈溢出以获得许多示例和解释。规范是JSR 310

您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC 4.2。不需要字符串,也不需要java.sql.*类。

在哪里获得java.time类?

  • Java 8Java 9Java 10Java 11和更高版本--捆绑实现的标准Java的一部分。
    • Java 9添加了一些次要的特性和修复。

  • Java 6Java 7
    • 大多数java.time功能都是在http://www.threeten.org/threetenbp/中移植到Java6&7中的。

  • 安卓
    • 较晚版本的Android实现的java.time类。
    • 对于早期的Android (<26),https://github.com/JakeWharton/ThreeTenABP项目采用了http://www.threeten.org/threetenbp/ (上面提到的)。见http://stackoverflow.com/q/38922754/642706

三次-额外项目使用其他类扩展java.time。这个项目是将来可能加入java.time的试验场。您可以在这里找到一些有用的类,如IntervalYearWeekYearQuarter更多

票数 2
EN

Stack Overflow用户

发布于 2018-11-05 21:46:55

您将sdf的时区设置两次,而不是设置sdf2的时区,从而得到不正确的结果。而且,在将对象传递给getTime()时,不需要调用DateFormat::format()

下面是您的代码的固定版本:

代码语言:javascript
复制
SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
TimeZone cstTimeZone = TimeZone.getTimeZone("CST");
sdf.setTimeZone(cstTimeZone);

SimpleDateFormat sdf2 = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");
sdf2.setTimeZone(TimeZone.getTimeZone("GMT+0530"));
System.out.println(sdf2.format(sdf.parse("11/5/2018 12:54:20")));

请注意,您使用的类非常旧,而且自版本8以来,Java提供了新的日期和时间API

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/53162599

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档