Java,解析字符串';yyyy-MM-dd';T';HH:mm:ss';在不更改时间的情况下分区DateTime
我有一个字符串“2018-07-24T01:30:27”。我想将其解析为带EST时区的ZonedDateTime,而不更改时间 我有密码Java,解析字符串';yyyy-MM-dd';T';HH:mm:ss';在不更改时间的情况下分区DateTime,java,spring-boot,timezone,simpledateformat,zoneddatetime,Java,Spring Boot,Timezone,Simpledateformat,Zoneddatetime,我有一个字符串“2018-07-24T01:30:27”。我想将其解析为带EST时区的ZonedDateTime,而不更改时间 我有密码 String foo = "2018-07-24T01:30:27"; ZoneId zone = ZoneId.of("America/New_York"); SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:
String foo = "2018-07-24T01:30:27";
ZoneId zone = ZoneId.of("America/New_York");
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss");
return simpleDateFormat.parse(foo).toInstant().atZone(zone);
返回值为
2018-07-24T02:30:27-04:00[America/New_York]
我也尝试过创建这个类,但是没有帮助
@Configuration
public class TimeZoneConfig {
@PostConstruct
public void init() {
TimeZone.setDefault(TimeZone.getTimeZone("EST"));
System.out.println("Date in UTC: " + new Date().toString());
}
}
请问,我可以得到一些建议吗?< /P> < P>因为您想要<代码> ZONDATEDATECTON//> >考虑使用<代码> DateTimeFormatter <代码> >代码> java。
String foo = "2018-07-24T01:30:27";
ZoneId zone = ZoneId.of("America/New_York");
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ss");
TemporalAccessor temporalAccessor = dateTimeFormatter.withZone(zone).parse(foo);
return ZonedDateTime.from(temporalAccessor);
返回的ZoneDateTime
将是:
2018-07-24T01:30:27-04:00[America/New_York]
当你知道怎么做的时候,事情就这么简单了。输出为:
2018-07-24T01:30:27-04:00[美国/纽约]
信息:
ZoneId
和ZoneDateTime
),请远离SimpleDateFormat
和朋友。顺便说一句,在任何情况下都要远离他们SimpleDataFormat
是一个臭名昭著的麻烦制造者SimpleDataFormat
假定字符串位于JVM的默认时区,因此从该时区转换而来。接下来,您将转换到美国/纽约(东部夏时制或EDT),从而相应地更改一天中的小时数
设置JVM的默认时区不起作用的原因是TimeZone
需要东部标准时间(与CST和PST相反),但7月份纽约是东部夏时制,因此仍有转换发生。但正如我所说的,你无论如何都不想设置默认时区
链接
tl;博士
在java.time中使用具体类
答案是正确的,但有点迟钝。它显式地使用接口。通常在Java中,这将是一件好事。但是java.time类是为应用程序作者设计的,用于调用具体类而不是接口。引用Javadoc:
此接口是框架级接口,不应在应用程序代码中广泛使用。相反,应用程序应该创建并传递具体类型的实例,例如LocalDate。原因有很多,其中一部分是该接口的实现可能在ISO以外的日历系统中。有关这些问题的更全面讨论,请参见ChronoLocalDate
LocalDateTime
那我们就这么做吧。首先,将输入解析为LocalDateTime
。此类不代表一个时刻,也不是时间线上的一个点,因为它缺少时区或偏移的上下文
String input = "2018-07-24T01:30:27" ;
LocalDateTime ldt = LocalDateTime.parse( input ) ;
ZoneDateTime
提供时区的上下文
ZoneId zone = ZoneId.of( "America/New_York" ) ;
ZonedDateTime zdt = ldt.atZone( zone ) ;
Instant
如果您希望看到将同一时刻调整为UTC,请提取一个Instant
对象
Instant instant = zdt.toInstant() ;
不要弄乱默认时区
TimeZone.setDefault
除非万不得已,否则不要设置JVM的当前默认时区。这样做会影响该JVM中所有应用程序的所有线程中的所有代码
相反,编写java.time代码以显式指定所需/预期的时区。切勿忽略各种方法的可选时区或偏移量
关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,& 要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是 该项目现已启动,建议迁移到类 您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*
类。Hibernate5和JPA2.2支持java.time
从哪里获得java.time类
- 、和更高版本-标准Java API的一部分,带有捆绑实现。
- 带来了一些小功能和修复
- 及
- 大多数java.time功能都在中向后移植到Java6和Java7
-
- Android(26+)的更高版本捆绑了java.time类的实现
- 对于早期的Android(你有
。你不再需要使用DateTimeFormatter
。我得到一个“无法从TemporalAccessor获取ZoneDateTime”尝试切换时出错。我想这是因为我的字符串中没有时区信息?LocalDateTime.parse可以工作,但ZonedDateTime.parse不能工作。是的,就是这样。但是您可以使用SimpleDateFormat
为格式化程序分配一个区域。谢谢!成功了:)(1)不要混淆旧的和现代的。如果您可以使用java.time,即现代的Jvaa日期和时间API(withZone
和ZoneId
),请远离过时的ZoneDateTime
和朋友。(2) 不要设置或依赖JVM的默认时区。它可以从程序的任何其他部分以及在同一JVM中运行的任何其他程序更改为其他内容。(3) 不要依赖三个字母的时区缩写,比如EST。它们往往模棱两可。EST可能意味着澳大利亚东部标准时间和北美东部标准时间,它们都不是时区(美国/纽约是其中之一)。这是黄金:永远不要忽略可选时区或各种方法的偏移量。谢谢你写得很好,回答得很透彻。SimpleDateFormat
ZoneId zone = ZoneId.of( "America/New_York" ) ; ZonedDateTime zdt = ldt.atZone( zone ) ;
Instant instant = zdt.toInstant() ;