How to get the given date string format(pattern) in java?

后端 未结 10 1636
抹茶落季
抹茶落季 2020-11-30 04:41

I want to get the format of a given date string.

Example: I have a string like 2011-09-27T07:04:21.97-05:00 and the date format of this string is

相关标签:
10条回答
  • 2020-11-30 04:57

    java.time and its predefined formatters

    We cannot do this for just any date-time format. There are thousands of them, we cannot know them all (someone will invent a new one tomorrow), and some look alike so much we can’t tell which we’ve got.

    I suggest that for the majority of purposes you need to parse the string, but you don’t need to know a format pattern for doing so. In very many cases, including the example from your question, 2011-09-27T07:04:21.97-05:00, we don’t need to specify a pattern (your string matches DateTimeFormatter.ISO_OFFSET_DATE_TIME).

    Since Java 8 came out in 2014 (and even if still using Java 6 or 7), use java.time, the modern Java date and time API, for your date and time work.

    I am defining an array of formatters for the formats we want to cater for. Please substitute your own set.

    private static final DateTimeFormatter[] formatters = {
            DateTimeFormatter.ISO_OFFSET_DATE_TIME,
            DateTimeFormatter.RFC_1123_DATE_TIME,
            new DateTimeFormatterBuilder().append(DateTimeFormatter.ISO_LOCAL_DATE)
                    .parseDefaulting(ChronoField.HOUR_OF_DAY, 0)
                    .parseDefaulting(ChronoField.OFFSET_SECONDS, 0)
                    .toFormatter(),
            DateTimeFormatter.ofLocalizedDateTime(FormatStyle.LONG).withLocale(Locale.US),
            DateTimeFormatter.ofPattern("MM/dd/uuuu HH:mm")
                    .withZone(ZoneId.of("America/Los_Angeles"))
    };
    

    The following method tries the formatters in turn until one works:

    private static OffsetDateTime parse(String dateTimeString) {
        for (DateTimeFormatter formatter : formatters) {
            try {
                return ZonedDateTime.parse(dateTimeString, formatter)
                        .toOffsetDateTime();
            } catch (DateTimeParseException dtpe) {
                // Ignore, try next formatter
            }
        }
        throw new IllegalArgumentException("String " + dateTimeString + " could not be parsed");
    } 
    

    Let’s try it out with some different strings:

        String[] dateTimeStrings = {
                "2011-09-27T07:04:21.97-05:00",
                "20110917",
                "2012-07-04",
                "12/27/2014 23:45",
                "Mon, 12 Nov 2018 01:32:10 GMT",
                "July 29, 2015 at 10:19:36 AM EDT",
        };
        
        for (String dts : dateTimeStrings) {
            try {
                System.out.format("%32s -> %s%n", dts, parse(dts));
            } catch (IllegalArgumentException iae) {
                System.out.format("%32s -> %s%n", dts, iae);
            }
        }
    

    Output is:

        2011-09-27T07:04:21.97-05:00 -> 2011-09-27T07:04:21.970-05:00
                            20110917 -> java.lang.IllegalArgumentException: String 20110917 could not be parsed
                          2012-07-04 -> 2012-07-04T00:00Z
                    12/27/2014 23:45 -> 2014-12-27T23:45-08:00
       Mon, 12 Nov 2018 01:32:10 GMT -> 2018-11-12T01:32:10Z
    July 29, 2015 at 10:19:36 AM EDT -> 2015-07-29T10:19:36-04:00
    

    Other options

    Techniques for parsing dates and times in multiple formats include:

    • Take a taste of the string to decide its format and use an appropriate formatter based on that. It’s best suited if you have just a few formats, though the answer by Vinit Solanki shows an elaborate version for quite many formats.
    • Use optional parts in a format pattern string. For example [uuuu][uu] will parse either four digit or two digit year (2021 or just 21).
    • Try several formatters in turn as shown in my code above. If you do need to know the pattern, use an array of patterns instead of an array of formatters.
    • Requiring the supplier of the string to supply a format patterns string too. This is not always as simple as it may sound, though.

    Beware of ambiguity. The classical example is the two formats MM-dd-yyyy and dd-MM-yyyy. If we get a string of 03-09-2020, there’s no way to tell whether it means March 9 or 3rd September. Even worse, 02-05-07 might be yy-MM-dd, dd-MM-yy, MM-dd-yy and even more possibilities. As a consequence, make sure you don’t include two (or more) formatters that may parse the same string into different results.

    Links

    • Oracle tutorial: Date Time explaining how to use java.time.
    • A fine answer by Arvind Kumar Avinash showing the use of optional parts in the format pattern string for parsing different formats.
    0 讨论(0)
  • 2020-11-30 05:02

    You could try dateparser.

    It can recognize any String automatically, and parse it into Date, Calendar, LocalDateTime, OffsetDateTime correctly and quickly(1us~1.5us).

    It doesn't based on any natural language analyzer or SimpleDateFormat or regex.Pattern.

    With it, you don't have to prepare any appropriate patterns like yyyy-MM-dd'T'HH:mm:ss'Z' or MM/dd/yyyy HH:mm:ss etc:

    Date date = DateParserUtils.parseDate("2015-04-29T10:15:00.500+0000");
    Calendar calendar = DateParserUtils.parseCalendar("2015-04-29T10:15:00.500Z");
    LocalDateTime dateTime = DateParserUtils.parseDateTime("2015-04-29 10:15:00.500 +00:00");
    

    And it has better performance than loop-try multiple SimpleDateFormat.

    Please enjoy it.

    0 讨论(0)
  • 2020-11-30 05:03

    you can do like this way, I don't know good way or not but try this

    first create the SimpleDateFormat object

    SimpleDateFormt sdf = new SimpleDateFormat("yyyy-MM-dd 'T' HH:mm:ss.SSS");
    

    now when check the date if this will parse in this format then change as per your format

    try{
         Date date = sdf.parse(yourdate);
         sdf.applyPattern("yy-mm--dd or mm/dd/yyyy");
         String dateformat = sdf.format(date);
    }catch(Exception ex) { // here forgot the exact exception class Parse exception was used
        // do something here
    }
    

    updated post:

    Returning a date format from an unknown format of date string in java

    How to convert String to Date without knowing the format?

    Parse any date in Java

    0 讨论(0)
  • 2020-11-30 05:05

    Here is a generic solution the determine the pattern without knowing the date pattern in advance and without calling the parse method of SimpleDateFormat for all formats. You can get any date pattern from date string value by using the regex.

    package com.utility.utils.modelmapper.datetime;
    
    import java.text.ParseException;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.HashMap;
    import java.util.Map;
    
    public class DateParser {
        private static final Map<String, String> DATE_FORMAT_REGEXPS = new HashMap<String, String>() {
            {
                put("^\\d{8}$", "yyyyMMdd");
                put("^\\d{12}$", "yyyyMMddHHmm");
                put("^\\d{8}\\s\\d{4}$", "yyyyMMdd HHmm");
                put("^\\d{14}$", "yyyyMMddHHmmss");
                put("^\\d{8}\\s\\d{6}$", "yyyyMMdd HHmmss");
                put("^\\d{1,2}-\\d{1,2}-\\d{4}$", "dd-MM-yyyy");
                put("^\\d{4}-\\d{1,2}-\\d{1,2}$", "yyyy-MM-dd");
                put("^\\d{1,2}/\\d{1,2}/\\d{4}$", "MM/dd/yyyy");
                put("^\\d{4}/\\d{1,2}/\\d{1,2}$", "yyyy/MM/dd");
                put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}$", "dd MMM yyyy");
                put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}$", "dd MMMM yyyy");
                put("^\\d{1,2}-\\d{1,2}-\\d{4}\\s\\d{1,2}:\\d{2}$", "dd-MM-yyyy HH:mm");
                put("^\\d{4}-\\d{1,2}-\\d{1,2}\\s\\d{1,2}:\\d{2}$", "yyyy-MM-dd HH:mm");
                put("^\\d{1,2}/\\d{1,2}/\\d{4}\\s\\d{1,2}:\\d{2}$", "MM/dd/yyyy HH:mm");
                put("^\\d{4}/\\d{1,2}/\\d{1,2}\\s\\d{1,2}:\\d{2}$", "yyyy/MM/dd HH:mm");
                put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}\\s\\d{1,2}:\\d{2}$", "dd MMM yyyy HH:mm");
                put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}\\s\\d{1,2}:\\d{2}$", "dd MMMM yyyy HH:mm");
                put("^\\d{1,2}-\\d{1,2}-\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd-MM-yyyy HH:mm:ss");
                put("^\\d{4}-\\d{1,2}-\\d{1,2}\\s\\d{1,2}:\\d{2}:\\d{2}$", "yyyy-MM-dd HH:mm:ss");
                put("^\\d{1,2}/\\d{1,2}/\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "MM/dd/yyyy HH:mm:ss");
                put("^\\d{4}/\\d{1,2}/\\d{1,2}\\s\\d{1,2}:\\d{2}:\\d{2}$", "yyyy/MM/dd HH:mm:ss");
                put("^\\d{1,2}\\s[a-z]{3}\\s\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd MMM yyyy HH:mm:ss");
                put("^\\d{1,2}\\s[a-z]{4,}\\s\\d{4}\\s\\d{1,2}:\\d{2}:\\d{2}$", "dd MMMM yyyy HH:mm:ss");
                put("^\\d{4}-\\d{1,2}-\\d{1,2}T\\d{1,2}:\\d{2}:\\d{2}\\.\\d{2}[-+]\\d{2}:\\d{2}$", "yyyy-MM-dd'T'HH:mm:ss.SSS");
            }
        };
    
        /**
         * To Determine the pattern by the string date value
         * 
         * @param dateString
         * @return The matching SimpleDateFormat pattern, or null if format is unknown.
         */
        public static String determineDateFormat(String dateString) {
            for (String regexp : DATE_FORMAT_REGEXPS.keySet()) {
                if (dateString.matches(regexp) || dateString.toLowerCase().matches(regexp)) {
                    return DATE_FORMAT_REGEXPS.get(regexp);
                }
            }
            return null;
        }
    
        public static void main(String[] args) {
            parse("2011-09-27T07:04:21.97-05:00"); //here is your value
            parse("20110917");
            parse("01/02/2018");
            parse("02-01-2018 06:07:59");
            parse("02 January 2018");
        }
    
        public static void parse(String value) {
            if (value != null) {
                String format = determineDateFormat(value);
                if (format != null) {
                    SimpleDateFormat sdf = new SimpleDateFormat(format);
                    try {
                        Date date = sdf.parse(value);
                        System.out.println(String.format("Format : %s | Value : %s | Parsed Date : %s", value, date, format));
                    } catch (ParseException e) {
                        // Failed the execution
                    }
                }
            }
        }
    }
    

    Console output of the class:

    Format : 2011-09-27T07:04:21.97-05:00 | Value : Tue Sep 27 07:04:21 LINT 2011 | Parsed Date : yyyy-MM-dd'T'HH:mm:ss.SSS
    Format : 20110917 | Value : Sat Sep 17 00:00:00 LINT 2011 | Parsed Date : yyyyMMdd
    Format : 01/02/2018 | Value : Tue Jan 02 00:00:00 LINT 2018 | Parsed Date : MM/dd/yyyy
    Format : 02-01-2018 06:07:59 | Value : Tue Jan 02 06:07:59 LINT 2018 | Parsed Date : dd-MM-yyyy HH:mm:ss
    Format : 02 January 2018 | Value : Tue Jan 02 00:00:00 LINT 2018 | Parsed Date : dd MMMM yyyy
    

    Maybe I missed some of the date-time patterns here but for that the correct regex pattern should be added in the map.

    0 讨论(0)
  • 2020-11-30 05:08

    You will need to take the inital date string and covert it to a date object and pass that converted date object and format it to your required string.

    0 讨论(0)
  • 2020-11-30 05:10

    Madhu's code is can workout, but some performance problem will arise because every failure case will raise the exception. i think we need to find the reguler expression solution to find the pattern form the given date String.

    you can find all most all reg expressions to date and time format in the following link

    http://regexlib.com/DisplayPatterns.aspx?cattabindex=4&categoryId=5&AspxAutoDetectCookieSupport=1

    0 讨论(0)
提交回复
热议问题