Ramesh
Ramesh

Reputation: 2337

How to detect the given date format using java

I have a method that gets a string and change that to a particular date format but the thing is the date will be any format For Example

16 July 2012

March 20 2012

2012 March 20

So I need to detect the string is in which file format.

I use the below code to test it but I get exception if the file format changes.

private String getUpdatedDate(String updated) {
        Date date;
        String formatedDate = null;
        try {
            date = new SimpleDateFormat("d MMMM yyyy", Locale.ENGLISH)
                    .parse(updated);
            formatedDate = getDateFormat().format(date);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return formatedDate;
    }

Upvotes: 11

Views: 31053

Answers (9)

Tim Segall
Tim Segall

Reputation: 31

My library FTA (https://github.com/tsegall/fta) is designed to solve exactly this problem (among others). Here is an example:


import java.util.Locale;

import com.cobber.fta.dates.DateTimeParser;
import com.cobber.fta.dates.DateTimeParser.DateResolutionMode;

public abstract class DetermineDateFormat {

    public static void main(final String[] args) {
        final DateTimeParser dtp = new DateTimeParser(DateResolutionMode.MonthFirst, Locale.ENGLISH);

        System.err.println(dtp.determineFormatString("26 July 2012"));
        System.err.println(dtp.determineFormatString("March 9 2012"));
        // Note: Detected as MM/dd/yyyy despite being ambiguous as we indicated MonthFirst above when insufficient data
        System.err.println(dtp.determineFormatString("07/04/2012"));
        System.err.println(dtp.determineFormatString("2012 March 20"));
        System.err.println(dtp.determineFormatString("2012/04/09 18:24:12"));
    }

Which will give the following output:

MMMM d yyyy
MM/dd/yyyy
yyyy MMMM dd
yyyy/MM/dd HH:mm:ss

Upvotes: 2

NoisyBoy
NoisyBoy

Reputation: 364

I encountered this issue as well, where at some places:

  1. I did the same thing having a collection of format which matches my need.
  2. Updated my sql query in a way that it returns the date in a format which I can easily parse for e.g. used this in my query TO_CHAR (o.CREATE_TS, 'MM-DD-YYYY') & while converting in my other desired format used "MM-dd-yyyy" in java to parse and change to desired format.

Hopefully, #2 will help you in atleast few cases.

Upvotes: 0

RP-
RP-

Reputation: 5837

BalusC wrote a simple DateUtil which serves for many cases. You may need to extend this to satisfy your requirements.

Here is the link: https://balusc.omnifaces.org/2007/09/dateutil.html

and the method you need to look for determineDateFormat()

Upvotes: 5

Suheb Rafique
Suheb Rafique

Reputation: 151

 public static String detectDateFormat(Context context, String inputDate, String requiredFormat) {
    String tempDate = inputDate.replace("/", "").replace("-", "").replace(" ", "");
    String dateFormat = "";

    if (tempDate.matches("([0-12]{2})([0-31]{2})([0-9]{4})")) {
        dateFormat = "MMddyyyy";
    } else if (tempDate.matches("([0-31]{2})([0-12]{2})([0-9]{4})")) {
        dateFormat = "ddMMyyyy";
    } else if (tempDate.matches("([0-9]{4})([0-12]{2})([0-31]{2})")) {
        dateFormat = "yyyyMMdd";
    } else if (tempDate.matches("([0-9]{4})([0-31]{2})([0-12]{2})")) {
        dateFormat = "yyyyddMM";
    } else if (tempDate.matches("([0-31]{2})([a-z]{3})([0-9]{4})")) {
        dateFormat = "ddMMMyyyy";
    } else if (tempDate.matches("([a-z]{3})([0-31]{2})([0-9]{4})")) {
        dateFormat = "MMMddyyyy";
    } else if (tempDate.matches("([0-9]{4})([a-z]{3})([0-31]{2})")) {
        dateFormat = "yyyyMMMdd";
    } else if (tempDate.matches("([0-9]{4})([0-31]{2})([a-z]{3})")) {
        dateFormat = "yyyyddMMM";
    } else {

    }
    try {
        String formattedDate = new SimpleDateFormat(requiredFormat, Locale.ENGLISH).format(new SimpleDateFormat(dateFormat).parse(tempDate));
        Toast.makeText(context, formattedDate, Toast.LENGTH_SHORT).show();
        return formattedDate;
    } catch (Exception e) {
        Toast.makeText(context, "Please check the date format", Toast.LENGTH_SHORT).show();
        return "";
    }

}

Upvotes: 0

Tri Nguyen
Tri Nguyen

Reputation: 11

Click to see the result

Use the regex to parse the string for date. This regex can detect any kind of date format. The sample code here is not including time yet. You can change the code to add more parts of the date like time and time zone...The month name is depending on default language locale of the system.

import java.io.IOException;
import java.text.DateFormatSymbols;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class DateUtils {

    static String MONTH="";
    static String dateRegEx="";
    static Pattern DatePattern; 
    static HashMap<String, Integer> monthMap = new HashMap<String, Integer>();
    static {
        initializeMonthName();
        dateRegEx="(?i)(\\d{1,4}|"+MONTH+")[-|/|.|\\s+]?(\\d{1,2}|"+MONTH+")[-|/|.|,]?[\\s+]?(\\d{1,4}|"+MONTH+")[\\s+|\\t|T]?(\\d{0,2}):?(\\d{0,2}):?(\\d{0,2})[.|,]?[\\s]?(\\d{0,3})?([+|-])?(\\d{0,2})[:]?(\\d{0,2})[\\s+]?([A|P]M)?";
        DatePattern = Pattern.compile(dateRegEx);
    }

    private static void initializeMonthName() {
        String[] monthName=getMonthString(true);
        for(int i=0;i<12;i++){
            monthMap.put(monthName[i].toLowerCase(), Integer.valueOf(i+1));
        }

        monthName=getMonthString(false);
        for(int i=0;i<12;i++){
            monthMap.put(monthName[i].toLowerCase(), Integer.valueOf(i+1));
        }

        Iterator<String> it = monthMap.keySet().iterator();
        while(it.hasNext()){
            String month=it.next();
            if(MONTH.isEmpty()){
                MONTH=month;
            }else{
                MONTH=MONTH + "|" + month;
            }
        }
    }

    public static boolean isInteger(Object object) {
        if(object instanceof Integer) {
            return true;
        } else {
            try{
                Integer.parseInt(object.toString());
            }catch(Exception e) {
                return false;
            }           
        } 
        return true;
    }

    public static String[] getMonthString(boolean isShort) {
        DateFormatSymbols dfs = new DateFormatSymbols();
        if (isShort) {
         return dfs.getShortMonths();
        } else {
            return dfs.getMonths();
        }
    }

    public static int getMonthMap(String value) {

        if(monthMap.get(value)==null){
            return 0;
        }
        return monthMap.get(value).intValue();      
    }

    public static long parseDate(String value){

        Matcher matcher = DatePattern.matcher(value);
        int Year=0, Month=0, Day=0; 
        boolean isYearFound=false;
        boolean isMonthFound=false;
        boolean isDayFound=false;
        if(matcher.find()) {            
            for(int i=1;i<matcher.groupCount();i++){
                String data=matcher.group(i)==null?"":matcher.group(i); 
                if(data.equalsIgnoreCase("null")){
                    data="";
                }
                //System.out.println(String.valueOf(i) + ": " + data);
                switch(i){
                case 1:
                    if(!data.isEmpty()){
                        if(isInteger(data)){
                            Integer YMD = Integer.valueOf(data);
                            if(YMD==0){
                                return 0;
                            }
                            if(YMD>31){
                                Year = YMD.intValue();
                                isYearFound = true;
                            }else if(YMD>12){
                                Day = YMD.intValue();
                                isDayFound = true;
                            }else {
                                Month=YMD.intValue();
                                isMonthFound=true;
                            }
                        }else {
                            Month = getMonthMap(data.toLowerCase());
                            if(Month==0){
                                return 0;
                            }
                            isMonthFound=true;
                        }
                    }else {
                        return 0;
                    }
                    break;
                case 2:
                    if(!data.isEmpty()){
                        if(isInteger(data)){                            
                            Integer YMD = Integer.valueOf(data);
                            if(YMD==0){
                                return 0;
                            }

                            if(YMD>31){
                                if(isYearFound) {
                                    return 0;
                                }
                                Year = YMD.intValue();
                                isYearFound = true;
                            }else if(YMD>12){
                                if(isDayFound) {                                    
                                    return 0;
                                }
                                Day = YMD.intValue();
                                isDayFound = true;
                            }else {                             
                                if(isMonthFound){
                                    Day=YMD.intValue();
                                    isDayFound=true;
                                }else{
                                    Month=YMD.intValue();
                                    isMonthFound=true;
                                }
                            }
                        }else {
                            if(isMonthFound){
                                Day=Month;
                                isDayFound=true;
                            }
                            Month = getMonthMap(data.toLowerCase());
                            if(Month==0){
                                return 0;
                            }

                            isMonthFound=true;
                        }
                    }else {
                        return 0;
                    }
                    break;
                case 3:
                    if(!data.isEmpty()){
                        if(isInteger(data)){

                            Integer YMD = Integer.valueOf(data);
                            if(YMD==0){
                                return 0;
                            }
                            if(YMD>31){
                                if(isYearFound) {
                                    return 0;
                                }
                                Year = YMD.intValue();
                                isYearFound = true;
                            }else if(YMD>12){
                                if(isDayFound) {
                                    return 0;
                                }
                                Day = YMD.intValue();
                                isDayFound = true;
                            }else {
                                if(isMonthFound){
                                    Day=YMD.intValue();
                                    isDayFound=true;                                    
                                }else {
                                    Month = YMD.intValue();
                                    isMonthFound=true;
                                }

                            }
                        }else {
                            if(isMonthFound){
                                Day=Month;
                                isDayFound=true;
                            }
                            Month = getMonthMap(data.toLowerCase());
                            if(Month==0){
                                return 0;
                            }
                            isMonthFound=true;
                        }
                    }else {
                        return 0;
                    }
                    break;
                case 4:
                //hour
                    break;
                case 5:
                //minutes
                    break;
                case 6:
                //second
                    break;
                case 7:
                //millisecond
                    break;
                case 8:
                //time zone +/-
                    break;
                case 9:
                //time zone hour
                    break;
                case 10:
                // time zone minute
                    break;
                case 11:
                //AM/PM
                    break;
                }

            }           
        }

        Calendar c = Calendar.getInstance();
        c.set(Year, Month-1, Day, 0, 0); 
        return c.getTime().getTime();
    }


    public static void main(String[] argv) throws IOException {

        long d= DateUtils.parseDate("16 July 2012");
        Date dt = new Date(d);
        SimpleDateFormat df2 = new SimpleDateFormat("d MMMM yyyy");
        String dateText = df2.format(dt);
        System.out.println(dateText);

        d= DateUtils.parseDate("March 20 2012");
        dt = new Date(d);
        dateText = df2.format(dt);
        System.out.println(dateText);        

        d= DateUtils.parseDate("2012 March 20");
        dt = new Date(d);
        dateText = df2.format(dt);
        System.out.println(dateText);  
    }

}

Upvotes: 0

tanmally
tanmally

Reputation: 1076

Apache commons has a utility method to solve this problem . The org.apache.commons.lang.time.DateUtils class has a method parseDateStrictly

   public static Date parseDateStrictly(String str,
                                         String[] parsePatterns)
                                  throws ParseException

 Parameters:
        str - the date to parse, not null
        parsePatterns - the date format patterns to use, see SimpleDateFormat, not null

Parses a string representing a date by trying a variety of different parsers.

The parse will try each parse pattern in turn. A parse is only deemed successful if it parses the whole of the input string. If no parse patterns match, a ParseException is thrown.

The parser parses strictly - it does not allow for dates such as "February 942, 1996".

Upvotes: 2

Andreas Johansson
Andreas Johansson

Reputation: 1145

If you're using Joda Time (awesome library btw) you can do this quite easily:

DateTimeParser[] dateParsers = { 
        DateTimeFormat.forPattern("yyyy-MM-dd HH").getParser(),
        DateTimeFormat.forPattern("yyyy-MM-dd").getParser() };
DateTimeFormatter formatter = new DateTimeFormatterBuilder().append(null, dateParsers).toFormatter();

DateTime date1 = formatter.parseDateTime("2012-07-03");
DateTime date2 = formatter.parseDateTime("2012-07-03 01");

Upvotes: 3

JB Nizet
JB Nizet

Reputation: 691943

Decide which formats are expected, and try to parse the date with each format, one after the other. Stop as soon as one of the formats parses the date without exception.

Upvotes: 0

Brian Agnew
Brian Agnew

Reputation: 272337

Perhaps the easiest solution is to build a collection of date formats you can reasonably expect, and then try the input against each one in turn.

You may want to flag ambiguous inputs e.g. is 2012/5/6 the 5th June or 6th May ?

Upvotes: 9

Related Questions