将日期字符串从ISO 8601格式转换为另一种格式

时间:2014-04-09 18:32:44

标签: java simpledateformat

我有这段代码,我试图将日期字符串从一种格式转换为另一种格式,最后我再次想要日期对象。

            String dateString = "2014-10-04";
    SimpleDateFormat oldFormatter = new SimpleDateFormat("yyyy-MM-dd");
    Date parsedDate = oldFormatter.parse(dateString);
    SimpleDateFormat newFormatter = new SimpleDateFormat("dd-MMM-yyyy");
    String convertDateStr = newFormatter.format(parsedDate);
    Date convertedDate = newFormatter.parse(convertDateStr);

当我使用dateString值作为“2014-10-04”测试上面的代码时,上面的代码正确执行但convertDate格式改为“Sat Oct 04 00:00:00 IST 2014”而不是“dd-MMM” -yyyy“格式。

我的功能就像我有两个不同格式的日期,并且需要在比较时剩余的天数有所不同,所以我需要在获得天数差异之前将一种日期格式转换为其他日期。

编辑 - 有一个替代选项可以将日期字符串转换为指定的格式并获取具有转换格式的日期对象

5 个答案:

答案 0 :(得分:1)

Date对象没有内置格式,这就是SimpleDateFormat的作用。 将convertDateStr转换回Date对象后,您就失去了格式。

在您的代码块之后运行这些代码,您就会明白我的意思。

    System.out.println(convertedDate);
    System.out.println(newFormatter.format(convertedDate));

答案 1 :(得分:1)

TL;博士

LocalDate.parse(            // Represent a date-only value with a date-only class.
    "2014-10-04"            // Inputs in standard ISO 8601 format are parsed by default. No need to specify a formatting pattern.
)                           // Returns a `LocalDate` object. Do not conflate a date-time object with a String that represents its value. A `LocalDate` has no “format”.
.format(                    // Generate a String representing the `LocalDate` object’s value. 
    DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US )  // Define your custom formatting pattern. Specify `Locale` for human language and cultural norms used in localization.
)                           // Return a String.

java.time

现代方法使用 java.time 类来取代麻烦的旧遗留日期时间类,例如Date / Calendar / SimpleDateFormat

将仅限日期的类用于仅限日期的值,而不是日期+时间类。 LocalDate类表示没有时间且没有时区的仅限日期的值。

您的输入字符串符合标准ISO 8601格式。解析/生成字符串时, java.time 类在默认情况下使用ISO 8601格式。因此无需指定格式化模式。

String input  = "2014-10-04" ;
LocalDate ld = LocalDate.parse( input ) ;  // No need to specify a formatting pattern for ISO 8601 inputs.

要生成以特定格式表示LocalDate对象值的字符串,请定义格式设置模式。指定Locale对象以确定本地化中使用的人类语言和文化规范。

Locale locale = Locale.US ; 
DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , locale ) ;
String output = ld.format( f ) ;
  

04-OCT-2014

关于 java.time

java.time框架内置于Java 8及更高版本中。这些类取代了麻烦的旧legacy日期时间类,例如java.util.DateCalendar和& SimpleDateFormat

现在位于Joda-Timemaintenance mode项目建议迁移到java.time类。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。规范是JSR 310

您可以直接与数据库交换 java.time 对象。使用符合JDBC driver或更高版本的JDBC 4.2。不需要字符串,不需要java.sql.*类。

从哪里获取java.time类?

ThreeTen-Extra项目使用其他类扩展java.time。该项目是未来可能添加到java.time的试验场。您可以在此处找到一些有用的课程,例如IntervalYearWeekYearQuartermore

答案 2 :(得分:0)

Date对象不存储日期格式。您看到的输出只是其toString方法的结果。如果您想要特定格式的日期,则必须始终使用格式化程序以所需格式获取日期的字符串版本。

答案 3 :(得分:0)

约达时间

更新 Joda-Time项目现在位于maintenance mode,团队建议迁移到java.time课程。这个答案完整地保留了历史。

正如correct answer by forgivenson许多中所解释的那样,通过在StackOverflow中搜索" java日期格式"或" java日期解析"或者这样:

  • java.util.Date对象没有格式。 j.u.Date不是文本。 j.u.Date不包含String。 j.u.Date对象包含自Unix纪元以来的毫秒数(忽略闰秒)。
  • 您可以通过调用其toString实现或使用格式化程序生成 java.util.Date的日期时间值的String表示。
  • java.util.Date的toString方法令人困惑,因为它应用了JVM的默认时区。结果意味着j.u.Date有一个时区,实际上它没有。
  • java.util.Date和.Calendar类非常麻烦。避免他们。使用一个像样的日期时间库,如Joda-Time或Java 8中捆绑的新java.time包。
  • 您的代码忽略了时区的关键问题。 java.util.Date有一个日期和时间,所以你需要注意时区。
  • Joda-Time和java.time都使用ISO 8601标准定义的格式作为默认值。您也可以定义自己的格式,或使用本地化格式。

所以你的短语"用转换后的格式取回日期对象"是一个矛盾。日期时间对象(无论是java.util.Date还是Joda-Time或java.time)没有格式。您将生成的字符串表示与日期时间对象本身混淆。

使用Joda-Time 2.3的示例代码...

String input = "2014-10-04";

DateTimeZone timeZoneIndia = DateTimeZone.forID( "Asia/Kolkata" );
DateTime dateTimeIndia = new DateTime( input, timeZoneIndia ); // Defaults to beginning of the day.
DateTime dateTimeUtc = dateTimeIndia.withZone( DateTimeZone.UTC );
DateTime octoberSecond = new DateTime( 2014, 10, 2, 1, 2, 3, timeZoneIndia ).withTimeAtStartOfDay();

DateTimeFormatter formatter_Iso = ISODateTimeFormat.date();
String dateTimeIndiaAsStringIso = formatter_Iso.print( dateTimeIndia );

DateTimeFormatter formatter_Dmy = DateTimeFormat.forPattern( "dd-MM-yyyy" );
String dateTimeIndiaAsStringDmy = formatter_Dmy.print( dateTimeIndia );
DateTime dateTimeAgain = formatter_Dmy.withZone( timeZoneIndia ).parseDateTime( dateTimeIndiaAsStringDmy ); // Defaults to beginning of the day.

DateTimeFormatter formatter_Québécois = DateTimeFormat.forStyle( "FF" ).withLocale( Locale.CANADA_FRENCH );
String dateTimeIndiaAsStringQuébécois = formatter_Québécois.print( dateTimeIndia );

int daysBetween = Days.daysBetween( octoberSecond, dateTimeIndia ).getDays();
Interval interval = new Interval( octoberSecond, dateTimeIndia );
Period period = interval.toPeriod();

java.util.Date date = dateTimeIndia.toDate();

input: 2014-10-04
dateTimeIndia: 2014-10-04T00:00:00.000+05:30
dateTimeUtc: 2014-10-03T18:30:00.000Z
octoberSecond: 2014-10-02T00:00:00.000+05:30
dateTimeIndiaAsStringIso: 2014-10-04
dateTimeIndiaAsStringDmy: 04-10-2014
dateTimeAgain: 2014-10-04T00:00:00.000+05:30
dateTimeIndiaAsStringQuébécois: samedi 4 octobre 2014 0 h 00 IST
daysBetween: 2
interval: 2014-10-02T00:00:00.000+05:30/2014-10-04T00:00:00.000+05:30
period: P2D
date: Fri Oct 03 11:30:00 PDT 2014

转储到控制台...

System.out.println( "input: " + input );
System.out.println( "dateTimeIndia: " + dateTimeIndia );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "octoberSecond: " + octoberSecond );
System.out.println( "dateTimeIndiaAsStringIso: " + dateTimeIndiaAsStringIso );
System.out.println( "dateTimeIndiaAsStringDmy: " + dateTimeIndiaAsStringDmy );
System.out.println( "dateTimeAgain: " + dateTimeAgain );
System.out.println( "dateTimeIndiaAsStringQuébécois: " + dateTimeIndiaAsStringQuébécois );
System.out.println( "daysBetween: " + daysBetween );
System.out.println( "interval: " + interval );
System.out.println( "period: " + period );
System.out.println( "date: " + date );  // Applies JVM's default time zone. North America west coast time zone in my case.

跑步时......

input: 2014-10-04
dateTimeIndia: 2014-10-04T00:00:00.000+05:30
dateTimeUtc: 2014-10-03T18:30:00.000Z
octoberSecond: 2014-10-02T00:00:00.000+05:30
dateTimeIndiaAsStringIso: 2014-10-04
dateTimeIndiaAsStringDmy: 04-10-2014
dateTimeAgain: 2014-10-04T00:00:00.000+05:30
dateTimeIndiaAsStringQuébécois: samedi 4 octobre 2014 0 h 00 IST
daysBetween: 2
interval: 2014-10-02T00:00:00.000+05:30/2014-10-04T00:00:00.000+05:30
period: P2D
date: Fri Oct 03 11:30:00 PDT 2014

答案 4 :(得分:0)

You can use this

    public static Date getDateFromString(String format, String dateStr) {

        DateFormat formatter = new SimpleDateFormat(format);
        Date date = null;
        try {
            date = (Date) formatter.parse(dateStr);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        return date;
    }

    public static String getDate(Date date, String dateFormat) {
        DateFormat formatter = new SimpleDateFormat(dateFormat);
        return formatter.format(date);
    }