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/London
、Europe/Paris
、Asia/Kolkata
、Pacific/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/Region
format 的标准时区名称列表,请参阅***。【参考方案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 [重复]的主要内容,如果未能解决你的问题,请参考以下文章
Django:timezone.now 与 timezone.now()