Print from joda-time DateTimeFormatter with optional Parser

旧城冷巷雨未停 提交于 2019-12-10 22:39:57

问题


In a project using joda-time 2.1, I have the following 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);

It does exactly what I want. It parses dates with or without fractions, and prints them without fractions.

If I upgrade to a more recent version of joda-time, I get

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)

So I guess what I had before was an error, but it did exactly what I wanted to do! How do I get the same behavior, without making an error? I've tried using append(DateTimePrinter, DateTimeParser[]) with a null printer and with a printer that doesn't actually print anything and neither of them work.


回答1:


So I eventually figured this out, the solution is to construct the complete parser and printer separately, like so:

  /**
   * 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);



回答2:


Is there a reason you need to use the printer. Would this work for you? It compiles and outputs the correct date/time for me.

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);

From reading the Javdoc there is a mention of toParser(); not being used and instead to use toFormatter(); I hope this helps.

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

This might be more usefull actually

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



来源:https://stackoverflow.com/questions/29921105/print-from-joda-time-datetimeformatter-with-optional-parser

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!