Search code examples
javastringdateformatjava-15

How can I format date in string in Java15?


I have a problem about showing date in the defined format in string text.

It throws an error which is shown below after the app runs.

Exception in thread "main" java.util.IllegalFormatConversionException: Y != java.lang.String

How can I solve it out?

Here is my code snippet which is shown below.

String exampleFourText = 
                """
                <html>                  
                   <body>               
                     <p> %s </p>
                     <p> %.1f </p>
                     <p> %d </p>
                     <p> %c </p>
                     <p> %1$tY-%1$tm-%1$td </p>
                   </body>              
                </html>                 
                """;
        
        exampleFourText = exampleFourText.formatted("Hello", 1234.6, 15 , 'y', new Date());
        
        System.out.println(exampleFourText);

Solution

  • You have used the wrong ordinal for the argument. It should be %5 instead of %1 because new Date() is the 5th argument.

    import java.util.Date;
    
    public class Main {
        public static void main(String[] args) {
            String exampleFourText = """
                    <html>
                       <body>
                         <p> %s </p>
                         <p> %.1f </p>
                         <p> %d </p>
                         <p> %c </p>
                         <p> %5$tY-%5$tm-%5$td </p>
                       </body>
                    </html>
                    """;
    
            exampleFourText = exampleFourText.formatted("Hello", 1234.6, 15, 'y', new Date());
    
            System.out.println(exampleFourText);
        }
    }
    

    Output:

    <html>
       <body>
         <p> Hello </p>
         <p> 1234.6 </p>
         <p> 15 </p>
         <p> y </p>
         <p> 2021-03-17 </p>
       </body>
    </html>
    

    However, the idiomatic way to do it is by using SimpleDateFormat as shown below:

    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.Locale;
    
    public class Main {
        public static void main(String[] args) {
            String exampleFourText = """
                    <html>
                       <body>
                         <p> %s </p>
                         <p> %.1f </p>
                         <p> %d </p>
                         <p> %c </p>
                         <p> %s </p>
                       </body>
                    </html>
                    """;
    
            exampleFourText = exampleFourText.formatted("Hello", 1234.6, 15, 'y',
                    new SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).format(new Date()));
    
            System.out.println(exampleFourText);
        }
    }
    

    Output:

    <html>
       <body>
         <p> Hello </p>
         <p> 1234.6 </p>
         <p> 15 </p>
         <p> y </p>
         <p> 2021-03-17 </p>
       </body>
    </html>
    

    Note that the java.util date-time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API*.

    import java.time.LocalDate;
    
    public class Main {
        public static void main(String[] args) {
            String exampleFourText = """
                    <html>
                       <body>
                         <p> %s </p>
                         <p> %.1f </p>
                         <p> %d </p>
                         <p> %c </p>
                         <p> %5$tY-%5$tm-%5$td </p>
                       </body>
                    </html>
                    """;
    
            exampleFourText = exampleFourText.formatted("Hello", 1234.6, 15, 'y', LocalDate.now());
    
            System.out.println(exampleFourText);
        }
    }
    

    Output:

    <html>
       <body>
         <p> Hello </p>
         <p> 1234.6 </p>
         <p> 15 </p>
         <p> y </p>
         <p> 2021-03-17 </p>
       </body>
    </html>
    

    As mentioned earlier, the idiomatic way to do it is by using a date-time formatter type which is DateTimeFormatter for the modern date-time API. However, since your desired format is also the default format of LocalDate#toString, you do not need DateTimeFormatter for this format. Just for the sake of completeness, I have also shown the use of DateTimeFormatter in the following code.

    import java.time.LocalDate;
    import java.time.format.DateTimeFormatter;
    import java.util.Locale;
    
    public class Main {
        public static void main(String[] args) {
            String exampleFourText = """
                    <html>
                       <body>
                         <p> %s </p>
                         <p> %.1f </p>
                         <p> %d </p>
                         <p> %c </p>
                         <p> %s </p>
                       </body>
                    </html>
                    """;
    
            exampleFourText = exampleFourText.formatted("Hello", 1234.6, 15, 'y', LocalDate.now());    
            System.out.println(exampleFourText);
    
            exampleFourText = exampleFourText.formatted("Hello", 1234.6, 15, 'y',
                    LocalDate.now().format(DateTimeFormatter.ofPattern("uuuu-MM-dd", Locale.ENGLISH)));    
            System.out.println(exampleFourText);
        }
    }
    

    Output:

    <html>
       <body>
         <p> Hello </p>
         <p> 1234.6 </p>
         <p> 15 </p>
         <p> y </p>
         <p> 2021-03-17 </p>
       </body>
    </html>
    
    <html>
       <body>
         <p> Hello </p>
         <p> 1234.6 </p>
         <p> 15 </p>
         <p> y </p>
         <p> 2021-03-17 </p>
       </body>
    </html>
    

    Learn more about the modern date-time API from Trail: Date Time.


    * For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.