1. Overview
1.概述
In this tutorial, we’ll show how we can convert Date objects to String objects in Java. To do so, we’ll work with the older java.util.Date type as well as with the new Date/Time API introduced in Java 8.
在本教程中,我们将展示如何在Java中将日期对象转换为字符串对象。为此,我们将使用旧的java.util.Date类型,以及Java 8中引入的新的Date/Time API。
If you’d like to learn how to do the opposite conversion, i.e., from String to Date types, you can check out this tutorial here.
如果你想学习如何进行相反的转换,即从字符串到日期类型,你可以查看这里的教程。
For more details regarding new Date/Time API, please see this related tutorial.
关于新的Date/Time API的更多细节,请参见这个相关教程。
2. Converting java.util.Date to String
2.将java.util.Date转换为String
Although we shouldn’t use java.util.Date if we’re working with Java 8, sometimes we have no choice (e.g., we’re receiving the Date object from a library that isn’t in our control).
尽管如果我们使用 Java 8,就不应该使用 java.util.Date,但有时我们别无选择(例如,我们从一个不受我们控制的库中接收 Date 对象)。
In such cases, we have several ways to convert java.util.Date to String at our disposal.
在这种情况下,我们有几种方法可以将java.util.Date转换成String,供我们使用。
2.1. Preparing the Date Object
2.1.准备Date对象
Let’s first declare an expected String representation of our date and define a pattern of desired date format:
让我们首先声明我们的日期的预期String表示,并定义一个期望的日期格式模式。
private static final String EXPECTED_STRING_DATE = "Aug 1, 2018 12:00 PM";
private static final String DATE_FORMAT = "MMM d, yyyy HH:mm a";
Now we need actual Date object that we’d like to convert. We’ll use a Calendar instance to create it:
现在我们需要实际的Date对象,我们想转换它。我们将使用一个Calendar实例来创建它。
TimeZone.setDefault(TimeZone.getTimeZone("CET"));
Calendar calendar = Calendar.getInstance();
calendar.set(2018, Calendar.AUGUST, 1, 12, 0);
Date date = calendar.getTime();
We’ve set default TimeZone to CET to prevent issues when working with the new API later. We should note that the Date itself doesn’t have any time zone, but its toString() uses the current default time zone.
我们将默认的TimeZone设置为CET,以防止以后使用新API时出现问题。我们应该注意,Date本身没有任何时区,但是它的toString()使用了当前的默认时区。
We’ll be using this Date instance in all of our examples below.
我们将在下面所有的例子中使用这个Date实例。
2.2. Using the SimpleDateFormat Class
2.2.使用SimpleDateFormat类
We’ll make use of the format() method of the SimpleDateFormat class in this example. Let’s create an instance of it by using our date format:
在这个例子中,我们将使用format()类的SimpleDateFormat方法。让我们通过使用我们的日期格式来创建它的一个实例。
DateFormat formatter = new SimpleDateFormat(DATE_FORMAT);
After this, we can format our date and compare it with the expected output:
在这之后,我们可以格式化我们的日期,并将其与预期的输出进行比较。
String formattedDate = formatter.format(date);
assertEquals(EXPECTED_STRING_DATE, formattedDate);
2.3. Using the Abstract DateFormat Class
2.3.使用抽象的DateFormat类
As we could’ve seen, SimpleDateFormat is a subclass of the abstract DateFormat class. This class provides various methods for date and time formatting.
正如我们所看到的,SimpleDateFormat是抽象的DateFormat类的一个子类。这个类提供了各种日期和时间格式化的方法。
We’ll use it to achieve the same output as above:
我们将用它来实现与上面一样的输出。
String formattedDate = DateFormat
.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT)
.format(date);
With this approach, we are passing style patterns — MEDIUM for the date and SHORT for the time in our case.
通过这种方法,我们正在传递样式模式–在我们的例子中,MEDIUM表示日期,SHORT表示时间。
3. Using the Formatter Class
3.使用Formatter类
Another simple way of getting the same String as in earlier examples is to use the Formatter class.
获得与前面例子中相同的String的另一个简单方法是使用Formatter类。
While this may not be the most readable solution, it is a thread-safe one-liner that could be useful, especially in a multi-threaded environment (we should keep in mind that SimpleDateFormat is not thread-safe):
虽然这可能不是最易读的解决方案,它是一个线程安全的单线程,可能很有用,特别是在多线程环境中(我们应该记住,SimpleDateFormat不是线程安全的)。
String formattedDate = String.format("%1$tb %1$te, %1$tY %1$tI:%1$tM %1$Tp", date);
We used 1$ to indicate that we’ll be passing only one argument to be used with every flag. A detailed explanation of the flags could be found on Date/Time Conversions part of the Formatter class.
我们用1$来表示我们将只传递一个参数,与每个标志一起使用。关于标志的详细解释可以在Formatter类的日期/时间转换部分找到。
4. Converting Using Java 8 Date/Time API
4.使用Java 8 Date/Time API进行转换
The Date/Time API from Java 8 is far more powerful than the java.util.Date and java.util.Calendar classes, and we should use it whenever possible. Let’s see how we can put it to use to convert our existing Date object to String.
来自 Java 8 的 Date/Time API 远比 java.util.Date 和 java.util.Calendar 类强大,我们应该尽可能地使用它。让我们看看如何利用它来将我们现有的Date对象转换为String。
This time, we’ll use the DateTimeFormatter class and its format() method, as well as the same date pattern, declared in Section 2.1:
这一次,我们将使用DateTimeFormatter类及其format()方法,以及第2.1节中声明的相同的日期模式。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(DATE_FORMAT);
To use the new API, we need to convert our Date object to an Instant object:
为了使用新的API,我们需要将我们的Date对象转换为Instant对象:。
Instant instant = date.toInstant();
Since our expected String has both date and time parts, we also need to convert the Instant object to LocalDateTime:
由于我们预期的String有日期和时间两部分,我们还需要将Instant对象转换成LocalDateTime:。
LocalDateTime ldt = instant
.atZone(ZoneId.of("CET"))
.toLocalDateTime();
And finally, we can easily get our formatted String:
最后,我们可以轻松地得到我们的格式化String。
String formattedDate = ldt.format(formatter);
5. Conclusion
5.总结
In this article, we illustrated several ways of converting java.util.Date objects to String. We first showed how to do that using the older java.util.Date and java.util.Calendar classes and corresponding date formatting classes.
在这篇文章中,我们说明了将java.util.Date对象转换为String的几种方法。我们首先展示了如何使用较早的java.util.Date和java.util.Calendar类以及相应的日期格式化类来实现这一目的。
Then we used the Formatter class and, finally, the Java 8 Date/Time API.
然后我们使用了Formatter类,最后是Java 8 Date/Time API。
As always, complete source code can be found over on GitHub.
一如既往,完整的源代码可以在GitHub上找到over。