【问题标题】:HTML - Custom input date formatHTML - 自定义输入日期格式
【发布时间】:2014-06-19 18:31:26
【问题描述】:

我想用自动格式化的 html 构建一个输入日期。例如,如果我写 '1 dec 1994' 或 '12/1/1994' 它会自动检测到它是一个日期并重新格式化它:'12.1.1994' 并创建一个日期对象:这正是擅长的。

我不想自己构建它,因为它看起来太复杂而且选项太多,所以你知道任何解决方案吗?

【问题讨论】:

  • 这么多选择?格式取决于脚本用于哪个国家/地区。在英语世界中,12/1/1994 通常表示 12 月 1 日,在其他一些国家,则表示 1 月 12 日。因此,请确定您所在国家/地区常见的日期格式,然后我认为 regexp 将是最好的解决方案。
  • 我能想到几十个...我会尝试正则表达式
  • 您可以使用 jQuery 收听该字段并拆分您需要的空格或字符,创建掩码或读取值并根据您的需要进行转换,我的意思是将 1 dec 1994 转换为 01 /12/1994 您需要使用 array() 与 javascript 比较值。
  • @ncohen 也许好的方法是用空格替换除 0-9 和 a-z 之外的所有符号。当你按空间分割它时,它应该创建 3 个元素的数组。如果其中一个元素包含 st、nd、rd 或 th - 将其用作一天。如果其中一个元素是纯字母,则将其转换为数字并将其用作月份。如果其中一个元素有 4 位数字,则将其用作年份。如果它们都不适用,则使用第一个元素作为月份,第二个作为日期,第三个作为年份。等...
  • @user2781994 有趣...我会尝试使用正则表达式。我还需要跟踪输入何时失去焦点以更改值。顺便说一句,你知道我怎么能抓住它吗?

标签: html html-input


【解决方案1】:

这是一个复杂的函数,它应该将许多常见的日期字符串转换为日、月和年整数。这肯定有一些弱点,所以请随意评论任何错误或升级想法。

这个脚本背后的想法是:

  1. 实际日期信息仅来自数字和字母
    • 解决方案:将所有额外的符号(点、斜线、破折号)转换为空格并最终删除多个空格
  2. 上述步骤应创建由 3 个日期部分除以空格的字符串
    • 解决办法: 用空格分割日期字符串 -> 3 个部分分开,但哪一个是日、月和年?
  3. 4 位数字的部分必须是年(日或月永远不会有 4 位数字)
  4. 1 到 2 位数字和 st|nd|rd|th 的部分必须是日期
  5. 月份名称为 (jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec) 的部分必须是月份
  6. 如果将 2 部分分配给其变量,则第三部分必须属于一个尚未设置的变量
  7. 如果上述条件只设置了一个变量或没有变量,则假定使用 YYYYMMDD 或 MMDDYYYY 格式
    • 解决办法:如果日期的第一部分有4位,则必须是YYYYMMDD格式,否则使用MMDDYYYY

定义变量

  • el = 输入日期的输入
  • reg_day = 匹配 1 到 2 位不区分大小写的后缀(1st、2ND、3Rd)
  • reg_month = 匹配任何月份名称,?: 表示它不被记住并且子字符串不会在结果数组中
  • reg_year = 匹配任何 4 位字符串

代码:

var el = document.getElementById("date_input"),
    reg_day = /\d{1,2}(st|nd|rd|th)/i,
    reg_month = /(?:jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)/i.
    reg_year = /^\d{4}$/;

添加前导零功能

此函数将前导零(如果需要)添加到日或月整数(返回字符串)

  1. 将整数转换为字符串(因为整数不能有前导零)
  2. 如果其长度小于 2(数字 1 到 9),则添加“0”
  3. 返回带零的字符串

代码:

function addZero(num) {
    var s = num.toString();
    while (s.length < 2) s = "0" + s;
    return s;
}

转换函数

  1. 如果month是一个单词,找到它的3个字母缩写并返回月份编号
  2. 如果月份是有效数字(01-12 或 1-12),解析并返回
  3. 否则返回 null(未知格式)

代码:

function getMonth(month) {
    if(month.search(reg_month) > -1) {
        var month_name = month.match(reg_month)[0];
        return new Date(Date.parse(month_name + " 1, 2000")).getMonth() + 1;
    } else if(month.search(/^(0?[1-9]|1[0-2])$/) > -1) {
        return parseInt(month);
    }
    return null;
}

  1. 删除所有字母(如 st 或 th)
  2. 如果 day 是有效数字(01-31 或 1-31),则解析并返回
  3. 否则返回 null(未知格式)

代码:

function getDay(day) {
    day = day.replace(/\D+/g, "")
    if(day.search(/^(0?[1-9]|[12][0-9]|3[01])$/) > -1) {
        return parseInt(day);
    }
    return null;
}

  1. 如果年份是有效的 4 位数字,则解析并返回
  2. 否则返回 null(未知格式)

代码:

function getYear(year) {
    if(year.search(reg_year) > -1) {
        return parseInt(year);
    }
    return null;
}

Onblur - 当输入失去焦点时

  • val = 日期输入值
  • array = 日、月、年值的数组
    1. 用空格替换所有非数字或 a-z 字符
    2. 用一个空格替换所有多个空格
    3. 用空格分割字符串(应该给出 3 个元素的数组)
  • data_not_used = array 中的索引数组,这些索引不是由以下 for 分配的
  • 日、月、年变量的声明

代码:

el.onblur = function(){
    var val = el.value,
        array = val.replace(/[^A-Za-z0-9]/g, " ").replace(/ +(?= )/g, "").split(" "),
        data_not_used = [],
        day = null, month = null, year = null;
// fn continues below

  1. 如果数组元素是带后缀的天,则将其分配给天变量
  2. 如果数组元素是月份名称,则将其编号分配给月份变量
  3. 如果数组元素是年份,则将其分配给年份变量
  4. 否则将 array 索引添加到 data_not_used

    (更多在变量部分和 getDay、getMonth 和 getYear 函数中)

代码:

// fn continues above
    for(var i=0; i < array.length; i++) {
        if(array[i].search(reg_day) > -1) {
            day = getDay(array[i]);
        } else if(array[i].search(reg_month) > -1) {
            month = getMonth(array[i]);
        } else if(array[i].search(reg_year) > -1) {
            year = getYear(array[i]);
        } else {
            data_not_used.push(i);
        }
    }
// fn continues below

  • 如果缺少一个以上的日、月、年:
    1. 如果数组中的第一个元素包含 4 位数字,则采用 YYYYMMDD 格式
    2. 否则采用 MMDDYYYY 格式
  • 如果仅缺少日、月、年中的一个,则用剩余值填充它

代码:

// fn continues above
    if(data_not_used.length > 1) {
        if(array[0].search(/\d{4}/) > -1) {
            year = getYear(array[0]);
            month = getMonth(array[1]);
            day = getDay(array[2]);
        } else {
            month = getMonth(array[0]);
            day = getDay(array[1]);
            year = getYear(array[2]);
        }
    }

    else if(data_not_used.length === 1) {
        var data = array[data_not_used[0]];
        if(day === null) day = getDay(data);
        else if(month === null) month = getMonth(data);
        else if(year === null) year = getYear(data);
    }
// fn continues below

  1. 如果设置了所有日、月、年,则将日和月转换为带有前导零(1 到 01)的字符串并将它们打印到控制台中
  2. 其他打印错误与调试值

代码:

// fn continues above
    if(day!==null && month!==null && year!==null) {
        console.log(addZero(month) + "/" + addZero(day) + "/" + year);
    } else {
        console.error("Date not valid: " + month + "/" + day + "/" + year);
    }
};

别忘了关闭 onblur() 函数!希望这会有所帮助 ;)

【讨论】:

    猜你喜欢
    • 2017-04-30
    • 1970-01-01
    • 2017-07-28
    • 2014-08-17
    • 2020-02-21
    • 2014-08-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多