Java 8 – 使用 TimeZone 从 LocalDateTime 创建 Instant [重复]

Posted

技术标签:

【中文标题】Java 8 – 使用 TimeZone 从 LocalDateTime 创建 Instant [重复]【英文标题】:Java 8 – Create Instant from LocalDateTime with TimeZone [duplicate] 【发布时间】:2017-11-18 01:08:58 【问题描述】:

我有一个日期以字符串格式 ddMMyyyy 和 hh:mm 和 TimeZone 存储在数据库中。 我想根据这些信息创建一个 Instant,但我不知道该怎么做。

类似

LocalDateTime dateTime = LocalDateTime.of(2017, Month.JUNE, 1, 13, 39);
Instant instant = dateTime.toInstant(TimeZone.getTimeZone("ECT"));

【问题讨论】:

你的意思是ZonedDateTime.ofInstant(instant, TimeZone.getDefault()) 吗? @soorapadman 这将返回 ZonedDateTime。 OP 想要一个 Instant。 永远不要使用 3-4 个字符的缩写来表示时区。 这些是实时时区,没有标准化,甚至不是唯一的!以continent/region 的格式使用true time zone names,例如Europe/LondonEurope/ParisAsia/KolkataPacific/Auckland。如果“ECT”是指厄瓜多尔时间,请使用ZoneId.of( "America/Guayaquil" )。如果您指的是中欧,请使用适当的 Europe/… 区域名称。 此问题不是与该链接问题重复。这个问题与毫秒数没有直接关系。 “我有一个日期以字符串格式 ddMMyyyy 和 hh:mm 和 TimeZone 存储在数据库中。”不,如果您在定义 DB 列时使用了日期时间数据类型,例如 TIMESTAMP WITH TIME ZONE(您应该这样做),则不会。日期时间列没有“格式”,因为它们是 not 字符串/文本。检索日期时间值作为日期时间对象而不是字符串。 Instant instant = myResultSet.getObject( … , Instant.class ) ; 【参考方案1】:

你可以先用那个时区创建一个ZonedDateTime,然后调用toInstant

LocalDateTime dateTime = LocalDateTime.of(2017, Month.JUNE, 15, 13, 39);
Instant instant = dateTime.atZone(ZoneId.of("Europe/Paris")).toInstant();
System.out.println(instant); // 2017-06-15T11:39:00Z

我也改用完整的时区名称(根据 Basil 的建议),因为它不那么模棱两可。

【讨论】:

几乎是一个完美的答案,但您不应该鼓励使用 3-4 个字母的伪时区代码。而是以continent/region 格式使用true time zone names。我猜作者是指“ECT”的厄瓜多尔时间ZoneId.of( "America/Guayaquil" ) ) @BasilBourque "ECT" 实际上是欧洲中部时间 (Europe/Paris),所以我明白为什么使用全名会更好;) 我只将“CET”视为中欧时间。但这就是重点,这 3-4 个字母的代码是模棱两可的噩梦,应该像瘟疫一样避免。 @Line A 日期不明确。法国巴黎午夜过后几分钟是新的一天,而魁北克蒙特利尔仍然是“昨天”。如果您希望日期采用 UTC,请使用 OffsetDateTime 确定时刻:OffsetDateTime.of( LocalDate.of( 2018 , 1 , 23 ) , LocalTime.MIN , ZoneOffset.UTC ) 因为 2-4 个字母的缩写(ET、PST、EST、CST、IST 等)不是真正的时区,不是标准化的,也不是唯一的。例如:IST = 冰岛标准时间、爱尔兰标准时间、印度标准时间等。有关Continent/Regionformat 的标准时区名称列表,请参阅***。【参考方案2】:

忘记旧的 TimeZone 类。使用ZoneId,因为它是适当的线程安全的,您可以只使用最终静态字段来存储区域。

LocalDateTime dateTime = LocalDateTime.of(2017, Month.JUNE, 1, 13, 39);
ZonedDateTime.of(dateTime, ZoneId.of("ECT")).toInstant();

【讨论】:

【参考方案3】:

我认为下面的代码应该可以工作:

LocalDateTime time = LocalDateTime.of(2017, Month.JUNE, 15, 13, 39);
ZonedDateTime.of(time, TimeZone.getTimeZone("ZONE").toZoneId()).toInstant();

您只需将“ZONE”替换为您需要的时区。

【讨论】:

不,TimeZone 是遗留类,现在被 ZoneId 和 ZoneOffset 取代。避免使用旧的日期时间类。当然不要将遗留类与 java.time 类混合。请更正或删除您的答案。

以上是关于Java 8 – 使用 TimeZone 从 LocalDateTime 创建 Instant [重复]的主要内容,如果未能解决你的问题,请参考以下文章

JAVA插入数据到MySql少了8小时

JAVA中的时区设置

Django:timezone.now 与 timezone.now()

firebase:InstantiationException:无法实例化抽象类 java.util.TimeZone

在java中如何处理日期格式问题

Java - 我怎样才能获得一个 K-hour-shifted TimeZone?