You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

JavaScript多格式日期字符串转Date对象及时间戳问题

解决多种日期字符串格式转Date对象的问题

这个坑我踩过好多次!JavaScript原生的Date构造函数对非ISO标准的日期字符串真的很不友好,就像你遇到的情况:15/01/2012这种日在前的格式,它会误以为是月日,15超过了月份的范围,直接返回Invalid Date;连-分隔的15-01-2012也识别不了。下面给你几个实用的解决方案:

方案一:自定义解析函数(原生实现,无需依赖)

针对你提到的三种格式,我们可以写一个函数手动拆分日期部分,根据分隔符和数字范围判断格式:

function parseCustomDate(dateStr) {
    let dateParts, timeParts;

    // 拆分日期和时间部分
    const [datePart, timePart] = dateStr.split(' ');
    timeParts = timePart ? timePart.split(':') : [0, 0, 0];
    const [hours, minutes, seconds] = timeParts.map(Number);

    if (datePart.includes('/')) {
        dateParts = datePart.split('/').map(Number);
        const [first, second, year] = dateParts;
        // 判断是dd/MM还是MM/dd:第一个数字>12则为dd/MM
        if (first > 12) {
            // dd/MM/yyyy 格式
            return new Date(year, second - 1, first, hours, minutes, seconds);
        } else {
            // MM/dd/yyyy 格式
            return new Date(year, first - 1, second, hours, minutes, seconds);
        }
    } else if (datePart.includes('-')) {
        dateParts = datePart.split('-').map(Number);
        const [first, second, year] = dateParts;
        // 判断是dd-MM还是MM-dd:第一个数字>12则为dd-MM
        if (first > 12) {
            // dd-MM-yyyy 格式
            return new Date(year, second - 1, first, hours, minutes, seconds);
        } else {
            // MM-dd-yyyy 格式
            return new Date(year, first - 1, second, hours, minutes, seconds);
        }
    }

    // fallback到原生解析(处理ISO格式等)
    return new Date(dateStr);
}

// 测试示例
console.log(parseCustomDate("05/01/2012 21:10:17")); // Tue May 01 2012 21:10:17...
console.log(parseCustomDate("15/01/2012 21:10:17")); // Sat Jan 15 2012 21:10:17...
console.log(parseCustomDate("15-01-2012 21:10:17")); // Sat Jan 15 2012 21:10:17...
console.log(parseCustomDate("01-15-2012 21:10:17")); // Sun Jan 15 2012 21:10:17...

逻辑说明:

  • 先拆分日期和时间部分,分别处理时分秒
  • 根据日期部分的分隔符(/或-)拆分日、月、年
  • 通过判断第一个数字是否大于12,区分是“日在前”还是“月在前”的格式
  • 用new Date(year, monthIndex, day, ...)构造日期(注意月份是0-based,必须减1)

方案二:正则匹配精准解析(更可靠,适合明确格式场景)

如果你的业务中只有固定的几种日期格式,用正则表达式精准匹配是最不容易出错的方式:

function parseDateWithRegex(dateStr) {
    // 定义三种格式的正则
    const patterns = [
        { regex: /^(\d{2})\/(\d{2})\/(\d{4}) (\d{2}):(\d{2}):(\d{2})$/, format: 'dd/MM/yyyy' },
        { regex: /^(\d{2})-(\d{2})-(\d{4}) (\d{2}):(\d{2}):(\d{2})$/, format: 'dd-MM-yyyy' },
        { regex: /^(\d{2})-(\d{2})-(\d{4}) (\d{2}):(\d{2}):(\d{2})$/, format: 'MM-dd-yyyy' }
    ];

    for (const { regex, format } of patterns) {
        const match = dateStr.match(regex);
        if (match) {
            let day, month, year;
            const [, p1, p2, p3, hours, minutes, seconds] = match.map(Number);
            if (format === 'dd/MM/yyyy' || format === 'dd-MM-yyyy') {
                day = p1;
                month = p2;
                year = p3;
            } else if (format === 'MM-dd-yyyy') {
                day = p2;
                month = p1;
                year = p3;
            }
            return new Date(year, month - 1, day, hours, minutes, seconds);
        }
    }

    return new Date(dateStr);
}

// 测试示例
console.log(parseDateWithRegex("15/01/2012 21:10:17")); // Sat Jan 15 2012...
console.log(parseDateWithRegex("15-01-2012 21:10:17")); // Sat Jan 15 2012...
console.log(parseDateWithRegex("01-15-2012 21:10:17")); // Sun Jan 15 2012...

逻辑说明:

  • 为每种格式编写精准的正则表达式,确保只匹配对应格式的字符串
  • 匹配成功后,根据格式提取对应的日、月、年部分
  • 构造Date对象,同样注意月份的0-based转换

方案三:使用第三方日期库(适合复杂场景)

如果你的项目允许引入第三方库,date-fns(轻量、现代)或者luxon(替代moment.js)都能轻松处理多种日期格式,无需自己写复杂逻辑:

以date-fns为例:

import { parse } from 'date-fns';

// 解析不同格式的日期字符串
const date1 = parse("15/01/2012 21:10:17", "dd/MM/yyyy HH:mm:ss", new Date());
const date2 = parse("15-01-2012 21:10:17", "dd-MM-yyyy HH:mm:ss", new Date());
const date3 = parse("01-15-2012 21:10:17", "MM-dd-yyyy HH:mm:ss", new Date());

// 转时间戳
const timestamp1 = date1.getTime();
// UI展示示例(根据需求格式化)
const displayStr = date1.toLocaleString('en-IN', {
    year: 'numeric',
    month: 'long',
    day: 'numeric',
    hour: '2-digit',
    minute: '2-digit'
});

优势:

  • 库已经封装了各种边缘情况的处理,比如闰年、不同时区等
  • 支持更多格式和本地化需求,减少自己造轮子的bug

后续处理

不管用哪种方法得到Date对象后:

  • 转时间戳:直接调用date.getTime()或者用+date获取毫秒级时间戳
  • UI展示:可以用date.toLocaleString()或者Intl.DateTimeFormat自定义展示格式,适配不同地区的用户习惯

内容的提问来源于stack exchange,提问作者Nagarjuna Reddy

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:25:53