什么是最好的方法转换格式的字符串' 1月2日,2010年'到一个日期在Java?
最后,我希望将月、日和年分解为整数,以便我可以使用
Date date = new Date();
date.setMonth()..
date.setYear()..
date.setDay()..
date.setlong currentTime = date.getTime();
将日期转换为时间。
什么是最好的方法转换格式的字符串' 1月2日,2010年'到一个日期在Java?
最后,我希望将月、日和年分解为整数,以便我可以使用
Date date = new Date();
date.setMonth()..
date.setYear()..
date.setDay()..
date.setlong currentTime = date.getTime();
将日期转换为时间。
当前回答
SimpleDateFormat sdf = new SimpleDateFormat("dd-MM-yyyy");
return sdf.format(date);
From String to Date
SimpleDateFormat sdf = new SimpleDateFormat(datePattern);
return sdf.parse(dateStr);
From date String to different format
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
SimpleDateFormat newSdf = new SimpleDateFormat("dd-MM-yyyy");
Date temp = sdf.parse(dateStr);
return newSdf.format(temp);
源链接。
其他回答
此外,SimpleDateFormat对于某些客户端技术(如GWT)是不可用的。
使用Calendar.getInstance()是个好主意,您的要求是比较两个日期;长时间约会。
我简陋的测试程序。我用它来摆弄格式化程序,查找我在日志文件中找到的长日期(但是谁把它们放在那里了……)
我的测试程序:
package be.test.package.time;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.TimeZone;
public class TimeWork {
public static void main(String[] args) {
TimeZone timezone = TimeZone.getTimeZone("UTC");
List<Long> longs = new ArrayList<>();
List<String> strings = new ArrayList<>();
//Formatting a date needs a timezone - otherwise the date get formatted to your system time zone.
//Use 24h format HH. In 12h format hh can be in range 0-11, which makes 12 overflow to 0.
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss.SSS");
formatter.setTimeZone(timezone);
Date now = new Date();
//Test dates
strings.add(formatter.format(now));
strings.add("01-01-1970 00:00:00.000");
strings.add("01-01-1970 00:00:01.000");
strings.add("01-01-1970 00:01:00.000");
strings.add("01-01-1970 01:00:00.000");
strings.add("01-01-1970 10:00:00.000");
strings.add("01-01-1970 12:00:00.000");
strings.add("01-01-1970 24:00:00.000");
strings.add("02-01-1970 00:00:00.000");
strings.add("01-01-1971 00:00:00.000");
strings.add("01-01-2014 00:00:00.000");
strings.add("31-12-1969 23:59:59.000");
strings.add("31-12-1969 23:59:00.000");
strings.add("31-12-1969 23:00:00.000");
//Test data
longs.add(now.getTime());
longs.add(-1L);
longs.add(0L); //Long date presentation at - midnight 1/1/1970 UTC - The timezone is important!
longs.add(1L);
longs.add(1000L);
longs.add(60000L);
longs.add(3600000L);
longs.add(36000000L);
longs.add(43200000L);
longs.add(86400000L);
longs.add(31536000000L);
longs.add(1388534400000L);
longs.add(7260000L);
longs.add(1417706084037L);
longs.add(-7260000L);
System.out.println("===== String to long =====");
//Show the long value of the date
for (String string: strings) {
try {
Date date = formatter.parse(string);
System.out.println("Formated date : " + string + " = Long = " + date.getTime());
} catch (ParseException e) {
e.printStackTrace();
}
}
System.out.println("===== Long to String =====");
//Show the date behind the long
for (Long lo : longs) {
Date date = new Date(lo);
String string = formatter.format(date);
System.out.println("Formated date : " + string + " = Long = " + lo);
}
}
}
测试结果:
===== String to long =====
Formated date : 05-12-2014 10:17:34.873 = Long = 1417774654873
Formated date : 01-01-1970 00:00:00.000 = Long = 0
Formated date : 01-01-1970 00:00:01.000 = Long = 1000
Formated date : 01-01-1970 00:01:00.000 = Long = 60000
Formated date : 01-01-1970 01:00:00.000 = Long = 3600000
Formated date : 01-01-1970 10:00:00.000 = Long = 36000000
Formated date : 01-01-1970 12:00:00.000 = Long = 43200000
Formated date : 01-01-1970 24:00:00.000 = Long = 86400000
Formated date : 02-01-1970 00:00:00.000 = Long = 86400000
Formated date : 01-01-1971 00:00:00.000 = Long = 31536000000
Formated date : 01-01-2014 00:00:00.000 = Long = 1388534400000
Formated date : 31-12-1969 23:59:59.000 = Long = -1000
Formated date : 31-12-1969 23:59:00.000 = Long = -60000
Formated date : 31-12-1969 23:00:00.000 = Long = -3600000
===== Long to String =====
Formated date : 05-12-2014 10:17:34.873 = Long = 1417774654873
Formated date : 31-12-1969 23:59:59.999 = Long = -1
Formated date : 01-01-1970 00:00:00.000 = Long = 0
Formated date : 01-01-1970 00:00:00.001 = Long = 1
Formated date : 01-01-1970 00:00:01.000 = Long = 1000
Formated date : 01-01-1970 00:01:00.000 = Long = 60000
Formated date : 01-01-1970 01:00:00.000 = Long = 3600000
Formated date : 01-01-1970 10:00:00.000 = Long = 36000000
Formated date : 01-01-1970 12:00:00.000 = Long = 43200000
Formated date : 02-01-1970 00:00:00.000 = Long = 86400000
Formated date : 01-01-1971 00:00:00.000 = Long = 31536000000
Formated date : 01-01-2014 00:00:00.000 = Long = 1388534400000
Formated date : 01-01-1970 02:01:00.000 = Long = 7260000
Formated date : 04-12-2014 15:14:44.037 = Long = 1417706084037
Formated date : 31-12-1969 21:59:00.000 = Long = -7260000
这是一种困难的方法,而且这些Java .util. date setter方法自Java 1.1(1997)以来就已经弃用了。此外,自java引入以来,整个java.util. date类实际上已被弃用(不推荐)。Java 8(2014)中的时间API。
只需使用DateTimeFormatter与输入字符串匹配的模式格式化日期(本教程可在此处获得)。
在“January 2, 2010”作为输入字符串的特定情况下:
“January”是全文月份,因此使用MMMM模式 “2”是一个月中最短的一天,所以使用d模式。 “2010”是4位数字的年份,所以使用yyyy模式。
String string = "January 2, 2010";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MMMM d, yyyy", Locale.ENGLISH);
LocalDate date = LocalDate.parse(string, formatter);
System.out.println(date); // 2010-01-02
注意:如果你的格式模式碰巧也包含时间部分,那么使用localdatetime# parse(文本,格式化程序)而不是localdatetime# parse(文本,格式化程序)。并且,如果您的格式模式碰巧也包含时区,那么使用ZonedDateTime#parse(文本,格式化器)代替。
下面是javadoc的相关摘录,列出了所有可用的格式模式:
Symbol | Meaning | Presentation | Examples |
---|---|---|---|
G |
era | text | AD; Anno Domini; A |
u |
year | year | 2004; 04 |
y |
year-of-era | year | 2004; 04 |
D |
day-of-year | number | 189 |
M /L |
month-of-year | number/text | 7; 07; Jul; July; J |
d |
day-of-month | number | 10 |
Q /q |
quarter-of-year | number/text | 3; 03; Q3; 3rd quarter |
Y |
week-based-year | year | 1996; 96 |
w |
week-of-week-based-year | number | 27 |
W |
week-of-month | number | 4 |
E |
day-of-week | text | Tue; Tuesday; T |
e /c |
localized day-of-week | number/text | 2; 02; Tue; Tuesday; T |
F |
week-of-month | number | 3 |
a |
am-pm-of-day | text | PM |
h |
clock-hour-of-am-pm (1-12) | number | 12 |
K |
hour-of-am-pm (0-11) | number | 0 |
k |
clock-hour-of-am-pm (1-24) | number | 0 |
H |
hour-of-day (0-23) | number | 0 |
m |
minute-of-hour | number | 30 |
s |
second-of-minute | number | 55 |
S |
fraction-of-second | fraction | 978 |
A |
milli-of-day | number | 1234 |
n |
nano-of-second | number | 987654321 |
N |
nano-of-day | number | 1234000000 |
V |
time-zone ID | zone-id | America/Los_Angeles; Z; -08:30 |
z |
time-zone name | zone-name | Pacific Standard Time; PST |
O |
localized zone-offset | offset-O | GMT+8; GMT+08:00; UTC-08:00; |
X |
zone-offset 'Z' for zero | offset-X | Z; -08; -0830; -08:30; -083015; -08:30:15; |
x |
zone-offset | offset-x | +0000; -08; -0830; -08:30; -083015; -08:30:15; |
Z |
zone-offset | offset-Z | +0000; -0800; -08:00; |
请注意,它为更流行的模式提供了几个预定义的格式化程序。所以不用例如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),而zoneeddatetime #parse(text)解析一个添加了偏移量和时区的ISO日期(参见iso_zoneed_date_time)。
Pre-Java 8
如果你还没有使用Java 8,或者被迫使用Java .util。日期,然后使用与输入字符串匹配的格式模式SimpleDateFormat格式化日期。
String string = "January 2, 2010";
DateFormat format = new SimpleDateFormat("MMMM d, yyyy", Locale.ENGLISH);
Date date = format.parse(string);
System.out.println(date); // Sat Jan 02 00:00:00 GMT 2010
注意显式Locale参数的重要性。如果省略它,那么它将使用默认的语言环境,而不一定是输入字符串的月份名中使用的英语。如果区域设置与输入字符串不匹配,那么即使格式模式看起来有效,您也会混淆地得到java.text.ParseException。
下面是javadoc的相关摘录,列出了所有可用的格式模式:
Letter | Date or Time Component | Presentation | Examples |
---|---|---|---|
G |
Era designator | Text | AD |
y |
Year | Year | 1996; 96 |
Y |
Week year | Year | 2009; 09 |
M /L |
Month in year | Month | July; Jul; 07 |
w |
Week in year | Number | 27 |
W |
Week in month | Number | 2 |
D |
Day in year | Number | 189 |
d |
Day in month | Number | 10 |
F |
Day of week in month | Number | 2 |
E |
Day in week | Text | Tuesday; Tue |
u |
Day number of week | Number | 1 |
a |
Am/pm marker | Text | PM |
H |
Hour in day (0-23) | Number | 0 |
k |
Hour in day (1-24) | Number | 24 |
K |
Hour in am/pm (0-11) | Number | 0 |
h |
Hour in am/pm (1-12) | Number | 12 |
m |
Minute in hour | Number | 30 |
s |
Second in minute | Number | 55 |
S |
Millisecond | Number | 978 |
z |
Time zone | General time zone | Pacific Standard Time; PST; GMT-08:00 |
Z |
Time zone | RFC 822 time zone | -0800 |
X |
Time zone | ISO 8601 time zone | -08; -0800; -08:00 |
注意,这些模式是区分大小写的,基于文本的四个字符或更多的模式表示完整的形式;否则,如果可能,则使用简短或缩写形式。所以,MMMMM或更多是不必要的。
下面是一些有效的SimpleDateFormat模式的例子,用于解析给定字符串的日期:
Input string | Pattern |
---|---|
2001.07.04 AD at 12:08:56 PDT | yyyy.MM.dd G 'at' HH:mm:ss z |
Wed, Jul 4, '01 | EEE, MMM d, ''yy |
12:08 PM | h:mm a |
12 o'clock PM, Pacific Daylight Time | hh 'o''clock' a, zzzz |
0:08 PM, PDT | K:mm a, z |
02001.July.04 AD 12:08 PM | yyyyy.MMMM.dd GGG hh:mm aaa |
Wed, 4 Jul 2001 12:08:56 -0700 | EEE, d MMM yyyy HH:mm:ss Z |
010704120856-0700 | yyMMddHHmmssZ |
2001-07-04T12:08:56.235-0700 | yyyy-MM-dd'T'HH:mm:ss.SSSZ |
2001-07-04T12:08:56.235-07:00 | yyyy-MM-dd'T'HH:mm:ss.SSSXXX |
2001-W27-3 | YYYY-'W'ww-u |
重要的一点是,SimpleDateFormat不是线程安全的。换句话说,永远不要将它声明为静态变量或实例变量并将其赋值,然后从不同的方法/线程重用它。您应该始终在方法的局部范围内创建全新的方法。
虽然有些答案在技术上是正确的,但它们并不可取。
The java.util.Date & Calendar classes are notoriously troublesome. Because of flaws in design and implementation, avoid them. Fortunately we have our choice of two other excellent date-time libraries: Joda-TimeThis 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. java.time.* packageThis 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. As Kristopher Johnson correctly noted in his comment on the question, the other answers ignore vital issues of: Time of DayDate has both a date portion and a time-of-day portion) Time ZoneThe 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. LocaleThe 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的一些注意事项。
时区
在Joda-Time中,DateTime对象真正知道自己分配的时区。这与java.util.Date类形成对比,后者似乎有时区,但实际上没有。
请注意,在下面的示例代码中,我们如何将一个时区对象传递给解析字符串的格式化程序。该时区用于将日期-时间解释为发生在该时区。因此,您需要考虑并确定由字符串输入表示的时区。
由于您的输入字符串中没有时间部分,所以Joda-Time将指定时区的第一个时刻分配为一天的时间。通常这意味着00:00:00,但并不总是如此,因为日光节约时间(DST)或其他异常情况。顺便说一下,你可以通过调用withTimeAtStartOfDay对任何DateTime实例做同样的事情。
格式化程序模式
格式化程序模式中使用的字符在Joda-Time中类似于java.util中的字符。日期/日历,但不完全相同。仔细阅读诊断书。
不变性
我们通常在Joda-Time中使用不可变类。我们不会修改现有的Date-Time对象,而是调用基于其他对象创建新实例的方法,复制大多数方面(除非需要更改的地方除外)。下面最后一行中的withZone调用就是一个例子。不可变性有助于使Joda-Time非常线程安全,也可以使一些工作更加清晰。
转换
你将需要java.util.Date对象与其他不知道Joda-Time对象的类/框架一起使用。幸运的是,来回移动非常容易。
从java.util.Date对象(这里命名为date)到Joda-Time DateTime…
org.joda.time.DateTime dateTime = new DateTime( date, timeZone );
从Joda-Time到java.util.Date对象……
java.util.Date date = dateTime.toDate();
示例代码
String input = "January 2, 2010";
java.util.Locale locale = java.util.Locale.US;
DateTimeZone timeZone = DateTimeZone.forID( "Pacific/Honolulu" ); // Arbitrarily chosen for example.
DateTimeFormatter formatter = DateTimeFormat.forPattern( "MMMM d, yyyy" ).withZone( timeZone ).withLocale( locale );
DateTime dateTime = formatter.parseDateTime( input );
System.out.println( "dateTime: " + dateTime );
System.out.println( "dateTime in UTC/GMT: " + dateTime.withZone( DateTimeZone.UTC ) );
运行时……
dateTime: 2010-01-02T00:00:00.000-10:00
dateTime in UTC/GMT: 2010-01-02T10:00:00.000Z
DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
Date date;
try {
date = dateFormat.parse("2013-12-4");
System.out.println(date.toString()); // Wed Dec 04 00:00:00 CST 2013
String output = dateFormat.format(date);
System.out.println(output); // 2013-12-04
}
catch (ParseException e) {
e.printStackTrace();
}
这对我来说很有效。