How to parse dates in multiple formats using SimpleDateFormat

前端 未结 12 1482
伪装坚强ぢ
伪装坚强ぢ 2020-11-22 08:41

I am trying to parse some dates that are coming out of a document. It would appear users have entered these dates in a similar but not exact format.

here are the for

相关标签:
12条回答
  • 2020-11-22 09:08

    In Apache commons lang, DateUtils class we have a method called parseDate. We can use this for parsing the date.

    Also another library Joda-time also have the method to parse the date.

    0 讨论(0)
  • 2020-11-22 09:15

    What about just defining multiple patterns? They might come from a config file containing known patterns, hard coded it reads like:

    List<SimpleDateFormat> knownPatterns = new ArrayList<SimpleDateFormat>();
    knownPatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"));
    knownPatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm.ss'Z'"));
    knownPatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss"));
    knownPatterns.add(new SimpleDateFormat("yyyy-MM-dd' 'HH:mm:ss"));
    knownPatterns.add(new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX"));
    
    for (SimpleDateFormat pattern : knownPatterns) {
        try {
            // Take a try
            return new Date(pattern.parse(candidate).getTime());
    
        } catch (ParseException pe) {
            // Loop on
        }
    }
    System.err.println("No known Date format found: " + candidate);
    return null;
    
    0 讨论(0)
  • 2020-11-22 09:17

    Implemented the same in scala, Please help urself with converting to Java, the core logic and functions used stays the same.

    import java.text.SimpleDateFormat
    import org.apache.commons.lang.time.DateUtils
    
    object MultiDataFormat {
      def main(args: Array[String]) {
    
    val dates =Array("2015-10-31","26/12/2015","19-10-2016")
    
    val possibleDateFormats:Array[String] = Array("yyyy-MM-dd","dd/MM/yyyy","dd-MM-yyyy")
    
    val sdf =  new SimpleDateFormat("yyyy-MM-dd") //change it as per the requirement
      for (date<-dates) {
        val outputDate = DateUtils.parseDateStrictly(date, possibleDateFormats)
        System.out.println("inputDate ==> " + date + ", outputDate ==> " +outputDate + " " + sdf.format(outputDate) )
      }
    }
    

    }

    0 讨论(0)
  • I'm solved this problem more simple way using regex

    fun parseTime(time: String?): Long {
        val longRegex = "\\d{4}+-\\d{2}+-\\d{2}+\\w\\d{2}:\\d{2}:\\d{2}.\\d{3}[Z]\$"
        val shortRegex = "\\d{4}+-\\d{2}+-\\d{2}+\\w\\d{2}:\\d{2}:\\d{2}Z\$"
    
        val longDateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.sssXXX")
        val shortDateFormat = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssXXX")
    
        return when {
            Pattern.matches(longRegex, time) -> longDateFormat.parse(time).time
            Pattern.matches(shortRegex, time) -> shortDateFormat.parse(time).time
            else -> throw InvalidParamsException(INVALID_TIME_MESSAGE, null)
        }
    }
    
    0 讨论(0)
  • 2020-11-22 09:21

    You'll need to use a different SimpleDateFormat object for each different pattern. That said, you don't need that many different ones, thanks to this:

    Number: For formatting, the number of pattern letters is the minimum number of digits, and shorter numbers are zero-padded to this amount. For parsing, the number of pattern letters is ignored unless it's needed to separate two adjacent fields.

    So, you'll need these formats:

    • "M/y" (that covers 9/09, 9/2009, and 09/2009)
    • "M/d/y" (that covers 9/1/2009)
    • "M-d-y" (that covers 9-1-2009)

    So, my advice would be to write a method that works something like this (untested):

    // ...
    List<String> formatStrings = Arrays.asList("M/y", "M/d/y", "M-d-y");
    // ...
    
    Date tryParse(String dateString)
    {
        for (String formatString : formatStrings)
        {
            try
            {
                return new SimpleDateFormat(formatString).parse(dateString);
            }
            catch (ParseException e) {}
        }
    
        return null;
    }
    
    0 讨论(0)
  • 2020-11-22 09:21

    This solution checks all the possible formats before throwing an exception. This solution is more convenient if you are trying to test for multiple date formats.

    Date extractTimestampInput(String strDate){
        final List<String> dateFormats = Arrays.asList("yyyy-MM-dd HH:mm:ss.SSS", "yyyy-MM-dd");    
    
        for(String format: dateFormats){
            SimpleDateFormat sdf = new SimpleDateFormat(format);
            try{
                return sdf.parse(strDate);
            } catch (ParseException e) {
                 //intentionally empty
            }
        }
            throw new IllegalArgumentException("Invalid input for date. Given '"+strDate+"', expecting format yyyy-MM-dd HH:mm:ss.SSS or yyyy-MM-dd.");
    
    }
    
    0 讨论(0)
提交回复
热议问题