Java 如何解析Datetime并将其与相应的时区关联
我正在尝试读取格式为Java 如何解析Datetime并将其与相应的时区关联,java,scala,date,datetime,timezone,Java,Scala,Date,Datetime,Timezone,我正在尝试读取格式为2019-12-23 13:35:00的字符串,以创建DateTime对象并将其与我知道它对应的特定时区关联(GMT-5) 我正试图这样做: val string1 = "2019-12-23 13:35:00" val sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss") sdf.setTimeZone(StaticDateTimeZone.forID("Etc/GMT-5").toTimeZone)
2019-12-23 13:35:00
的字符串,以创建DateTime对象并将其与我知道它对应的特定时区关联(GMT-5)
我正试图这样做:
val string1 = "2019-12-23 13:35:00"
val sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
sdf.setTimeZone(StaticDateTimeZone.forID("Etc/GMT-5").toTimeZone)
val date = sdf.parse(string1)
输出不是我想要的,因为它不是假设datetime不在GMT-5时区,而是在我的系统时区(GMT+0)中,将datetime调整为GMT-5如下:Mon Dec 23 08:35:00 GMT 2019
我如何创建一个不改变输入的datetime对象,而只是将一个时区与之关联?您似乎正在使用它,然后将其转换为java.util.Date
。您可以直接使用java 8中的java.time
包:
val string1 = "2019-12-23 13:35:00"
val formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")
val date = LocalDateTime.parse(string1, formatter)
date.atZone(ZoneId.of("Etc/GMT-5"))
其中:
date: java.time.LocalDateTime = 2019-12-23T13:35
res0: java.time.ZonedDateTime = 2019-12-23T13:35+05:00[Etc/GMT-5]
LocalDateTime
生成一个没有附加任何时区的日期。最后一行有效地从上一个日期创建了一个新的ZonedDateTime
,并将给定的时区添加到其上。如果需要返回到java.util.Date
,请参阅。- 我建议使用JodaTime李>
- JodaTime最适合使用时区
公共静态日期getDateWithTimeZone(字符串日期字符串、字符串格式、字符串时区){
DateFormat df=新的SimpleDataFormat(格式);
Date dateObj=null;
试一试{
dateObj=df.parse(dateString);
DateTime DateTime=新的DateTime(dateObj);
时区=时区。getTimeZone(时区);
返回dateTime.withZoneRetainFields(DateTimeZone.forTimeZone(zone))
.toDate();
}捕获(解析异常){
logger.error(“将字符串转换为日期时出错”,e);
}
返回null;
}
- 您可以根据需要更改方法/异常处理。 希望这有帮助
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String strDateTime = "2019-12-23 13:35:00";
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime ldt = LocalDateTime.parse(strDateTime, format);
ZoneId gmtZoneId = ZoneId.of("UTC+00:00");
ZoneId myZoneId = ZoneId.of("UTC-05:00");
System.out.println(format.format(ldt.atZone(gmtZoneId).withZoneSameInstant(myZoneId)));
}
}
输出:
2019-12-23 08:35:00
2019-12-23 08:35:00
帮助文档:
2019-12-23 08:35:00
2019-12-23 08:35:00
[更新]
根据Basil Bourque的评论发布以下代码:
import java.time.LocalDateTime;
import java.time.ZoneOffset;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
String strDateTime = "2019-12-23 13:35:00";
DateTimeFormatter format = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
LocalDateTime ldt = LocalDateTime.parse(strDateTime, format);
System.out.println(format.format(ldt.atZone(ZoneOffset.of("+00:00")).withZoneSameInstant(ZoneOffset.of("-05:00"))));
}
}
输出:
2019-12-23 08:35:00
2019-12-23 08:35:00
(使用Java语法而不是Scala)
tl;博士
我知道它所对应的特定时区(GMT-5)
GMT-5
不是时区,它只是一个偏移量。时区的名称为大陆/地区
格式,例如非洲/突尼斯
。时区是区域使用的偏移量变化的历史记录
您无法根据偏移量可靠地确定时区。许多时区在特定时刻可能共享相同的偏移量,但在其他时刻可能不同。所以你只是在胡乱猜测。仅当您确定知道特定区域时,才应用时区
相反,使用偏移量本身来确定力矩,不带区域。这里是一个单线解决方案
LocalDateTime // Represent a date with time-of-day but lacking the context of an offset-from-UTC or a time zone.
.parse( // When parsing, no need to specify a formatting pattern when the input complies with the ISO 8601 standard.
"2019-12-23 13:35:00".replace( " " , "T" ) // Comply with ISO 8601 standard formatting, replacing SPACE in the middle with an uppercase `T`.
) // Returns a `LocalDateTime` object.
.atOffset( // Determine a moment by placing the date and time-of-day of a `LocalDateTime` into the context of an offset-from-UTC.
ZoneOffset.ofHours( -5 ) // Represent an offset-from-UTC with `ZoneOffset`, merely a number of hours-minutes-seconds ahead or behind the prime meridian.
) // Returns a `OffsetDateTime` object.
.toString() // Generate text in standard ISO 8601 format.
2019-12-23T13:35-05:00
java.time
ISO 8601
您的输入字符串几乎是ISO8601标准格式。要遵守,用“<代码> t>代码>替换中间的空间。
String input = "2019-12-23 13:35:00".replace( " " , "T" ) ;
LocalDateTime
考虑到您的输入缺少时区或UTC偏移量,将其解析为LocalDateTime
LocalDateTime ldt = LocalDateTime.parse( input ) ;
请注意,LocalDateTime
不是一个时刻,也不是时间线上的一个点。在您的示例中,大约下午1:30,我们不知道这是指日本东京的下午1:30,还是美国俄亥俄州托莱多的下午1:30,这两个时刻相差很多小时
OffsetDateTime
您声称明确知道该日期和时间是通过UTC后五小时(通常在本初子午线以西)的偏移镜头看到的
因此,让我们应用ZoneOffset
来获得OffsetDateTime
OffsetDateTime odt = ldt.atOffset( offset ) ;
看这个
odt.toString():2019-12-23T13:35-05:00
ZoneDateTime
时区总是比仅从UTC偏移更可取。偏移量是小时数——分秒,仅此而已。时区更重要。时区是特定地区人民使用的偏移量的过去、现在和未来变化的历史
但不要猜测时区。仅当您知道LocalDateTime
对象最初用于该区域时,才应用区域
以大陆/地区
的格式指定,例如美国/蒙特利尔
,非洲/卡萨布兰卡
,或太平洋/奥克兰
。切勿使用2-4个字母的缩写,如EST
或IST
,因为它们不是真正的时区,也不是标准化的,甚至不是唯一的(!)
关于java.time 该框架内置于Java8及更高版本中。这些类取代了麻烦的旧日期时间类,例如,& 要了解更多信息,请参阅。并搜索堆栈溢出以获得许多示例和解释。规格是 该项目现已启动,建议迁移到类 您可以直接与数据库交换java.time对象。使用兼容的或更高版本。不需要字符串,也不需要
java.sql.*
类
从哪里获得java.time类
- 、和更高版本-标准Java API的一部分,带有捆绑实现。
- Java9添加了一些次要功能和修复
- 及
- 大多数java.time功能都在中向后移植到Java6和Java7
-
- 更高版本的Android捆绑包实现了java.time类
- 对于早期的Android(仅供参考:该项目现在正在进行中。它的创建者继续领导定义内置于Java 8+中的类。请参阅。基本上是正确的,但您应该使用
进行偏移,而不是ZoneOffset
,后者用于时区。谢谢,这是最完整的ZoneId