Including wildcard in a SimpleDateFormat

Viewed 923

I want a DateFormatter in java so that i can specify some special character as well as digits in a date expression. For ex :

String dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSS zzz";

Here dd is used to specify the day of month which is numeric. But i have a requirement to create a date as below :

 String stringDate = "2017-12-??T00:00Z";
 SimpleDateFormat formatter = new SimpleDateFormat(dateFormat);
 formatter.parse(stringDate);

I get an unparseable exception as the DAY specified here is ?? . Is there any workaround for this or shall i have to write a new parser ?

Thanks

2 Answers

Try escaping the additional literals using single quote

SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-'??T'HH:mm:ss.SSS zzz");

Also the value and the format given should match(Can edit the string date as required), in your case following syntax will work.

String stringDate = "2017-12-??T00:00Z";
Date date = (new SimpleDateFormat("yyyy-MM-'??T'HH:mmZ")).parse(stringDate.replaceAll("Z$", "+0000"));
System.out.println("date: " + (new SimpleDateFormat("yyyy-MM-dd'??T'HH:mmZ")).format(date));

Please note that 'Z' indicates that the timezone conforms to the RFC 822 time zone standard as well.

Edit: Consider a scheduler. Your comment may sound like what you need is a scheduler, for example Quartz scheduler. I include a link at the bottom. Then convert user input not to a YearMonth, OffsetDateTime or any other date-time object (because they don’t fit), but into a syntax that your scheduler can accept.

Original answer

I am giving you a couple of suggestions. It’s with reservation though: I don’t understand why you want this, not even exactly what you want, so these suggestions may not be the right ones for you.

One suggestion I am pretty sure of, though: do use java.time, the modern java date and time API, for your date and time work. It is so much nicer to work with than the old, poorly designed and long outdated date-time classes that include the notoriously troublesome SimpleDateFormat class.

Parsing year and month: If you just want the year and the month from a string that has question marks instead of the day of month, parse into a YearMonth:

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-'??T'HH:mmX");

    String stringDate = "2017-12-??T00:00Z";
    YearMonth ym = YearMonth.parse(stringDate, formatter);
    System.out.println("Year and month are " + ym);

Output from this snippet is:

Year and month are 2017-12

Parsing all information from the string: If you need time of day and offset from the same string too, just parse the string once and get the various information from the parse result:

    TemporalAccessor parsed = formatter.parse(stringDate);
    YearMonth ym = YearMonth.from(parsed);
    System.out.println("Year and month are " + ym);
    LocalTime time = LocalTime.from(parsed);
    System.out.println("Time of day is " + time);
    ZoneOffset offset = ZoneOffset.from(parsed);
    System.out.println("UTC offset is " + offset);
Year and month are 2017-12
Time of day is 00:00
UTC offset is Z

Using a default day of month: If you know what day of month you want instead of the question marks, specify it as a default value:

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("uuuu-MM-'??T'HH:mmX")
            .parseDefaulting(ChronoField.DAY_OF_MONTH, 23)
            .toFormatter();
    String stringDate = "2017-12-??T00:00Z";
    OffsetDateTime dateTime = OffsetDateTime.parse(stringDate, formatter);
    System.out.println("Date and time is " + dateTime);
Date and time is 2017-12-23T00:00Z

Accepting both numbers and question marks: If the date can be given as either numeric or question marks, use optional parts in the format pattern strings. Such are enclosed in square brackets:

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .appendPattern("uuuu-MM-[??][dd]'T'HH:mmX")
            .parseDefaulting(ChronoField.DAY_OF_MONTH, 23)
            .toFormatter();
    String stringDate = "2017-12-??T00:00Z";
    OffsetDateTime dateTime = OffsetDateTime.parse(stringDate, formatter);
    System.out.println("Date and time is " + dateTime);
    stringDate = "2018-02-16T00:00Z";
    dateTime = OffsetDateTime.parse(stringDate, formatter);
    System.out.println("Date and time is " + dateTime);
Date and time is 2017-12-23T00:00Z
Date and time is 2018-02-16T00:00Z

Tutorial links

Related