-1

I'm trying to take two strings and make it into a Date object. I'm having trouble trying to work out what formats I need to use.

The first string is a date and is in the format of : 5th Jan

The second string is a time and is in the format of : 8:15

The main issue is what the format would be for the 5th

Ceri Turner
  • 830
  • 2
  • 12
  • 36
  • 1
    In my opinion, the linked duplicate is incorrect. The questioner wants to parse strings that are in the given form `5th Jan 8:15` to a date and not format a date to be outputed having the suffix `th`. – Eritrean Jan 14 '21 at 19:54
  • 2
    @Eritrean - I agree with you. I would also like to mention that the OP has mentioned: `The first string is a date and is in the format of : 5th Jan The second string is a time and is in the format of : 8:15` i.e. there are two separate strings. – Arvind Kumar Avinash Jan 14 '21 at 19:57
  • 1
    @Eritrean Oops, I misread. – Sotirios Delimanolis Jan 14 '21 at 21:02
  • 1
    @LiveandLetLive Please reclose with these duplicates that address parsing: [1](https://stackoverflow.com/questions/28514346/parsing-a-date-s-ordinal-indicator-st-nd-rd-th-in-a-date-time-string), [2](https://stackoverflow.com/questions/17485907/java-dateformat-how-to-deal-with-st-nd-rd-th), [3](https://stackoverflow.com/questions/33389982/define-the-date-format-java-rd-st-th-nd/33390680), [4](https://stackoverflow.com/questions/4722289/parsing-dates-of-the-format-january-10th-2010-in-java-with-ordinal-indicato) – Sotirios Delimanolis Jan 14 '21 at 21:02
  • 1
    [5](https://stackoverflow.com/questions/65041758/date-formatting-with-special-pattern), [6](https://stackoverflow.com/questions/44185762/how-to-convert-the-date-value-26th-may-2017-to-26-05-2017), [7](https://stackoverflow.com/questions/36786407/date-format-of-22nd-april-2016), [8](https://stackoverflow.com/questions/32718078/convert-date-with-ordinal-numbers-11th-22nd-etc) – Sotirios Delimanolis Jan 14 '21 at 21:02
  • 3
    @SotiriosDelimanolis - Each of these links fulfils the requirement partially e.g. it's not just about parsing; it's also about combining the date & time. We can also find some questions regarding that requirement but if we start marking questions as a duplicate based on two or more questions regarding different types of requirements partially, most of the questions on SO can be marked as duplicate. Your experience on SO is almost 9 years more than mine and therefore, I am not challenging your opinion; rather, I'm just putting forward my point of view based on my limited experience on SO. – Arvind Kumar Avinash Jan 14 '21 at 21:29
  • 1
    This problem can be broken down into parts each of which has a solution in one or more other questions. But the parts are many even though the OP names one of them the main issue. So closing as a duplicate may not be the best thing to do in this case? If we close as a dupe, we should at least link to questions that answer the other parts mentioned by @LiveandLetLive too. And it may still put demands on the OP and other readers that you and I would not find hard, but could be a real challenge to someone less experienced. – Ole V.V. Jan 15 '21 at 04:38
  • 1
    If by *a Date object* you intended `java.util.Date`, don’t use that class. It is poorly designed and long outdated. Instead use `LocalDateTime` from [java.time, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Jan 15 '21 at 04:41
  • I downvoted the question because I find it poorly researched. – Ole V.V. Jan 15 '21 at 04:42

1 Answers1

11

Since your date string, 5th Jan doesn't have a year, you will have to use some default year e.g. the current year, which you can get from LocalDate.now(). You can put defaults using DateTimeFormatterBuilder#parseDefaulting. Additionally, you can also make the parser case-insensitive by using DateTimeFormatterBuilder#parseCaseInsensitive.

In order to parse a date string, 5th Jan, you can use the pattern, d'th' MMM. However, in order to deal with other suffixes like in 3rd, 1st etc., you should use the pattern, d['th']['st']['rd']['nd'] MMM where the patterns inside the square bracket are optional.

In order to parse a time string like 8:15, you can use the pattern, H:m.

Demo:

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        LocalDate date = LocalDate.now();
        DateTimeFormatter dtfForDate = new DateTimeFormatterBuilder()
                                        .parseCaseInsensitive()
                                        .parseDefaulting(ChronoField.YEAR, date.getYear())
                                        .appendPattern("d['th']['st']['rd']['nd'] MMM")
                                        .toFormatter(Locale.ENGLISH);

        DateTimeFormatter dtfForTime = DateTimeFormatter.ofPattern("H:m", Locale.ENGLISH);

        String strDate = "5th Jan";
        String strTime = "8:15";

        LocalDateTime ldt = LocalDate.parse(strDate, dtfForDate)
                                        .atTime(LocalTime.parse(strTime, dtfForTime));

        // Print the default string value i.e. the value returned by ldt.toString()
        System.out.println(ldt);

        // The default format omits seconds and fraction of second if they are 0. In
        // order to retain them in the output string, you can use DateTimeFormatter
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss");
        String formatted = dtf.format(ldt);
        System.out.println(formatted);
    }
}

Output:

2021-01-05T08:15
2021-01-05T08:15:00

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

Arvind Kumar Avinash
  • 71,965
  • 6
  • 74
  • 110