Joda Time bug还是我的错误?(Java Joda时间日期为字符串解析)

Ed *_*d . 2 java parsing date jodatime

所以我在解析日期时遇到了问题,使用了JodaTime年表,IslamicChronology所以写了一个小例子来演示我的问题.

这是代码:

import org.joda.time.Chronology;
import org.joda.time.format.DateTimeFormatter;
import org.joda.time.format.DateTimeFormat;
import org.joda.time.chrono.IslamicChronology;

import java.util.Date;

/**
 * Test
 */
public class Test
{
    public static void main(String[] args)
    {
        Date now = new Date();

        String format = "dd MMM yyyy";
        Chronology calendarSystem = IslamicChronology.getInstance();
        DateTimeFormatter formatter = DateTimeFormat.forPattern(format).withChronology(calendarSystem);

        String nowAsString = formatter.print(now.getTime());

        System.out.println("nowAsString = " + nowAsString);

        long parsedNowTs = formatter.parseMillis(nowAsString);

        String parsedNowTsAsString = formatter.print(parsedNowTs);
    }
}
Run Code Online (Sandbox Code Playgroud)

并输出:

nowAsString = 16 10 1430
Exception in thread "main" java.lang.IllegalArgumentException: Invalid format: "16 10 1430" is malformed at "10 1430"
    at org.joda.time.format.DateTimeFormatter.parseMillis(DateTimeFormatter.java:634)
    at test.Test.main(Test.java:40)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    ...
Run Code Online (Sandbox Code Playgroud)

我认为问题是月份名称是数字,但我是对的吗?有人有什么建议吗?如果年表是格里高利的话,则无法重新创建.

提前致谢.

Ed *_*d . 7

如果有人感兴趣...我找到了一个解决方法:

  • 创建一个新类,例如IslamicChronologyWithNames,它委托给org.joda.time.DateTimeZoneIslamicChronology包中的实例
  • 修改一个方法; assemble(Fields fields):调用委托的方法,然后将fields.monthOfYear(可能是dayOfWeek)设置为您自己的子类BasicMonthOfYearDateTimeField
  • 然后,子类BasicMonthOfYearDateTimeField可以在属性文件名中查找月份(或日期为DayOfWeek ...)名称.子类需要在org.joda.time.chrono包中才能扩展BasicMonthOfYearDateTimeField.

还有一个问题是,Joda时间似乎在调用子类的方法之前验证了您正在解析的日期getAsText(int fieldValue, Locale locale),因为它不知道您的类返回的月份名称,验证失败,因此从不调用方法.我的解决方法是在此类中使用静态方法,将日期作为具有伊斯兰月份名称的字符串转换为具有格里高利英语月份名称的字符串的日期.所以在调用之前parseDateTime(),调用静态方法,然后日期字符串通过验证.然后,不要在convertText()方法中处理伊斯兰月份名称,而是在子类中使用默认的格里高利实现:

protected int convertText(String text, Locale locale)
{
    return GJLocaleSymbols.forLocale(locale).monthOfYearTextToValue(text);
}
Run Code Online (Sandbox Code Playgroud)

这应该工作!希望对有同样问题的人有意义.


jar*_*bjo 5

格式模板中的MMM表示缩写的月份名称.数字月份索引应以MM表示.

在阅读了对dtsazza答案的评论之后,我首先意识到了你的实际问题.:)

我已经看了一下JODA源代码,似乎对伊斯兰计时码表的支持相当破碎.首先,格式化程序不支持月份名称,因此模式MMM和MMMM格式化为月份编号,尽管根据DateTimeFormat的文档,缩写的月份名称应该用于MMM,而完整的月份名称用于MMMM .

您的代码示例的一个问题parseMillis是始终使用ISO年表,尽管格式化程序已配置了另一个年表.API文档中也提到了这一点,尽管不是特别直观.

如果我更换parseMillisparseDateTime,我本来预计将用于解析年表(至少文档是这么说的),但它看起来好像实现忽略的配置年表和与ISO年代的推移在这里.