日期格式的字符串,可能有以下格式:
'2008-10-11'
'2009-10-11 23:22'(日期和时间之间是空格)
'2009-10-11 23:22:49'
日期分隔符可以是'-','/','.',但这3种情况下时间分隔符一定是':'
日期也可能是'年月日',但此时时间分隔符可能是':'('2009年01月11日 23:22:23'),也可能是'时分秒'('2009年01月11日 23时22分23秒')不会出现其他情况求验证表达式,并能转化为java.util.Date

解决方案 »

  1.   

    比较复杂
    (\d{4}[-/\.]{1}\d{2}[-/\.]{1}\d{2}(\s{1}\d{2}:\d{2}(:\d{2}){0,1}){0,1})
    |
    (\d{4}年}\d{2}月\d{2}日(\s{1}\d{2}:\d{2}(:\d{2}){0,1}){0,1}) 
    |
    (\d{4}年}\d{2}月\d{2}日(\s{1}\d{2}时\d{2}分(\d{2}秒){0,1}){0,1})分成了三个分支结构,由“|”(意同或)连接。其中对于月份,日期,时,分,秒等数字合理性的判断没写在里面,免得太长,影响阅读理解。
    具体数字的范围判断如下,可以逐个按照位置上面的正则里
             月   0{1}/d{1}|10|11|12
    日   [0-2]{1}/d{1}|30|31
    时   [0-1]{1}/d{1}|20|21|22|23
    分   [0-5]{1}/d{1}
    秒   [0-5]{1}/d{1}
      

  2.   

    顶java2000_net
    不要把简单的事情复杂化~
      

  3.   

    由于日期涉及闰年、大月、小月问题,因此日期的正则表达式非常复杂,加上又有那么多的格式和时间,
    写出来的话,正则表达式字符长度将会超过 400 个字符。建议使用正则表达式验证基本的数据格式,至于数据的合法性应采用代码逻辑进行验证。
    原来在 CSDN 的 blog 里写的,带有行内嵌注释:   1. import java.util.regex.Matcher;  
       2. import java.util.regex.Pattern;  
       3.   
       4. public class DateRegex {      
       5.   
       6.     public static void main(String[] args) {  
       7.         String[] str = {  
       8.                 "2001-00-00", "2001-01-01", "2001-01-30", "2001-01-31",  
       9.                 "2001-01-32", "2001-02-01", "2001-02-27", "2001-02-28",  
      10.                 "2004-02-29", "2001-02-29", "2001-02-30", "2001-02-31",  
      11.                 "2001-02-32", "2001-03-01", "2001-03-10", "2001-03-29",  
      12.                 "2001-03-30", "2001-03-31", "2001-03-32", "2001-04-01",  
      13.                 "2001-04-10", "2001-04-29", "2001-04-30", "2001-04-31",  
      14.                 "2001-04-32", "2001-05-01", "2001-05-10", "2001-05-29",  
      15.                 "2001-05-30", "2001-05-31", "2001-05-32", "2001-06-01",  
      16.                 "2001-06-10", "2001-06-29", "2001-06-30", "2001-06-31",  
      17.                 "2001-06-32", "2001-07-01", "2001-07-10", "2001-07-29",  
      18.                 "2001-07-30", "2001-07-31", "2001-07-32", "2001-08-01",  
      19.                 "2001-08-10", "2001-08-29", "2001-08-30", "2001-08-31",  
      20.                 "2001-08-32", "2001-09-01", "2001-09-10", "2001-09-29",  
      21.                 "2001-09-30", "2001-09-31", "2001-09-32", "2001-10-01",  
      22.                 "2001-10-10", "2001-10-29", "2001-10-30", "2001-10-31",  
      23.                 "2001-10-32", "2001-11-01", "2001-11-10", "2001-11-29",  
      24.                 "2001-11-30", "2001-11-31", "2001-11-32", "2001-12-01",  
      25.                 "2001-12-10", "2001-12-29", "2001-12-30", "2001-12-31",  
      26.                 "2001-12-32", "2001-13-01", "2001-13-10", "2001-13-29",  
      27.                 "2001-13-30", "2001-13-31", "2001-13-32", "245-12-04",  
      28.                 "100-02-29" , "200-02-29" , "300-02-29" , "400-02-29",  
      29.                 "500-02-29" , "800-02-29" , "900-02-29" , "2008-02-29",  
      30.                 "1900-02-29", "2000-02-29", "1-01-01"   , "1-02-28",  
      31.                 "0-01-01"   , "1-12-31"   , "351-02-29" , "352-02-29",  
      32.                 "353-02-29" , "354-02-29" , "355-02-29" , "356-02-29",  
      33.                 "357-02-29" , "358-02-29" , "350-02-29" , "1-02-29",  
      34.                 "2-02-29"   , "3-02-29"   , "4-02-29"   , "5-02-29",  
      35.                 "6-02-29"   , "7-02-29"   , "8-02-29"   , "9-02-29",  
      36.                 "10-02-29"  , "11-02-29"  , "12-02-29"  , "13-02-29",  
      37.                 "14-02-29"  , "15-02-29"  , "16-02-29"  , "17-02-29",  
      38.                 "18-02-29"  , "19-02-29"  , "20-02-29"  , "21-02-29",  
      39.                 "22-02-29"  , "23-02-29"  , "24-02-29"  , "25-02-29",  
      40.                 "26-02-29"  , "27-02-29"  , "28-02-29"  , "29-02-29",  
      41.                 "0-01-12"   , "00-01-12"  , "000-01-12" , "0000-01-12",  
      42.                 "0028-02-29"  
      43.             };  
      44.   
      45.         String moreMonth =  
      46.                 "(?:                         \n" +  
      47.                 "   ## 日期前是大月              \n" +  
      48.                 "   ## 01 03 05 07 08        \n" +  
      49.                 "   ## 10 12 月                 \n" +  
      50.                 "   (?<=                     \n" +  
      51.                 "       (?:                  \n" +  
      52.                 "           0[13578]         \n" +  
      53.                 "           |                \n" +  
      54.                 "           1[02]            \n" +  
      55.                 "       )                    \n" +  
      56.                 "       -                    \n" +   // 分隔符  
      57.                 "   )                        \n" +  
      58.                 "   (?:                      \n" +  
      59.                 "       ## 大月的日期 29       \n" +  
      60.                 "       29                   \n" +  
      61.                 "       |                    \n" +  
      62.                 "       ## 大月的日期 30~31    \n" +  
      63.                 "       3[01]                \n" +  
      64.                 "   )                        \n" +  
      65.                 ")                           \n";  
      66.   
      67.         String lesserMonth =   
      68.                 "(?:                         \n" +  
      69.                 "   ## 日期前是小月              \n" +  
      70.                 "   ## 04 06 09 11 月         \n" +  
      71.                 "   (?<=                     \n" +  
      72.                 "       (?:                  \n" +  
      73.                 "           0[469]           \n" +  
      74.                 "           |                \n" +  
      75.                 "           11               \n" +  
      76.                 "       )                    \n" +  
      77.                 "       -                    \n" +   // 分隔符  
      78.                 "   )                        \n" +  
      79.                 "   (?:                      \n" +  
      80.                 "       ## 小月的日期 29       \n" +  
      81.                 "       29                   \n" +  
      82.                 "       |                    \n" +  
      83.                 "       ## 小月的日期 30~31    \n" +  
      84.                 "       30                   \n" +  
      85.                 "   )                        \n" +  
      86.                 ")                           \n";  
      87.   
      

  4.   

      88.         String feburary =  
      89.                 "(?:                                            \n" +  
      90.                 "   ## 29 号必须满足的条件,闰年                       \n" +  
      91.                 "   (?<=                                        \n" +  
      92.                 "       (?:                                     \n" +  
      93.                 "           ## 被 4 整除的年份                       \n" +  
      94.                 "           ## 除去最后两位为 0 的年份                \n" +  
      95.                 "           ## 最后两位数一定是:                     \n" +  
      96.                 "           ##    20 40 60 80                   \n" +  
      97.                 "           ## 04 24 44 64 84                   \n" +  
      98.                 "           ## 08 28 48 68 88                   \n" +  
      99.                 "           ## 12 32 52 72 92                   \n" +  
     100.                 "           ## 16 36 56 76 96                   \n" +  
     101.                 "           (?:                                 \n" +  
     102.                 "               [0-9]{0,2}(?!0?0)               \n" +  
     103.                 "               (?:                             \n" +  
     104.                 "                   ## 当尾数为[048]时前面不允是    \n" +  
     105.                 "                   ## [13579]中的任何一个         \n" +  
     106.                 "                   [02468]?(?<![13579])[048]   \n" +  
     107.                 "                   |                           \n" +  
     108.                 "                   [13579][26]                 \n" +  
     109.                 "               )                               \n" +  
     110.                 "           )                                   \n" +  
     111.                 "           |                                   \n" +  
     112.                 "           ## 能被 400 整除的年份                   \n" +  
     113.                 "           ## 其头两位数字规定同上                   \n" +  
     114.                 "           (?:                                 \n" +  
     115.                 "               (?:                             \n" +  
     116.                 "                   [02468]?[048]               \n" +  
     117.                 "                   |                           \n" +  
     118.                 "                   [13579][26]                 \n" +  
     119.                 "               )                               \n" +  
     120.                 "               00                              \n" +  
     121.                 "           )                                   \n" +  
     122.                 "       )                                       \n" +  
     123.                 "       -02-                                    \n" +   // 02 前后为分隔符  
     124.                 "   )                                           \n" +  
     125.                 "   (?:29)                                      \n" +  
     126.                 ")                                              \n";  
     127.   
     128.         String debugRegex =  
     129.                 "(?x:                                \n" +  
     130.                 "   ## 年份 0001~9999,并忽略0年         \n" +  
     131.                 "   (?:[0-9]{1,4}(?<!^0?0?0?0))      \n" +  
     132.                 "   -                                \n" +   // 分隔符  
     133.                 "   ## 月份                               \n" +  
     134.                 "   (?:                              \n" +  
     135.                 "       0[1-9]                       \n" +  
     136.                 "       |                            \n" +  
     137.                 "       1[0-2]                       \n" +  
     138.                 "   )                                \n" +  
     139.                 "   -                                \n" +   // 分隔符  
     140.                 "   (?:                              \n" +  
     141.                 "       ## 每个月都有的公共日期 01~09    \n" +  
     142.                 "       0[1-9]                       \n" +  
     143.                 "       |                            \n" +  
     144.                 "       ## 每个月都有的公共日期 10~19    \n" +  
     145.                 "       1[0-9]                       \n" +  
     146.                 "       |                            \n" +  
     147.                 "       ## 每个月都有的公共日期 20~28    \n" +  
     148.                 "       2[0-8]                       \n" +  
     149.                 "       |                            \n" +  
     150.                             moreMonth                    +  
     151.                 "       |                            \n" +  
     152.                             lesserMonth                  +  
     153.                 "       |                            \n" +  
     154.                             feburary                     +  
     155.                 "   )                                \n" +  
     156.                 ")";          
     157.   
     158.         Pattern pattern = Pattern.compile(debugRegex);  
     159.         Matcher matcher = pattern.matcher("");  
     160.         for(String s : str) {  
     161.             matcher.reset(s);  
     162.             System.out.println(s + " " + matcher.matches());  
     163.         }  
     164.     }  
     165. }上面那个是带注释用于调试用的,去掉空格、注释和换行后正式用的是这样的:(?:[0-9]{1,4}(?<!^0?0?0?0))-(?:0[1-9]|1[0-2])-(?:0[1-9]|1[0-9]|2[0-8]|(?:(?<=(?:0[13578]|1[02])-)(?:29|3[01]))|(?:(?<=(?:0[469]|11)-)(?:29|30))|(?:(?<=(?:(?:[0-9]{0,2}(?!0?0)(?:[02468]?(?<![13579])[048]|[13579][26]))|(?:(?:[02468]?[048]|[13579][26])00))-02-)(?:29)))这种表达式仅仅适合学习研究之用,仅仅是验证日期的还没带上时间,共有 266 个字符,
    因此并不建议用于正式环境之中,用了是跟自己过不过。另外,在下面这个链接中可以找到很多日期和时间的正则表达式(这个站点上面的表达式很多都是用 .net 正则
    表达式语法写的,在 Java 中可能不能正常使用):
    http://regexlib.com/DisplayPatterns.aspx?cattabindex=4&categoryId=5
      

  5.   


    这么麻烦啊?难道真的要自己写代码实现,本来想在XML里面配置一下的?
      

  6.   

    是的,这种很难进行配置,由于你所要求的格式太多,而且表达式除了闰年、大月、小月在内的逻辑之外,还带有
    其他的逻辑(日期分隔符可以是'-','/','.',但这3种情况下时间分隔符一定是':' ),带有逻辑的东西正则表达
    式都很难实现,就算实现了字符数将非常之多,验证效率也很低,还有可能会存在很多的 bug。由于表达式很长,
    而且相似的字符也很多,直接导致测试和修改都会变得极其困难。
      

  7.   

    正则表达式花样很多
    但用的多的也就这几个
    看看我的总结
    http://blog.csdn.net/terryzero/archive/2009/01/05/3716115.aspx
      

  8.   

    错了
    ---------------->(\d{4}[-/\.]{1}\d{2}[-/\.]{1}\d{2}(\s{1}\d{2}:\d{2}(:\d{2}){0,1}){0,1}) 

    (\d{4}年\d{2}月\d{2}日(\s{1}\d{2}:\d{2}(:\d{2}){0,1}){0,1}) 

    (\d{4}年\d{2}月\d{2}日(\s{1}\d{2}时\d{2}分(\d{2}秒){0,1}){0,1}) 
      

  9.   

    换个实现方法,干脆不用正则表达式,使用 Ext 或类似 JavaScript UI 库里的 DatePicker 组件供用户选择日期和时间,没有输入的过程,选择的时间日期的格式就固定了,只要在 Server 端按固定的格式校验或直接解析字符串到 Date 就 OK。这种一堆要求的客户就得拿这招对付他/她。
      

  10.   

    带时间选择的 JavaScript 组件这儿有一个:http://www.my97.net/dp/demo/
      

  11.   


    嗯,Server 端的校验无论如何都得做,但客户端选择到的时间日期的格式固定下来后服务器端可以直接用 DateFormat 解析了。