将Joda-Time DateTime - ISO 8601日期格式转换为另一种日期格式

10

在我的Java应用程序中,我使用Joda-Time将用户输入的日期从MM/dd/yyyy格式转换为ISO 8601格式,以便将其保存在数据库中。

有人能告诉我如何使用Joda-Time将ISO 8601日期转换回MM/dd/yyyy格式吗?

我的代码将用户日期转换为ISO 8601日期格式:

String date1 = "05/05/2013";
DateTimeFormatter parser1 = DateTimeFormat.forPattern("MM/dd/yyyy");
DateTime dateTimeObj1 = DateTime.parse(date1,parser1);
DateTimeFormatter isoDateFormat = ISODateTimeFormat.dateTime();
String isoDateStr = isoDateFormat.print(dateTimeObj1);
System.out.println(isoDateStr);

你想在后续阶段仅有日期以 ISO 格式进行操作吗?你可以将该值解析为 DateTime 对象,并按照 MM/dd/yyyy 的格式进行格式化。 - Sotirios Delimanolis
1个回答

23

使用相同的格式化器

Joda-Time 2.3中,您需要使用相同的DateTimeFormatter对象来解析和print(渲染字符串)。

时区

请注意,您的代码未考虑时区。在这种情况下,您将得到JVM的默认时区。这不是一个好习惯。

DateTime表示日期和时间。当仅解析日期部分的字符串时,时间部分会自动设置为一天中的第一刻钟。该第一刻钟因时区而异。因此,应用不同的时区会得到不同的结果,宇宙时间轴上的不同点,不同的自纪元以来的毫秒数。

请注意在定义格式化器时调用withZone

字符串

请记住,DateTime对象不是字符串。您可以通过以下两种方式生成包含在DateTime实例中的日期时间信息的字符串表示形式:
  • 在DateTime实例上调用toString方法。
    每个DateTime都有一个内置的ISO 8601 格式化程序,由“toString”方法自动使用。
  • 实例化自己的DateTimeFormatter实例。
下面的示例代码中展示了这两种字符串生成技术。

示例代码

// Usually better to specify a time zone than rely on default.
DateTimeZone timeZone = DateTimeZone.forID( "Asia/Hong_Kong" );
DateTimeFormatter formatter = DateTimeFormat.forPattern( "MM/dd/yyyy" ).withZone( timeZone );

// Parse string into a DateTime. Define the format.
String input = "05/05/2013";
DateTime dateTime = formatter.parseDateTime( input ); // Defaults to first moment of the day.

// Render date-time as an ISO 8601 string. The "toString" method on DateTime defaults to a built-in ISO 8601 formatter.
// A DateTime object is not itself a string. But a DateTime can generate a string by calling its "toString" method.
String iso8601String = dateTime.toString();

// Parse string into a DateTime. Passing to constructor conveniently uses the built-in ISO 8601 parser built into DateTime class.
DateTime dateTime2 = new DateTime( iso8601String, timeZone );

// Render date-time as a string in a particular format.
String output = formatter.print( dateTime2 );

与其硬编码特定格式,您可以软编码本地化格式。

String outputUS = DateTimeFormat.forStyle( "S-" ).withLocale( Locale.US ).print( dateTime2 );
String outputQuébécois = DateTimeFormat.forStyle( "F-" ).withLocale( Locale.CANADA_FRENCH ).print( dateTime2 );

转储到控制台...

System.out.println( "dateTime: " + dateTime ); // Implicit call to "toString" method in DateTime class generates a new string using a built-in formatter for ISO 8601 format.
System.out.println( "iso8601String: " + iso8601String );
System.out.println( "dateTime2: " + dateTime2 ); // Another implicit call to "toString" method on DateTime class. Generates a new string in ISO format.
System.out.println( "output: " + output );

运行时...

dateTime: 2013-05-05T00:00:00.000+08:00
iso8601String: 2013-05-05T00:00:00.000+08:00
dateTime2: 2013-05-05T00:00:00.000+08:00
output: 05/05/2013

字符串不是日期时间

不要把日期时间对象看作字符串。

DateTime 没有格式。该类可以解析 ISO 8601 格式的字符串以实例化日期时间对象。同样,DateTimeFormatter 可以解析字符串以实例化日期时间对象。

相反地,DateTime 有一个 toString 实现,生成日期时间对象值的字符串表示形式。同样,DateTimeFormatter 可以生成日期时间对象值的字符串表示形式。

在所有这些情况下,字符串表示形式与日期时间对象完全不同且独立。


非常感谢您提供详细的回答。我有些困惑,在 DateTime dateTime 步骤中,从 println 打印的结果中我们已经得到了 ISO8601 格式的日期,那么为什么还需要使用 String iso8601String 步骤再次获取 ISO8601 格式的日期呢? - MChan
@MChan 因为你提出了这个问题。我将展示完整的过程:字符串(仅日期)→ DateTime 实例 → 字符串(ISO)→ DateTime 实例 → 字符串(仅日期)。在 DateTime dateTime 行中,我们没有 ISO 字符串。 ISO 字符串是在第一个 System.out.println 行中生成的,该行隐式调用了 dateTime 对象上的 toString 方法。DateTime 实例不是一个字符串,但是它可以通过调用其 toString 方法(该方法又调用内置格式化程序)生成 ISO 字符串。请阅读文档。如果您需要其他类型的字符串,请定义自己的格式化程序实例。 - Basil Bourque

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