在Java字符串中更改日期格式

514

我有一个表示日期的 String

String date_s = "2011-01-18 00:00:00.0";

我想把它转换成 Date,并以YYYY-MM-DD格式输出。

2011-01-18

我该怎么做?


好的,根据下面的答案,这是我尝试过的:

String date_s = " 2011-01-18 00:00:00.0"; 
SimpleDateFormat dt = new SimpleDateFormat("yyyyy-mm-dd hh:mm:ss"); 
Date date = dt.parse(date_s); 
SimpleDateFormat dt1 = new SimpleDateFormat("yyyyy-mm-dd");
System.out.println(dt1.format(date));

但它输出的是 02011-00-1,而不是期望的 2011-01-18。我做错了什么?


182
"yyyyy不同于yyyy。:)" - Hovercraft Full Of Eels
2
一个回旋镖式的问题。你的使用场景是什么?因为有可能你应该使用内置模式(DateFormat.getDateTimeInstance())。 - Paweł Dyda
13
格式字符串中表示月份的是MM,而不是像上面的例子中所示的mm,mm代表分钟。 - Mike
3
我将yyyy-mm-dd更改为yyyy-MM-dd,因为初始版本无法运行。 - Pavlo Zvarych
2
"mm"是分钟数 :) - Fuad Efendi
"yyyyy-MM-dd hh:mm:ss": - Guilherme
23个回答

546
使用 LocalDateTime#parse() 方法(如果字符串中包含时区部分,则使用ZonedDateTime#parse())来将符合特定格式的 String 解析为 LocalDateTime
String oldstring = "2011-01-18 00:00:00.0";
LocalDateTime datetime = LocalDateTime.parse(oldstring, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.S"));

接着使用 LocalDateTime#format()(或ZonedDateTime#format())方法,将一个LocalDateTime对象按照指定的格式转换成String类型。

String newstring = datetime.format(DateTimeFormatter.ofPattern("yyyy-MM-dd"));
System.out.println(newstring); // 2011-01-18

或者,如果您还没有使用Java 8,则可以使用SimpleDateFormat#parse()将特定格式的String解析为Date

String oldstring = "2011-01-18 00:00:00.0";
Date date = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S").parse(oldstring);
然后使用 SimpleDateFormat#format() 方法,将一个 Date 对象按照指定的格式转换成 String 类型。
String newstring = new SimpleDateFormat("yyyy-MM-dd").format(date);
System.out.println(newstring); // 2011-01-18

参见:


更新:根据您在此答案发布后添加到问题中的错误尝试; 这些模式区分大小写。仔细阅读java.text.SimpleDateFormat javadoc,了解各个部分的含义。例如,M表示月份,m表示分钟。此外,年份由四个数字组成yyyy,而不是五个yyyyy。请更仔细地查看我在此处发布的代码片段。


如果您想让日期看起来像“2012年9月1日星期一”,该怎么办? - crmepham
11
请点击javadoc链接,找到必要的模式字符并相应地修改该模式。 - BalusC
如果你还没有使用Java 8,考虑使用ThreeTen Backport,然后参考答案中的第一个示例。或者对于Android API级别低于26的设备,可以使用ThreeTenABP - Ole V.V.

178

格式化对大小写敏感,因此使用 MM 表示月份而不是 mm(后者表示分钟),以及 yyyy 表示年份。您可以使用以下Cheat sheet参考文档

G   Era designator  Text    AD
y   Year    Year    1996; 96
Y   Week year   Year    2009; 09
M   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 name in week    Text    Tuesday; Tue
u   Day number of week (1 = Monday, ..., 7 = Sunday)    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

示例:

"yyyy.MM.dd G 'at' HH:mm:ss z"  2001.07.04 AD at 12:08:56 PDT
"EEE, MMM d, ''yy"  Wed, Jul 4, '01
"h:mm a"    12:08 PM
"hh 'o''clock' a, zzzz" 12 o'clock PM, Pacific Daylight Time
"K:mm a, z" 0:08 PM, PDT
"yyyyy.MMMMM.dd GGG hh:mm aaa"  02001.July.04 AD 12:08 PM
"EEE, d MMM yyyy HH:mm:ss Z"    Wed, 4 Jul 2001 12:08:56 -0700
"yyMMddHHmmssZ" 010704120856-0700
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"   2001-07-04T12:08:56.235-0700
"yyyy-MM-dd'T'HH:mm:ss.SSSXXX"   2001-07-04T12:08:56.235-07:00
"YYYY-'W'ww-u"  2001-W27-3

2
"yyyy-MM-dd'T'HH:mm:ss.SSSZ" 应该改为 "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"。 - a fair player
2
如果在单引号中放置“Z”,它将输出“Z”,但不加引号时将输出时区。例如:2014-08-14T01:24:57.236Z 和不加引号的格式2014-08-14T01:24:57.236-0530 --> 我在jdk1.7上尝试过。 - Dev
1
02001年7月04日 公元下午12:08 - Stefano Mtangoo
这是我在使用Java日期格式化程序方面找到的最令人满意的答案。非常感谢。 - viper
谢谢,非常好!我需要使用 yyyy-MM-dd'T'HH:mm:ssXXX - Alberto Cerqueira
显示剩余4条评论

117

答案当然是创建一个SimpleDateFormat对象,使用它来解析字符串为日期并将日期格式化为字符串。如果您已经尝试过SimpleDateFormat但不起作用,请展示您的代码和所有可能收到的错误。

附加说明:“mm”在格式字符串中与“MM”不同。用MM表示月份,用mm表示分钟。此外,“yyyyy”也不同于“yyyy”。例如:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class FormateDate {

    public static void main(String[] args) throws ParseException {
        String date_s = "2011-01-18 00:00:00.0";

        // *** note that it's "yyyy-MM-dd hh:mm:ss" not "yyyy-mm-dd hh:mm:ss"  
        SimpleDateFormat dt = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        Date date = dt.parse(date_s);

        // *** same for the format String below
        SimpleDateFormat dt1 = new SimpleDateFormat("yyyy-MM-dd");
        System.out.println(dt1.format(date));
    }

}

导入java.text.ParseException; 导入java.text.SimpleDateFormat; 导入java.util.Date;public class formateDate { /**
  • @param args
  • @throws ParseException */ public static void main(String[] args) throws ParseException { // TODO Auto-generated method stub
String date_s=" 2011-01-18 00:00:00.0"; SimpleDateFormat dt= new SimpleDateFormat("yyyyy-mm-dd hh:mm:ss"); Date date=dt.parse(date_s); SimpleDateFormat dt1= new SimpleDateFormat("yyyyy-mm-dd"); System.out.println( dt1.format(date)); }} 我想输出应该是“2011-01-18”,但输出是02011-00-1
- amit4444
请在原问题下方添加您的任何代码(缩进四个空格)。这样它将保留其格式,我们就可以阅读它。 - Hovercraft Full Of Eels
1
请查看我上面的回答。您在格式字符串中使用了“mm”,而应该使用“MM”。 - Hovercraft Full Of Eels
hh将给出范围在1-12之间的小时数,您需要使用a来打印/解析AMPM。要打印/解析范围在0-23之间的小时数,请使用HH - Andre Holzner

32

为什么不直接使用这个?

Date convertToDate(String receivedDate) throws ParseException{
        SimpleDateFormat formatter = new SimpleDateFormat("dd-MM-yyyy");
        Date date = formatter.parse(receivedDate);
        return date;
    }

此外,还有另一种方式:

DateFormat df = new SimpleDateFormat("dd/MM/yyyy");
String requiredDate = df.format(new Date()).toString();
或者
Date requiredDate = df.format(new Date());

3
为什么不使用这个呢?因为 (a) 它忽略了时区的问题。确定日期取决于时区,而该代码依赖于 JVM 的默认时区,结果可能会无意中有所不同。另外 (b) 因为 java.util.Date 和 SimpleDateFormat 类非常麻烦,应该避免使用它们。 - Basil Bourque
2
始终返回字符串,需要日期的日期 = df.format(new Date()); - user3402040

16

在Java 8及更高版本中使用java.time包:

String date = "2011-01-18 00:00:00.0";
TemporalAccessor temporal = DateTimeFormatter
    .ofPattern("yyyy-MM-dd HH:mm:ss.S")
    .parse(date); // use parse(date, LocalDateTime::from) to get LocalDateTime
String output = DateTimeFormatter.ofPattern("yyyy-MM-dd").format(temporal);

13

[根据BalusC的更正进行了编辑] SimpleDateFormat类应该可以解决问题:

String pattern = "yyyy-MM-dd HH:mm:ss.S";
SimpleDateFormat format = new SimpleDateFormat(pattern);
try {
  Date date = format.parse("2011-01-18 00:00:00.0");
  System.out.println(date);
} catch (ParseException e) {
  e.printStackTrace();
}

DD代表“年中的日”,而不是“月中的日”。hh代表“上午/下午小时(1-12)”,而不是“一天中的小时(0-23)”。 - BalusC

11
请参考此处的“日期和时间模式”。http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.ParseException;

public class DateConversionExample{

  public static void main(String arg[]){

    try{

    SimpleDateFormat sourceDateFormat = new SimpleDateFormat("yyyy-MM-DD HH:mm:ss");

    Date date = sourceDateFormat.parse("2011-01-18 00:00:00.0");


    SimpleDateFormat targetDateFormat = new SimpleDateFormat("yyyy-MM-dd");
    System.out.println(targetDateFormat.format(date));

    }catch(ParseException e){
        e.printStackTrace();
    }
  } 

}

9

其他答案都是正确的,基本上您的匹配模式中"y"字符的数量有误。

时区

但是还有一个问题...您没有涉及到时区。如果您想使用UTC,那么您应该明确说明。如果不是,答案就不完整。如果您只需要日期而不需要时间,则没有问题。但是如果您要进行涉及时间的进一步操作,则应指定时区。

Joda-Time

以下是相同类型的代码,但使用了第三方开源的Joda-Time 2.3库。

// © 2013 Basil Bourque. This source code may be used freely forever by anyone taking full responsibility for doing so.

String date_s = "2011-01-18 00:00:00.0";

org.joda.time.format.DateTimeFormatter formatter = org.joda.time.format.DateTimeFormat.forPattern( "yyyy-MM-dd' 'HH:mm:ss.SSS" );
// By the way, if your date-time string conformed strictly to ISO 8601 including a 'T' rather than a SPACE ' ', you could
// use a formatter built into Joda-Time rather than specify your own: ISODateTimeFormat.dateHourMinuteSecondFraction().
// Like this:
//org.joda.time.DateTime dateTimeInUTC = org.joda.time.format.ISODateTimeFormat.dateHourMinuteSecondFraction().withZoneUTC().parseDateTime( date_s );

// Assuming the date-time string was meant to be in UTC (no time zone offset).
org.joda.time.DateTime dateTimeInUTC = formatter.withZoneUTC().parseDateTime( date_s );
System.out.println( "dateTimeInUTC: " + dateTimeInUTC );
System.out.println( "dateTimeInUTC (date only): " + org.joda.time.format.ISODateTimeFormat.date().print( dateTimeInUTC ) );
System.out.println( "" ); // blank line.

// Assuming the date-time string was meant to be in Kolkata time zone (formerly known as Calcutta). Offset is +5:30 from UTC (note the half-hour).
org.joda.time.DateTimeZone kolkataTimeZone = org.joda.time.DateTimeZone.forID( "Asia/Kolkata" );
org.joda.time.DateTime dateTimeInKolkata = formatter.withZone( kolkataTimeZone ).parseDateTime( date_s );
System.out.println( "dateTimeInKolkata: " + dateTimeInKolkata );
System.out.println( "dateTimeInKolkata (date only): " + org.joda.time.format.ISODateTimeFormat.date().print( dateTimeInKolkata ) );
// This date-time in Kolkata is a different point in the time line of the Universe than the dateTimeInUTC instance created above. The date is even different.
System.out.println( "dateTimeInKolkata adjusted to UTC: " + dateTimeInKolkata.toDateTime( org.joda.time.DateTimeZone.UTC ) );

When run…

dateTimeInUTC: 2011-01-18T00:00:00.000Z
dateTimeInUTC (date only): 2011-01-18

dateTimeInKolkata: 2011-01-18T00:00:00.000+05:30
dateTimeInKolkata (date only): 2011-01-18
dateTimeInKolkata adjusted to UTC: 2011-01-17T18:30:00.000Z

8
您可以直接使用以下代码:
Date yourDate = new Date();

SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd");
String date = DATE_FORMAT.format(yourDate);

它完美地工作了!


这段代码返回错误 "Uncaught SyntaxError: Unexpected identifier"。 - Ivan Frolov
@IvanFrolov 也许你少了一个引用,你在哪一行出现了错误? - cнŝdk
1
哦,抱歉 - 没有注意到这是Java的解决方案,我正在寻找JavaScript的解决方案))) (顺便说一句 - 已经找到了)。谢谢! - Ivan Frolov
1
啊,好的,现在很明显了。 - cнŝdk

8
try
 {
    String date_s = "2011-01-18 00:00:00.0";
    SimpleDateFormat simpledateformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.S");
    Date tempDate=simpledateformat.parse(date_s);
    SimpleDateFormat outputDateFormat = new SimpleDateFormat("yyyy-MM-dd");           
    System.out.println("Output date is = "+outputDateFormat.format(tempDate));
  } catch (ParseException ex) 
  {
        System.out.println("Parse Exception");
  }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接