Using GregorianCalendar with SimpleDateFormat

后端 未结 5 1930
渐次进展
渐次进展 2020-12-03 04:45

So, I\'ve been racking my brain over this (should-be) simple exercise to make the program turn a date string into a GregorianCalendar object, format it, and ret

相关标签:
5条回答
  • 2020-12-03 05:09

    tl;dr

    LocalDate.parse(
        "23-Mar-2017" ,
        DateTimeFormatter.ofPattern( "dd-MMM-uuuu" , Locale.US ) 
    )
    

    Avoid legacy date-time classes

    The Question and other Answers are now outdated, using troublesome old date-time classes that are now legacy, supplanted by the java.time classes.

    Using java.time

    You seem to be dealing with date-only values. So do not use a date-time class. Instead use LocalDate. The LocalDate class represents a date-only value without time-of-day and without time zone.

    Specify a Locale to determine (a) the human language for translation of name of day, name of month, and such, and (b) the cultural norms deciding issues of abbreviation, capitalization, punctuation, separators, and such.

    Parse a string.

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

    Generate a string.

    String output = ld.format( f );
    

    If you were given numbers rather than text for the year, month, and day-of-month, use LocalDate.of.

    LocalDate ld = LocalDate.of( 2017 , 3 , 23 );  // ( year , month 1-12 , day-of-month )
    

    See this code run live at IdeOne.com.

    input: 23-Mar-2017

    ld.toString(): 2017-03-23

    output: 23-Mar-2017


    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?

    • Java SE 8, Java SE 9, and later
      • Built-in.
      • Part of the standard Java API with a bundled implementation.
      • Java 9 adds some minor features and fixes.
    • Java SE 6 and Java SE 7
      • Much of the java.time functionality is back-ported to Java 6 & 7 in ThreeTen-Backport.
    • Android
      • Later versions of Android bundle implementations of the java.time classes.
      • For earlier Android, the ThreeTenABP project adapts ThreeTen-Backport (mentioned above). See How to use ThreeTenABP….

    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.

    0 讨论(0)
  • 2020-12-03 05:10

    Why such complications?

    public static GregorianCalendar convertFromDMY(String dd_mm_yy) throws ParseException 
    {
        SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
        Date date = fmt.parse(dd_mm_yy);
        GregorianCalendar cal = GregorianCalendar.getInstance();
        cal.setTime(date);
        return cal;
    }
    
    0 讨论(0)
  • 2020-12-03 05:16
    1. You are putting there a two-digits year. The first century. And the Gregorian calendar started in the 16th century. I think you should add 2000 to the year.

    2. Month in the function new GregorianCalendar(year, month, days) is 0-based. Subtract 1 from the month there.

    3. Change the body of the second function as follows:

          String dateFormatted = null;
          SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
          try {
              dateFormatted = fmt.format(date);
          }
          catch ( IllegalArgumentException e){
              System.out.println(e.getMessage());
          }
          return dateFormatted;
      

    After debugging, you'll see that simply GregorianCalendar can't be an argument of the fmt.format();.

    Really, nobody needs GregorianCalendar as output, even you are told to return "a string".

    Change the header of your format function to

    public static String format(final Date date) 
    

    and make the appropriate changes. fmt.format() will take the Date object gladly.

    1. Always after an unexpected exception arises, catch it yourself, don't allow the Java machine to do it. This way, you'll understand the problem.
    0 讨论(0)
  • 2020-12-03 05:17

    A SimpleDateFormat, as its name indicates, formats Dates. Not a Calendar. So, if you want to format a GregorianCalendar using a SimpleDateFormat, you must convert the Calendar to a Date first:

    dateFormat.format(calendar.getTime());
    

    And what you see printed is the toString() representation of the calendar. It's intended usage is debugging. It's not intended to be used to display a date in a GUI. For that, use a (Simple)DateFormat.

    Finally, to convert from a String to a Date, you should also use a (Simple)DateFormat (its parse() method), rather than splitting the String as you're doing. This will give you a Date object, and you can create a Calendar from the Date by instanciating it (Calendar.getInstance()) and setting its time (calendar.setTime()).

    My advice would be: Googling is not the solution here. Reading the API documentation is what you need to do.

    0 讨论(0)
  • 2020-12-03 05:19

    SimpleDateFormat.format() method takes a Date as a parameter. You can get a Date from a Calendar by calling its getTime() method:

    public static String format(GregorianCalendar calendar) {
        SimpleDateFormat fmt = new SimpleDateFormat("dd-MMM-yyyy");
        fmt.setCalendar(calendar);
        String dateFormatted = fmt.format(calendar.getTime());
    
        return dateFormatted;
    }
    

    Also note that the months start at 0, so you probably meant:

    int month = Integer.parseInt(splitDate[1]) - 1;
    
    0 讨论(0)
提交回复
热议问题