2

I try to convert a String to GregorianCalendar, and then check it. Below, I post my codes. I really confuse that why the fields seem wrong. Thanks a lot for help.

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

And the outputs are like these:

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

Could anyone help me explain why that the fields don't match the date?

Liran Jiao
  • 43
  • 4

2 Answers2

3

These:

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

Should be:

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

(And then remember that Calendar.MONTH is 0-based.)

The DAY_OF_MONTH etc values are constants, basically indicating which field you want to fetch. The calendar API is fundamentally pretty awful, unfortunately :( If you can possibly use Joda Time or the Java 8 java.time API instead, they're both much better.

Also note that there's really no need to write your own calendar parsing code - it already exists with SimpleDateFormat etc.

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
0

tl;dr

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

The modern approach uses java.time classes that supplanted the troublesome old date-time classes. The GregorianCalendar class was replaced by ZonedDateTime.

You want a date-only value, without a time-of-day and without a time zone. So use LocalDate.

Extract the part of the input we care about.

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

Define a formatting pattern to match that input. By the way, when possible, use the standard ISO 8601 formats for exchanging date-time values whenever possible rather than format encountered here.

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

Extract any part of the date.

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

About java.time

The 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.

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

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

Using a JDBC driver compliant with JDBC 4.2 or later, you may exchange java.time objects directly with your database. No need for strings nor java.sql.* classes.

Where to obtain the java.time classes?

The 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.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154