问题描述
我收到的字符串格式如下:“ yyyy-MM-dd'T'HH:mm:ssZ”,例如:2020-09-09T09:58:00 + 0000”,偏移量是UTC。
我需要在不应用偏移量“ +0000”的情况下将字符串转换为Date对象,但是在运行代码时,我会得到不同的时间:
cable_ready["MyChannel"].morph(
selector: "string",# required - string containing a CSS selector or XPath expression
html: "string",# [null] - the HTML to assign
children_only: true|false,# [null] - indicates if only child nodes should be morphed... skipping the parent element
permanent_attribute_name: "string",# [null] - an attribute name that prevents elements from being updated i.e. "data-permanent"
focus_selector: "string",# [null] - string containing a CSS selector
)
您可以在上方看到日期已更改。
相反,我想保留相同的日期和时间,例如:Wed Sep 09 09:58:00,所以我可以将此Date对象转换为带有“ yyyy-MM-dd”,“ HH:mm: ss”和“ yyyy-MM-dd'T'HH:mm:ss”格式。
解决方法
我建议您使用modern java.time
日期时间API和相应的格式API(软件包java.time.format
)来完成此操作。从 Trail: Date Time 了解有关现代日期时间API的更多信息。
import java.time.OffsetDateTime;
import java.time.format.DateTimeFormatter;
public class Main {
public static void main(String[] args) {
// The given date-time string
String strDateTime = "2020-09-09T09:58:00+0000";
// Define the formatter
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ssZ");
// Parse the given date-time string into OffsetDateTime
OffsetDateTime odt = OffsetDateTime.parse(strDateTime,formatter);
// Output OffsetDateTime in the default format
System.out.println(odt);
// Print OffsetDateTime using the defined formatter
String formatted = formatter.format(odt);
System.out.println(formatted);
}
}
输出:
2020-09-09T09:58Z
2020-09-09T09:58:00+0000
注意:java.util.Date
不代表日期/时间对象。它只是表示否。距1970-01-01T00:00:00Z
的毫秒数。它没有任何时区或时区偏移信息。在打印时,Java将打印通过应用JVM的时区获得的字符串。建议您停止使用java.util.Date
并切换到现代的日期时间API。
使用joda日期时间API,您可以执行以下操作:
import org.joda.time.DateTime;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.ISODateTimeFormat;
public class Main {
public static void main(String[] args) {
// The given date-time string
String strDateTime = "2020-09-09T09:58:00+0000";
// Define the formatter
DateTimeFormatter isoFormat = ISODateTimeFormat.dateTimeParser();
DateTime dateTime = isoFormat.parseDateTime("2020-09-09T09:58:00+0000");
// Display DateTime in the default format
System.out.println(dateTime);
// Define formatter for ouput
DateTimeFormatter outputFormat = DateTimeFormat.forPattern("yyyy-MM-dd'T'HH:mm:ssZ").withZoneUTC();
// Display DateTime in the defined output format
String formatted = outputFormat.print(dateTime);
System.out.println(formatted);
}
}
输出:
2020-09-09T10:58:00.000+01:00
2020-09-09T09:58:00+0000
,
答案的第一个也是最重要的部分是:不要转换为老式的Date
。坚持使用Joda-Time或迁移到现代Java日期和时间API java.time,这已经在Arvind Kumar Avinash的良好回答中提到了。
由于您已经在使用Joda-Time,因此我向您展示了Joda-Time解决方案。说服格式化程序保持解析的字符串的时间和偏移量的技巧是withOffsetParsed()
。
DateTimeFormatter isoFormat
= ISODateTimeFormat.dateTimeParser().withOffsetParsed();
String incomingString = "2020-09-09T09:58:00+0000";
DateTime dateTime = isoFormat.parseDateTime(incomingString);
但是!如果我正确地猜想您要使用UTC存储日期和时间(建议的做法),则比withOffsetParsed()
更好的是在解析器上指定UTC:
DateTimeFormatter isoFormat
= ISODateTimeFormat.dateTimeParser().withZoneUTC();
现在,如果有一天输入非零UTC偏移量的字符串,您还将获得正确的时间。
无论如何,我们现在都可以将获取的DateTime
格式化为您请求的字符串。
String dateString = dateTime.toString(ISODateTimeFormat.date());
System.out.println(dateString);
String timeString = dateTime.toString(ISODateTimeFormat.hourMinuteSecond());
System.out.println(timeString);
String dateTimeString = dateTime.toString(ISODateTimeFormat.dateHourMinuteSecond());
System.out.println(dateTimeString);
输出:
2020-09-09 09:58:00 2020-09-09T09:58:00
使用Date
有什么问题?首先,Date
类的设计不佳,而且已经过时了。其次,Date
只是一个时间点,它没有日期和时间的概念(他们尝试在Java 1.0中将其构建到日期中,但是在1997年的Java 1.1中放弃并弃用了它。 )。因此,Date
无法为您保存UTC中的日期和时间。
代码中发生的事情是,您得到了一个Date
来代表正确的时间点。仅当您打印该Date
时,您才隐式调用其toString
方法。 Date.toString()
令人困惑地获取了JVM的时区设置(在您的情况下,显然是北美东部时间),并将其用于呈现要返回的字符串。因此,在您的情况下,时间点将显示为Wed Sep 09 05:58:00 EDT 2020
。