使用可选的解析器从 joda-time DateTimeFormatter 打印

Print from joda-time DateTimeFormatter with optional Parser

在一个使用joda-time 2.1的项目中,我有以下DateTimeFormatter

   /**
   * Parser for the "fraction" part of a date-time value.
   */
  private static final DateTimeParser FRACTION_PARSER =
      new DateTimeFormatterBuilder()
          .appendLiteral('.')
          .appendFractionOfSecond(3, 9)
          .toParser();

  /**
   * A formatter for a "local" date/time without time zone offset
   * (in the format "yyyy-dd-mmThh:mm:ss[.fff]").
   */
  private static final DateTimeFormatter FORMAT_LOCAL =
      new DateTimeFormatterBuilder()
          .append(ISODateTimeFormat.date())
          .appendLiteral('T')
          .append(ISODateTimeFormat.hourMinuteSecond())
          .appendOptional(FRACTION_PARSER)
          .toFormatter()
          .withZone(DateTimeZone.UTC);

它完全符合我的要求。它解析带或不带分数的日期,并在不带分数的情况下打印它们。

如果我升级到更新版本的 joda-time,我会得到

Exception in thread "main" java.lang.ExceptionInInitializerError
Caused by: java.lang.UnsupportedOperationException: Printing is not supported
    at org.joda.time.format.DateTimeFormatterBuilder.toPrinter(DateTimeFormatterBuilder.java:136)

所以我猜我之前的错误,但它确实做了我想做的事!如何在不出错的情况下获得相同的行为?我试过将 append(DateTimePrinter, DateTimeParser[]) 与空打印机和实际上不打印任何东西的打印机一起使用,但它们都不起作用。

您是否有需要使用打印机的原因。这对你有用吗?它为我编译并输出正确的 date/time。

private static final DateTimeParser FRACTION_PARSER =
        new DateTimeFormatterBuilder()
                .appendLiteral('[')
                .appendLiteral('.')
                .appendFractionOfSecond(3, 9)
                .appendLiteral(']')
                .toParser();

/**
 * A formatter for a "local" date/time without time zone offset
 * (in the format "yyyy-dd-mmThh:mm:ss[.fff]").
 */
private static final DateTimeFormatter FORMAT_LOCAL =
        new DateTimeFormatterBuilder()
                .append(ISODateTimeFormat.date())
                .appendLiteral('T')
                .append(ISODateTimeFormat.hourMinuteSecond())

                .appendOptional(FRACTION_PARSER)
                        .toFormatter()
                        .withZone(DateTimeZone.UTC);

String strInputDateTime = "1990-12-11T13:12:22[.025]";

DateTime dt = FORMAT_LOCAL.parseDateTime(strInputDateTime);

System.out.println(dt);

阅读 Javdoc 时提到了 toParser();未被使用而是使用 toFormatter();希望对您有所帮助。

toParser

public DateTimeParser toParser() Internal method to create a DateTimeParser instance using all the appended elements. Most applications will not use this method. If you want a parser in an application, call toFormatter() and just use the parsing API.

Subsequent changes to this builder do not affect the returned parser.

Throws: UnsupportedOperationException - if parsing is not supported

http://www.joda.org/joda-time/apidocs/index.html

这实际上可能更有用

public DateTimeFormatter toFormatter() Constructs a DateTimeFormatter using all the appended elements. This is the main method used by applications at the end of the build process to create a usable formatter.

Subsequent changes to this builder do not affect the returned formatter.

The returned formatter may not support both printing and parsing. The methods DateTimeFormatter.isPrinter() and DateTimeFormatter.isParser() will help you determine the state of the formatter.

Throws: UnsupportedOperationException - if neither printing nor parsing is supported

所以我最终想通了,解决方案是分别构建完整的解析器和打印机,如下所示:

  /**
   * Parser for the "fraction" part of a date-time value.
   */
  private static final DateTimeParser FRACTION_PARSER =
      new DateTimeFormatterBuilder()
          .appendLiteral('.')
          .appendFractionOfSecond(3, 9)
          .toParser();

  private static final DateTimeParser BASE_PARSER =
      new DateTimeFormatterBuilder()
          .append(ISODateTimeFormat.date())
          .appendLiteral('T')
          .append(ISODateTimeFormat.hourMinuteSecond())
          .appendOptional(FRACTION_PARSER)
          .toParser();

  private static final DateTimePrinter BASE_PRINTER =
      new DateTimeFormatterBuilder()
          .append(ISODateTimeFormat.date())
          .appendLiteral('T')
          .append(ISODateTimeFormat.hourMinuteSecond())
          // omit fraction of second
          .toPrinter();

  /**
   * A formatter for a "local" date/time without time zone offset
   * (in the format "yyyy-dd-mmThh:mm:ss[.fff]").
   */
  private static final DateTimeFormatter FORMAT_LOCAL =
      new DateTimeFormatterBuilder()
          .append(BASE_PRINTER, BASE_PARSER)
          .toFormatter()
          .withZone(DateTimeZone.UTC);