我试图以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)输出不是我想要的,因为它不是假设日期时间不在GMT-5时区,而是在我的系统的时区(GMT+0)中,将日期时间调整为GMT-5,如下所示:Mon Dec 23 08:35:00 GMT 2019。
如何创建不更改输入的datetime对象,并将时区与其关联?
发布于 2019-12-24 21:59:44
(使用Java语法而不是Scala)
tl;dr
我知道它对应的特定时区(格林尼治标准时间-5)
GMT-5是,不是时区,它只是偏移量。时区具有Continent/Region格式的名称,如Africa/Tunis。时区是区域使用的偏移量变化的历史记录。
无法从偏移量可靠地确定时区。许多时区在某一特定时刻可能共享相同的偏移量,但在其他时刻则可能有所不同。所以你只会胡思乱想。只有当您确实了解特定区域时,才应用时区。
相反,使用偏移量本身来确定时间,而不是区域。这里有一个单行解决方案。
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
您的输入字符串几乎采用ISO 8601标准格式。若要符合要求,请将中间的空格替换为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下午1:30在俄亥俄州托莱多,两个非常不同的时刻相隔许多小时。
OffsetDateTime
您可以肯定地知道,这个日期和时间是通过UTC后5小时(通常是在主子午线以西)偏移的镜头看到的。
ZoneOffset offset = ZoneOffset.ofHours( -5 ) ; // Five hours before UTC.因此,让我们应用这个ZoneOffset来获得一个OffsetDateTime。
OffsetDateTime odt = ldt.atOffset( offset ) ;odt.toString():2019-12-23T13:35-05:00
ZonedDateTime
时区总是比与世界协调时相距更好的时区.偏移是几个小时--分-秒,仅此而已。时区更重要。时区是过去、现在和未来对特定地区人民使用的偏移量的变化的历史。
但不要在时区猜测。仅当您知道LocalDateTime对象最初用于该区域时,才应用区域。
以Continent/Region格式指定Continent/Region,如America/Montreal、Africa/Casablanca或Pacific/Auckland。不要使用2-4字母的缩写,如EST或IST,因为它们不是真正的时区,不标准化,甚至不是唯一的(!)。
ZoneId z = ZoneId.of( "America/Panama" ) ;
ZonedDateTime zdt = ldt.atZone( z ) ;

关于java.time
https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/time/package-summary.html框架内置到Java8和更高版本中。这些类取代了麻烦的旧遗赠日期时间类,如java.util.Date、Calendar和SimpleDateFormat。
要了解更多信息,请参见http://docs.oracle.com/javase/tutorial/datetime/TOC.html。并搜索堆栈溢出以获得许多示例和解释。规范是JSR 310。
http://www.joda.org/joda-time/项目现在在维护模式中,建议迁移到java.time类。
您可以直接与数据库交换java.time对象。使用与JDBC 4.2或更高版本兼容的JDBC 4.2。不需要字符串,也不需要java.sql.*类。
在哪里获得java.time类?
三次-额外项目使用其他类扩展java.time。这个项目是将来可能加入java.time的试验场。您可以在这里找到一些有用的类,如Interval、YearWeek、YearQuarter和更多。
发布于 2019-12-24 20:42:31
您似乎正在使用JodaTime,然后转换为java.util.Date。您可以直接使用Java8中的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,请参阅这个答案。
发布于 2019-12-24 21:20:16
例如,我编写了一个方法:
public static Date getDateWithTimeZone(String dateString, String format, String timeZone) {
DateFormat df = new SimpleDateFormat(format);
Date dateObj = null;
try {
dateObj = df.parse(dateString);
DateTime dateTime = new DateTime(dateObj);
TimeZone zone = TimeZone.getTimeZone(timeZone);
return dateTime.withZoneRetainFields(DateTimeZone.forTimeZone(zone))
.toDate();
} catch (ParseException e) {
logger.error("Error while converting string to date",e);
}
return null;
}https://stackoverflow.com/questions/59473083
复制相似问题