【问题标题】:How to detect the given date format using java如何使用java检测给定的日期格式
【发布时间】:2012-07-03 20:02:19
【问题描述】:

我有一个获取字符串并将其更改为特定日期格式的方法,但问题是日期可以是任何格式 例如

16 July 2012

March 20 2012

2012 March 20

所以我需要检测字符串是哪种文件格式。

我使用下面的代码来测试它,但如果文件格式发生变化,我会得到异常。

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;
    }

【问题讨论】:

标签: java localdate


【解决方案1】:

也许最简单的解决方案是构建一组您可以合理预期的日期格式,然后依次尝试输入每种格式。

您可能想要标记模棱两可的输入,例如2012/5/6 是 6 月 5 日还是 5 月 6 日?

【讨论】:

  • 我赞成这个,因为我的想法是正确的,但为什么没有图书馆呢?这就是我正在寻找的。​​span>
【解决方案2】:

BalusC 写了一个简单的DateUtil,它适用于许多情况。您可能需要扩展它以满足您的要求。

这里是链接:https://balusc.omnifaces.org/2007/09/dateutil.html

以及你需要寻找的方法determineDateFormat()

【讨论】:

  • 但是它不考虑像 1990 年 8 月 19 日这样的日期
  • @user2822178:您可以在DATE_FORMAT_REGEXPS 中再添加一个reg ex,例如^[a-z]{3}\\s\\d{1,2}[,]\\s\\d{4}$", "MMM dd, yyyy"
  • 链接目前已断开
  • @BernhardWebstudio 修复了链接。谢谢。
【解决方案3】:

如果您使用 Joda Time(btw 很棒的库),您可以很容易地做到这一点:

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");

【讨论】:

    【解决方案4】:

    Apache commons 有一个实用方法来解决这个问题。 org.apache.commons.lang.time.DateUtils 类有一个方法 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
    

    通过尝试各种不同的解析器来解析表示日期的字符串。

    解析将依次尝试每个解析模式。仅当解析整个输入字符串时,解析才被视为成功。如果没有匹配的解析模式,则抛出 ParseException。

    解析器进行严格解析 - 它不允许诸如“1996 年 2 月 942 日”之类的日期。

    【讨论】:

    • 1996 年 2 月 942 日是一个日期? 942 代表什么??
    【解决方案5】:

    确定预期的格式,并尝试使用每种格式解析日期,一个接一个。只要其中一种格式无一例外地解析日期,就停止。

    【讨论】:

      【解决方案6】:

      Click to see the result

      使用正则表达式解析日期字符串。此正则表达式可以检测任何类型的日期格式。这里的示例代码还不包括时间。您可以更改代码以添加更多日期部分,例如时间和时区...月份名称取决于系统的默认语言区域设置。

      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);  
          }
      
      }
      

      【讨论】:

        【解决方案7】:
         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 "";
            }
        
        }
        

        【讨论】:

          【解决方案8】:

          我也遇到过这个问题,在某些地方:

          1. 我做了同样的事情,有一个符合我需要的格式集合。
          2. 更新了我的 sql 查询,它以我可以轻松解析的格式返回日期,例如在我的查询 TO_CHAR (o.CREATE_TS, 'MM-DD-YYYY') 中使用了这个 & 在转换为我所需的其他格式时,在 java 中使用“MM-dd-yyyy”来解析并更改为所需的格式。

          希望#2 至少能在少数情况下对您有所帮助。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2023-03-27
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2018-01-22
            相关资源
            最近更新 更多