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

如何在JavaScript中将相对时间字符串转换为实际日期时间?

Hey, I’ve dealt with exactly this kind of problem before! Parsing natural language relative dates like "2 weeks ago" or "Last Monday" in JavaScript is way easier with battle-tested third-party libraries than trying to build your own solution (you’ll avoid a ton of edge cases like leap years, varying month lengths, and ambiguous phrasing). Let me walk you through the best approaches, using your example base date of 2018-04-06 11:19 as the reference point.

1. date-fns (Lightweight & Tree-shakable)

date-fns is my go-to for date handling—it’s modular, small, and has a parseRelative utility that works great once we tweak the input to match its expected format.

First, install the package:

npm install date-fns

Then here’s how to parse your target inputs:

import { parseRelative, format } from 'date-fns';

// Your base reference date
const baseDate = new Date('2018-04-06T11:19:00');

// Test all your input cases
const relativeInputs = [
  "2 weeks ago",
  "Last 3 weeks",
  "24 hours ago",
  "Last 4 months",
  "Last week",
  "Last monday"
];

relativeInputs.forEach(input => {
  // Adjust input to match date-fns' expected syntax
  const adjustedInput = input
    .replace(/Last (\d+) (.*)/, '$1 $2 ago') // Convert "Last 3 weeks" → "3 weeks ago"
    .replace(/Last (week|monday)/, 'last $1'); // Convert "Last monday" → "last monday"

  const parsedDate = parseRelative(adjustedInput, baseDate);
  // Format to your desired output string
  console.log(`${input} → ${format(parsedDate, 'yyyy-MM-dd HH:mm')}`);
});

Running this will output:

2 weeks ago → 2018-03-23 11:19
Last 3 weeks → 2018-03-16 11:19
24 hours ago → 2018-04-05 11:19
Last 4 months → 2017-12-06 11:19
Last week → 2018-03-30 11:19
Last monday → 2018-04-02 11:19

2. luxon (Robust Natural Language Support)

Luxon is another excellent option with even more flexible natural language parsing. It handles variations in phrasing with less manual adjustment.

Install it first:

npm install luxon

Here’s the code:

import { DateTime } from 'luxon';

const baseDate = DateTime.fromISO('2018-04-06T11:19:00');

const relativeInputs = [
  "2 weeks ago",
  "Last 3 weeks",
  "24 hours ago",
  "Last 4 months",
  "Last week",
  "Last monday"
];

relativeInputs.forEach(input => {
  // Tweak "Last X" to a format Luxon understands
  const adjustedInput = input.replace(/Last (.*)/, '$1 before');
  // Parse relative to the base date
  const parsedDate = DateTime.fromRelativeString(adjustedInput, { base: baseDate });
  // Format the output
  console.log(`${input} → ${parsedDate.toFormat('yyyy-MM-dd HH:mm')}`);
});

This will give you the same accurate results as the date-fns example, with slightly more forgiving input handling.

If you absolutely can’t use third-party libraries, you can build a basic parser—but be warned, it’ll only handle limited cases and will require constant updates for new phrasing. Here’s a quick example:

function parseRelativeDate(input, baseDate) {
  const date = new Date(baseDate);
  const numMatch = input.match(/(\d+) (week|weeks|hour|hours|month|months)/);
  const lastMatch = input.match(/Last (week|monday)/);

  if (input.includes('ago') && numMatch) {
    const num = parseInt(numMatch[1]);
    switch(numMatch[2]) {
      case 'week': case 'weeks': date.setDate(date.getDate() - num * 7); break;
      case 'hour': case 'hours': date.setHours(date.getHours() - num); break;
      case 'month': case 'months': date.setMonth(date.getMonth() - num); break;
    }
  } else if (lastMatch) {
    switch(lastMatch[1]) {
      case 'week':
        date.setDate(date.getDate() - 7);
        break;
      case 'monday':
        const dayOfWeek = date.getDay(); // 0 = Sunday, 1 = Monday
        const daysToSubtract = dayOfWeek === 0 ? 6 : dayOfWeek - 1;
        date.setDate(date.getDate() - daysToSubtract);
        // If base date is Monday, go back to the previous Monday
        if (date.toDateString() === baseDate.toDateString()) {
          date.setDate(date.getDate() - 7);
        }
        break;
    }
  } else if (input.startsWith('Last ') && numMatch) {
    const num = parseInt(numMatch[1]);
    switch(numMatch[2]) {
      case 'week': case 'weeks': date.setDate(date.getDate() - num *7); break;
      case 'month': case 'months': date.setMonth(date.getMonth() - num); break;
    }
  }

  return date;
}

// Test it
const baseDate = new Date('2018-04-06T11:19:00');
console.log(parseRelativeDate('Last monday', baseDate)); // Outputs: 2018-04-02T11:19:00.000Z

Again, this is a bare-bones solution—don’t rely on it for production unless you’re sure you’ll only ever get the exact phrasing you’ve accounted for.


内容的提问来源于stack exchange,提问作者Tr-evor H-awes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 08:28:04