Java日期格式驗證幾個執行個體程式

來源:互聯網
上載者:User

需求:因為系統有很多日期格式,所以日期驗證函式的輸入是一個日期文字和一個格式字串。格式字串用的是Java定義的格式(參考地址)。
剛開始寫時,覺得很簡單,直接就寫了下面的代碼。

 代碼如下 複製代碼

public static boolean isDate(String dttm, String format) {
    boolean retValue = false;
    if (dttm != null) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        try {
            formatter.parse(dttm);
            retValue = true;
        } catch (ParseException e) {
        }
    }
    return retValue;
}

寫好之後,一測試,發現2012/12/43這種日期居然也返回True,於是查資料,設定轉化時不進位formatter.setLenient(false);之後好用了,代碼為

 代碼如下 複製代碼

public static boolean isDate(String dttm, String format) {
    boolean retValue = false;
    if (dttm != null) {
        SimpleDateFormat formatter = new SimpleDateFormat(format);
        formatter.setLenient(false);
        try {
            formatter.parse(dttm);
            retValue = true;
        } catch (ParseException e) {
        }
    }
    return retValue;
}

寫到這裡,以為萬事大吉了。但之後的測試卻發現,當日期有分隔字元時,只會轉換前一部分,比如2012/12/43ABCD也會返回True。想了一下,覺得先轉為日期型,再轉為字串,再比較兩者是否相等,但馬上就否決了這個方案,因為客戶要求的是不嚴格的日期形式,如格式為yyyy/MM/dd,輸入2012/1/2也需要驗證通過。然後考慮了一下,覺得先用Regex做一次驗證,然後再驗證是否是日期型。代碼如下

 代碼如下 複製代碼

public static boolean isDate(String dttm, String format) {
    boolean retValue = false;

    if (dttm == null || dttm.isEmpty() || format == null || format.isEmpty()) {
        return retValue;
    }

    String regFormat = format;
    regFormat = regFormat.replaceAll("(^')|('$)", "");
    regFormat = regFormat.replaceAll("'([^'])", "$1");
    regFormat = regFormat.replace("''", "'");
    regFormat = regFormat.replace("\", "\\");
    regFormat = regFormat.replaceAll("[MdHmsS]+", "
\\d+");
    regFormat = regFormat.replaceAll("[y]+", "
\\d{1,4}");
    if (!dttm.matches("^" + regFormat + "$")) {
        return false;
    }

    SimpleDateFormat formatter = new SimpleDateFormat(format);
    formatter.setLenient(false);
    try {
        formatter.parse(dttm);
        retValue = true;
    } catch (ParseException e) {
    }

    return retValue;
}

上面的代碼只對應了yMdHmsS,雖然對當時的系統已經足夠了,但還是感覺不太爽,覺得應該有一種通用的方法。於是查Java的API,發現parse方法還有一個帶參數的方法。理解了它的使用方法之後,把代碼改成下面的樣子

 代碼如下 複製代碼

 private static boolean isDate(String dttm, String format) {
    if (dttm == null || dttm.isEmpty() || format == null || format.isEmpty()) {
        return false;
    }

    DateFormat formatter = new SimpleDateFormat(format);
    formatter.setLenient(false);
    ParsePosition pos = new ParsePosition(0);
    Date date = formatter.parse(dttm, pos);

    if (date == null || pos.getErrorIndex() > 0) {
        return false;
    }
   
    if (pos.getIndex() != dttm.length()) {
        return false;
    }

    return true;
}

本來以為這樣應該萬事大吉了,但之後的測試又發現兩個Bug。一個是,當輸入的日期沒有年份(需求是沒有輸入年份是預設當前年份)時,預設取的是1970年,這樣的話,如果當年是閏年的話,2/29號就驗證出錯了;另一個是Java的日期和Oracle的日期大小不同,Oracle好像最大隻支援到9999年,而Java可以有2萬多年。所以代碼又被改成了下面的樣子

 代碼如下 複製代碼

private static boolean isDate(String dttm, String format) {
    if (dttm == null || dttm.isEmpty() || format == null || format.isEmpty()) {
        return false;
    }

    if (format.replaceAll("'.+?'", "").indexOf("y") < 0) {
        format += "/yyyy";
        DateFormat formatter = new SimpleDateFormat("/yyyy");
        dttm += formatter.format(new Date());
    }

    DateFormat formatter = new SimpleDateFormat(format);
    formatter.setLenient(false);
    ParsePosition pos = new ParsePosition(0);
    Date date = formatter.parse(dttm, pos);

    if (date == null || pos.getErrorIndex() > 0) {
        return false;
    }
    if (pos.getIndex() != dttm.length()) {
        return false;
    }

    if (formatter.getCalendar().get(Calendar.YEAR) > 9999) {
        return false;
    }

    return true;
}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.