Java 公历字段

Java GregorianCalendar Fields

我尝试将字符串转换为 GregorianCalendar,然后进行检查。 下面,我 post 我的代码。我真的很困惑为什么字段看起来不对。 非常感谢您的帮助。

public class test{

    private static final ArrayList<String> MONTH_OF_YEAR = new ArrayList(Arrays.asList( "Jan", "Feb", "Mar", "Apr", "May", 
          "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"));

    static GregorianCalendar date;

    public static void main(String[] args){
        String t = "28-Mar-2099 11294.94 11279.65";
        String[] splitStr = t.split(" ");

        System.out.println(splitStr[0]);

        date = ConvertToDate(splitStr[0]);
        System.out.println(date.getTime());

        System.out.println(date.DAY_OF_MONTH);
        System.out.println(date.MONTH);
        System.out.println(date.YEAR);

    }


    private static GregorianCalendar ConvertToDate(String dt){
        String[] splitStr = dt.split("-");
        if(splitStr.length != 3){
            throw new IllegalArgumentException();
        }
        int dayOfMonth = Integer.parseInt(splitStr[0]);
        int year = Integer.parseInt(splitStr[2]);
        int month = MONTH_OF_YEAR.indexOf(splitStr[1]);
        if(month < 0 || month > 11){
            throw new IllegalArgumentException();
        }
        return new GregorianCalendar(year, month, dayOfMonth);
    }
}

输出如下:

28-Mar-2099
Sat Mar 28 00:00:00 PDT 2099
5
2
1

谁能帮我解释为什么字段与日期不匹配?

这些:

System.out.println(date.DAY_OF_MONTH);
System.out.println(date.MONTH);
System.out.println(date.YEAR);

应该是:

System.out.println(date.get(Calendar.DAY_OF_MONTH));
System.out.println(date.get(Calendar.MONTH));
System.out.println(date.get(Calendar.YEAR));

(然后记住 Calendar.MONTH 是从 0 开始的。)

DAY_OF_MONTH等值都是常量,基本上表示你要获取哪个字段。不幸的是,日历 API 从根本上来说非常糟糕 :( 如果你可以使用 Joda Time 或 Java 8 java.time API,它们都会好得多。

另请注意,实际上无需编写您自己的日历解析代码 - SimpleDateFormat 等已经存在

tl;博士

LocalDate.parse(
    "28-Mar-2099 11294.94 11279.65".split( " " )[0] ,        // Extract the part of the input text we care about.
    DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US ) // Specify formatting pattern to match input. The `Locale` determines human language and cultural norms needed for parsing.
).getYear() // .getMonthValue() .getDayOfMonth()             // Interrogate for the parts of the date you desire.

java.time

现代方法使用 java.time classes 取代了麻烦的旧日期时间 classes。 GregorianCalendar class 被 ZonedDateTime 取代。

您想要一个只有日期的值,没有时间和时区。所以使用 LocalDate.

提取我们关心的输入部分。

String[] pieces = "28-Mar-2099 11294.94 11279.65".split( " " );
String input = pieces[0] ;

定义格式模式以匹配该输入。顺便说一句,尽可能使用标准 ISO 8601 格式来交换日期时间值,而不是此处遇到的格式。

DateTimeFormatter f = DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US ) ;
LocalDate ld = LocalDate.parse( input , f ) ;

提取日期的任何部分。

int year = ld.getYear() ;
Month month = ld.getMonth() ;  // An enum object from `Month` enum class.
int monthNumber = ld.getMonthValue() ;
int dayOfMonth = ld.getDayOfMonth() ;

关于java.time

java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

要了解更多信息,请参阅 Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310

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

从哪里获得java.time classes?

  • Java SE 8, Java SE 9,及以后
    • 内置。
    • 标准 Java API 的一部分,带有捆绑实施。
    • Java 9 添加了一些小功能和修复。
  • Java SE 6 and Java SE 7
  • Android
    • Android java.time classes.
    • 捆绑实施的更高版本
    • 对于较早的Android,ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See

ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.