Java 字符串到日期的转换
将“2010 年 1 月 2 日”格式的 String
转换为 Java 中的 Date
的最佳方法是什么?
最终,我想将月、日和年分解为整数,以便我可以
Date date = new Date();
date.setMonth()..
date.setYear()..
date.setDay()..
date.setlong currentTime = date.getTime();
将日期转换为时间。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(17)
这是一个艰难的方法,并且自 Java 1.1 (1997) 以来,那些
java.util.Date
setter 方法已被弃用。此外,自从 Java 8 (2014) 中引入java.time
API 以来,整个 java.util.Date 类实际上已被弃用(不推荐)。只需使用
DateTimeFormatter
具有与输入字符串匹配的模式 (教程可在此处获取)。在“January 2, 2010”作为输入字符串的特定情况下:
MMMM
模式,d
模式。注意:如果您的格式模式恰好也包含时间部分,则使用
LocalDateTime#parse(text, formatter)
而不是LocalDate#parse(text, formatter)
。而且,如果您的格式模式恰好也包含时区,请使用ZonedDateTime#parse(text, formatter)
代替。以下是 javadoc,列出所有可用的格式模式:
G
y
D
M
/L
d
Q
/q
Y
w
W
E
e
/c
F
a
h
K
k
H
m
s
S
n
N
V
z
O
X
x
Z
请注意,它有几个 针对更流行的模式的预定义格式化程序。因此,您可以使用
DateTimeFormatter.RFC_1123_DATE_TIME
,而不是DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
。这是可能的,因为与SimpleDateFormat
相反,它们是线程安全的。因此,如果有必要,您也可以定义自己的。对于特定的输入字符串格式,您不需要使用显式的
DateTimeFormatter
:标准的 ISO 8601 日期,如 2016-09-26T17:44:57Z,可以直接使用LocalDateTime#parse(text)
因为它已经使用ISO_LOCAL_DATE_TIME
格式化程序。同样,LocalDate#parse(text)
解析不带时间部分的 ISO 日期(请参阅ISO_LOCAL_DATE
) 和ZonedDateTime#parse(text)
解析添加了偏移量和时区的 ISO 日期(请参阅ISO_ZONED_DATE_TIME
)。Java 8 之前的版本
如果您尚未使用 Java 8,或者被迫使用
java.util.Date
,请使用SimpleDateFormat
使用格式模式匹配输入字符串。请注意显式
Locale
参数的重要性。如果省略它,它将使用 默认区域设置 不一定是输入字符串的月份名称中使用的英语。如果区域设置与输入字符串不匹配,那么即使格式模式看起来有效,您也会混淆地得到 java.text.ParseException 。以下是 javadoc,列出所有可用的格式模式:
G
y
Y
M
/L
w
W
D
d
F
E
u
a
H
k
K
h
m
s
S
z
Z
X
请注意,模式区分大小写,并且基于文本的四个字符或更多字符的模式代表完整形式;否则,如果有的话,将使用简短或缩写的形式。因此,例如
MMMMM
或更多内容是不必要的。以下是解析迄今为止给定字符串的有效
SimpleDateFormat
模式的一些示例:yyyy.MM.dd G 'at' HH :mm:ss z
EEE, MMM d, ''yy
h:mm a
hh 'o''clock' a, zzzz
K:mm a, z
yyyyy.MMMM.dd GGG hh:mm aaa
EEE, d MMM yyyy HH:mm:ss Z
yyyy-MM-dd'T'HH:mm:ss.SSSXXX
YYYY-'W'ww-u
重要说明是
SimpleDateFormat
是不是线程安全的。换句话说,您永远不应该将其声明并分配为静态变量或实例变量,然后从不同的方法/线程中重用它。您应该始终在方法本地范围内创建全新的它。That's the hard way, and those
java.util.Date
setter methods have been deprecated since Java 1.1 (1997). Moreover, the wholejava.util.Date
class was de-facto deprecated (discommended) since introduction ofjava.time
API in Java 8 (2014).Simply format the date using
DateTimeFormatter
with a pattern matching the input string (the tutorial is available here).In your specific case of "January 2, 2010" as the input string:
MMMM
pattern for itd
pattern for it.yyyy
pattern for it.Note: if your format pattern happens to contain the time part as well, then use
LocalDateTime#parse(text, formatter)
instead ofLocalDate#parse(text, formatter)
. And, if your format pattern happens to contain the time zone as well, then useZonedDateTime#parse(text, formatter)
instead.Here's an extract of relevance from the javadoc, listing all available format patterns:
G
u
y
D
M
/L
d
Q
/q
Y
w
W
E
e
/c
F
a
h
K
k
H
m
s
S
A
n
N
V
z
O
X
x
Z
Do note that it has several predefined formatters for the more popular patterns. So instead of e.g.
DateTimeFormatter.ofPattern("EEE, d MMM yyyy HH:mm:ss Z", Locale.ENGLISH);
, you could useDateTimeFormatter.RFC_1123_DATE_TIME
. This is possible because they are, on the contrary toSimpleDateFormat
, thread safe. You could thus also define your own, if necessary.For a particular input string format, you don't need to use an explicit
DateTimeFormatter
: a standard ISO 8601 date, like 2016-09-26T17:44:57Z, can be parsed directly withLocalDateTime#parse(text)
as it already uses theISO_LOCAL_DATE_TIME
formatter. Similarly,LocalDate#parse(text)
parses an ISO date without the time component (seeISO_LOCAL_DATE
), andZonedDateTime#parse(text)
parses an ISO date with an offset and time zone added (seeISO_ZONED_DATE_TIME
).Pre-Java 8
In case you're not on Java 8 yet, or are forced to use
java.util.Date
, then format the date usingSimpleDateFormat
using a format pattern matching the input string.Note the importance of the explicit
Locale
argument. If you omit it, then it will use the default locale which is not necessarily English as used in the month name of the input string. If the locale doesn't match with the input string, then you would confusingly get ajava.text.ParseException
even though when the format pattern seems valid.Here's an extract of relevance from the javadoc, listing all available format patterns:
G
y
Y
M
/L
w
W
D
d
F
E
u
a
H
k
K
h
m
s
S
z
Z
X
Note that the patterns are case sensitive and that text based patterns of four characters or more represent the full form; otherwise a short or abbreviated form is used if available. So e.g.
MMMMM
or more is unnecessary.Here are some examples of valid
SimpleDateFormat
patterns to parse a given string to date:yyyy.MM.dd G 'at' HH:mm:ss z
EEE, MMM d, ''yy
h:mm a
hh 'o''clock' a, zzzz
K:mm a, z
yyyyy.MMMM.dd GGG hh:mm aaa
EEE, d MMM yyyy HH:mm:ss Z
yyMMddHHmmssZ
yyyy-MM-dd'T'HH:mm:ss.SSSZ
yyyy-MM-dd'T'HH:mm:ss.SSSXXX
YYYY-'W'ww-u
An important note is that
SimpleDateFormat
is not thread safe. In other words, you should never declare and assign it as a static or instance variable and then reuse it from different methods/threads. You should always create it brand new within the method local scope.啊,是的,再次讨论 Java Date。为了处理日期操作,我们使用 Date, 日历, GregorianCalendar 和 SimpleDateFormat。例如,使用您的一月日期作为输入:
然后您可以使用以下内容进行操作:
Ah yes the Java Date discussion, again. To deal with date manipulation we use Date, Calendar, GregorianCalendar, and SimpleDateFormat. For example using your January date as input:
Then you can manipulate that with something like:
在 Java 8 中,我们获得了新的日期/时间 API (JSR 310)。
在 Java 8 中可以使用以下方式解析日期,而不依赖 Joda-Time:
LocalDate 是用于表示的标准 Java 8 类一个日期(没有时间)。如果要解析包含日期和时间信息的值,应使用 本地日期时间。对于带有时区的值,请使用 ZonedDateTime。两者都提供类似于
LocalDate
的parse()
方法:来自 DateTimeFormatter Javadoc:
With Java 8 we get a new Date / Time API (JSR 310).
The following way can be used to parse the date in Java 8 without relying on Joda-Time:
LocalDate is the standard Java 8 class for representing a date (without time). If you want to parse values that contain date and time information you should use LocalDateTime. For values with timezones use ZonedDateTime. Both provide a
parse()
method similar toLocalDate
:The list formatting characters from DateTimeFormatter Javadoc:
虽然有些答案在技术上是正确的,但并不可取。
这个流行的开放-源免费库可以在多个 Java 版本中使用。 StackOverflow 上可以找到许多其用法示例。阅读其中一些内容将有助于您快速上手。
这组新的类受到 Joda-Time 的启发并由 JSR 310 定义。这些类内置于 Java 8 中。一个项目正在进行中,旨在将这些类向后移植到 Java 7,但该向后移植不受 Oracle 支持。
日期同时包含日期部分和时间部分)
一天的开始取决于时区。如果未能指定时区,则应用 JVM 的默认时区。这意味着在其他计算机上运行或修改时区设置时,代码的行为可能会发生变化。可能不是你想要的。
区域设置的语言指定如何解释解析过程中遇到的单词(月份和日期的名称)。 (BalusC 的回答正确处理了这个问题。)此外,在生成字符串表示形式时,区域设置会影响某些格式化程序的输出您的日期时间。
Joda-Time
下面是有关 Joda-Time 的一些注释。
时区
在 Joda-Time 中,DateTime 对象确实知道自己指定的时区。这与 java.util.Date 类形成鲜明对比,后者似乎有时区,但实际上没有。
请注意下面的示例代码中我们如何将时区对象传递给解析字符串的格式化程序。该时区用于将该日期时间解释为发生在该时区。因此,您需要考虑并确定该字符串输入表示的时区。
由于输入字符串中没有时间部分,Joda-Time 会将指定时区的第一时刻指定为当天的时间。通常这意味着
00:00:00
但并非总是如此,因为夏令时 ( DST) 或其他异常情况。顺便说一句,您可以通过调用withTimeAtStartOfDay
对任何 DateTime 实例执行相同的操作。格式化程序模式
格式化程序模式中使用的字符在 Joda-Time 中与 java.util.Date/Calendar 中的字符相似,但并不完全相同。仔细阅读文档。
不变性
我们通常在 Joda-Time 中使用不可变类。我们不是修改现有的日期时间对象,而是调用基于另一个对象创建新实例的方法,并复制大多数方面(除了需要更改的地方)。一个示例是下面最后一行中对
withZone
的调用。 不变性有助于让Joda-Time非常线程安全,也可以让一些工作更加清晰。转换
您将需要 java.util.Date 对象来与不了解 Joda-Time 对象的其他类/框架一起使用。幸运的是,来回移动非常容易。
从 java.util.Date 对象(此处名为
date
)到 Joda-Time DateTime...从 Joda-Time 到 java.util.Date 对象的另一个方向...
示例代码
运行时...
While some of the answers are technically correct, they are not advisable.
This popular open-source free-of-cost library can be used across several versions of Java. Many examples of its usage may be found on StackOverflow. Reading some of these will help get you up to speed quickly.
This new set of classes are inspired by Joda-Time and defined by JSR 310. These classes are built into Java 8. A project is underway to backport these classes to Java 7, but that backporting is not backed by Oracle.
Date has both a date portion and a time-of-day portion)
The beginning of a day depends on the time zone. If you fail to specify a time zone, the JVM's default time zone is applied. That means the behavior of your code may change when run on other computers or with a modified time zone setting. Probably not what you want.
The Locale's language specifies how to interpret the words (name of month and of day) encountered during parsing. (The answer by BalusC handles this properly.) Also, the Locale affects the output of some formatters when generating a string representation of your date-time.
Joda-Time
A few notes about Joda-Time follow.
Time Zone
In Joda-Time, a DateTime object truly knows its own assigned time zone. This contrasts the java.util.Date class which seems to have a time zone but does not.
Note in the example code below how we pass a time zone object to the formatter which parses the string. That time zone is used to interpret that date-time as having occurred in that time zone. So you need to think about and determine the time zone represented by that string input.
Since you have no time portion in your input string, Joda-Time assigns the first moment of the day of the specified time zone as the time-of-day. Usually this means
00:00:00
but not always, because of Daylight Saving Time (DST) or other anomalies. By the way, you can do the same to any DateTime instance by callingwithTimeAtStartOfDay
.Formatter Pattern
The characters used in a formatter's pattern are similar in Joda-Time to those in java.util.Date/Calendar but not exactly the same. Carefully read the doc.
Immutability
We usually use the immutable classes in Joda-Time. Rather than modify an existing Date-Time object, we call methods that create a new fresh instance based on the other object with most aspects copied except where alterations were desired. An example is the call to
withZone
in last line below. Immutability helps to make Joda-Time very thread-safe, and can also make some work more clear.Conversion
You will need java.util.Date objects for use with other classes/framework that do not know about Joda-Time objects. Fortunately, it is very easy to move back and forth.
Going from a java.util.Date object (here named
date
) to Joda-Time DateTime…Going the other direction from Joda-Time to a java.util.Date object…
Sample Code
When run…
它对我来说效果很好。
It works fine for me.
在处理 SimpleDateFormat 类时,请务必记住 Date 不是线程安全的,并且您不能与多个线程共享单个 Date 对象。
“m”和“M”之间也有很大的区别,小写表示分钟,大写表示月份。与“d”和“D”相同。这可能会导致经常被忽视的细微错误。请参阅 Javadoc 或 Java 中字符串转换为日期的指南 了解更多详细信息。
While on dealing with the SimpleDateFormat class, it's important to remember that Date is not thread-safe and you can not share a single Date object with multiple threads.
Also there is big difference between "m" and "M" where small case is used for minutes and capital case is used for month. The same with "d" and "D". This can cause subtle bugs which often get overlooked. See Javadoc or Guide to Convert String to Date in Java for more details.
您可以使用 SimpleDateformat 将字符串更改为日期
You can use SimpleDateformat for change string to date
我们使用了两个简单的格式化程序:
我们解析完整的日期到时间格式:
Simple two formatters we have used:
We parse the full date to time format:
此外,SimpleDateFormat 不适用于某些客户端技术,例如 GWT。
使用 Calendar.getInstance() 是个好主意,您的要求是比较两个日期;去长期约会。
Also, SimpleDateFormat is not available with some of the client-side technologies, like GWT.
It's a good idea to go for Calendar.getInstance(), and your requirement is to compare two dates; go for long date.
我简陋的测试程序。我用它来使用格式化程序并查找我在日志文件中找到的长日期(但谁把它们放在那里......)。
我的测试程序:
测试结果:
My humble test program. I use it to play around with the formatter and look-up long dates that I find in log-files (but who has put them there...).
My test program:
Test results:
来源链接
对于 Android
Calendar.getInstance().getTime() 给出
使用
Source Link
For Android
Calendar.getInstance().getTime() gives
Use
我致力于将 String 解析为 LocalDateTime。我把它留在这里作为例子
我得到了
I worked on parsing String to LocalDateTime. I leave it here as example
And I got
From Date to String
From String to Date
From date String to different format
来源链接。
From Date to String
From String to Date
From date String to different format
Source link.
字符串到日期的转换:
String to Date conversion:
试试这个
Try this