鍍金池/ 問答/HTML/ JavaScript 根據(jù)自定義的日期格式創(chuàng)建 Date 對象

JavaScript 根據(jù)自定義的日期格式創(chuàng)建 Date 對象

如題所述, JavaScript 根據(jù)自定義 Pattern 創(chuàng)建 Date 對象好像沒有原生的方法, 有什么好的解決方案么? (((o(?▽?)o)))

回答
編輯回答
怣痛

已經(jīng)自己寫了一個解析方法

/**
 * 解析字符串為 Date 對象
 * @param dateStr 日期字符串
 * @param fmt 日期字符串的格式
 * 目前僅支持使用 y(年),M(月),d(日),h(時),m(分),s(秒),S(毫秒)
 */
Date.of = function (dateStr, fmt) {
    if (!dateStr) {
        throw new Error('傳入的日期字符串不能為空!');
    }
    if (!fmt) {
        throw new Error('傳入的日期字符串的自定義格式不能為空!');
    }

    /**
     * 日期格式化對象
     * @param name 日期格式的名稱
     * @param format 日期的格式值
     * @param value 格式化得到的值
     * @constructor
     */
    function DateFormat(name, format, value, index) {
        this.name = name;
        this.format = format;
        this.value = value;
        this.index = index;
    }

    //日期時間的正則表達式
    const dateFormats = {
        year: 'y{1,4}',
        month: 'M{1,2}',
        day: 'd{1,2}',
        hour: 'h{1,2}',
        minute: 'm{1,2}',
        second: 's{1,2}',
        milliSecond: 'S{1,3}'
    };
    //如果沒有格式化某項的話則設(shè)置為默認時間
    const defaultDateValues = {
        year: '2001',
        month: '01',
        day: '01',
        hour: '00',
        minute: '00',
        second: '00',
        milliSecond: '000'
    };
    //保存對傳入的日期字符串進行格式化的全部信息數(shù)組列表
    const dateUnits = [];
    for (const fmtName in dateFormats) {
        const regExp = new RegExp(dateFormats[fmtName]);
        if (regExp.test(fmt)) {
            const matchStr = regExp.exec(fmt)[0];
            const regexStr = String.fill('`', matchStr.length);
            const index = fmt.indexOf(matchStr);
            fmt = fmt.replaceAll(matchStr, regexStr);
            dateUnits.push(new DateFormat(fmtName, String.fill('\\d', matchStr.length), null, index));
        } else {
            dateUnits.push(new DateFormat(fmtName, null, defaultDateValues[fmtName], -1));
        }
    }
    //進行驗證是否真的是符合傳入格式的字符串
    fmt = fmt.replaceAll('`', '\d');
    if (!new RegExp(fmt).test(dateStr)) {
        return null;
    }
    //進行一次排序, 依次對字符串進行截取
    dateUnits.sort(function (a, b) {
        return a.index - b.index;
    });
    for (var i = 0, length = dateUnits.length; i < length; i++) {
        const format = dateUnits[i].format;
        if (format == null) {
            continue;
        }
        const matchDateUnit = new RegExp(format).exec(dateStr);
        if (matchDateUnit !== null && matchDateUnit.length > 0) {
            dateStr = dateStr.replace(matchDateUnit[0], '');
            dateUnits[i].value = matchDateUnit[0];
        }
    }
    //將截取完成的信息封裝成對象并格式化標(biāo)準的日期字符串
    const obj = dateUnits.toObject(function (item) {
        return {
            key: item.name,
            value: item.value
        };
    });
    const date = '{year}-{month}-{day} {hour}:{minute}:{second}:{milliSecond}'.format(obj);
    try {
        return new Date(date);
    } catch (e) {
        return null;
    }
};

//下面是上面的 Date.of() 使用的一些輔助方法

/**
 * 替換所有匹配exp的字符串為指定字符串
 * @param exp 被替換部分的正則
 * @param newStr 替換成的字符串
 */
String.prototype.replaceAll = function (exp, newStr) {
    return this.replace(new RegExp(exp, "gm"), newStr);
};

/**
 * 原型:字符串格式化
 * @param args 格式化參數(shù)值
 */
String.prototype.format = function (args) {
    var result = this;
    if (arguments.length < 1) {
        return result;
    }

    var data = arguments; // 如果模板參數(shù)是數(shù)組
    if (arguments.length === 1 && typeof (args) === "object") {
        // 如果模板參數(shù)是對象
        data = args;
    }
    for (var key in data) {
        var value = data[key];
        if (undefined !== value) {
            result = result.replaceAll("\\{" + key + "\\}", value);
        }
    }
    return result;
};

/**
 * 為 js 的 String 添加填充字符串的靜態(tài)方法
 * @param item 填充的元素
 * @param length 填充的長度
 * @returns {string} 填充得到的字符串
 */
String.fill = function (item, length) {
    var result = '';
    for (var i = 0; i < length; i++) {
        result += item;
    }
    return result;
};

/**
 * js 數(shù)組轉(zhuǎn)換為一個 Object 對象
 * @param fn 轉(zhuǎn)換方法
 * @returns {{}} 得到的 Object 對象
 */
Array.prototype.toObject = function (fn) {
    const obj = {};
    this.map(fn)
        .forEach(function (item) {
            obj[item.key] = item.value;
        });
    return obj;
};

嗯,順便也發(fā)了一篇 blog 呢
https://rxliuli.blogspot.com/...

2018年8月9日 08:05
編輯回答
巫婆

推薦一下moment

比較全面的一個日期時間處理工具庫。

2017年7月14日 20:54
編輯回答
絯孑氣

自己封裝一個方法唄

2017年1月8日 14:31