Js 以字符串形式返回开始日期和结束日期

发布于 2025-01-11 01:00:07 字数 600 浏览 0 评论 0原文

我有这样的字符串:

(Feb 28-Mar 1)
(Mar 2-3)

我希望我返回一个对象,如下所示,有人给出一些建议我该怎么做?

    function rD(text){
    let date = text.replace('(', '').replace(')', '').split(' ');
    //const [start, end] = date[2].split("-").map(Number);
    return date;
    }
    
    
    console.log(rD("(Feb 28-Mar 1)"))
    console.log(rD("(Mar 2-3)"))

返回:

[
{
  month: 2,
  day: 28
},
{
  month: 3,
  day: 1
}
]

[
{
  month: 3,
  day: 2
},
{
  month: 3,
  day: 3
}
]

I have strings like this:

(Feb 28-Mar 1)
(Mar 2-3)

I would like me to return an object as you can see below, someone to give some suggestion how can I do?

    function rD(text){
    let date = text.replace('(', '').replace(')', '').split(' ');
    //const [start, end] = date[2].split("-").map(Number);
    return date;
    }
    
    
    console.log(rD("(Feb 28-Mar 1)"))
    console.log(rD("(Mar 2-3)"))

Return:

[
{
  month: 2,
  day: 28
},
{
  month: 3,
  day: 1
}
]

[
{
  month: 3,
  day: 2
},
{
  month: 3,
  day: 3
}
]

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

疯了 2025-01-18 01:00:07

我建议使用正则表达式模式来解析每个范围。

由此我们可以得到startMonth、startDay、endMonth、endDay。然后,我们可以创建一个 getMonthNumber() 函数,将月份名称缩写(Jan、Feb 等)转换为数字。

function getMonthNumber(month) {
    const lookup = { jan: 01, feb: 02, mar: 03, apr: 04, may: 05, jun: 06, jul: 07, aug: 08, sep: 09, oct: 10, nov: 11, dec: 12};
    return lookup[(month + '').toLowerCase()]
}

function parseSpan(str) {
    const pattern = /\(([a-z]{3})\s+(\d{1,2})\-([a-z]{3})?\s?(\d{1,2})\)/i
    const [, startMonth, startDay, endMonth, endDay] = str.match(pattern);
    return [
        { month: getMonthNumber(startMonth), day: +startDay },
        { month: getMonthNumber(endMonth || startMonth), day: +endDay }
    ];
}

let testInputs = [
  '(Feb 28-Mar 1)',
  '(Mar 2-3)',
  '(Sep 28-Oct 31)',
  '(Jan 3-17)'
]

testInputs.map(parseSpan).forEach(span => console.log(span))
.as-console-wrapper { max-height: 100% !important; }

I'd suggest using a regex pattern to parse each span.

From this we can get the startMonth, startDay, endMonth, endDay. We can then create a getMonthNumber() function to turn the abbreviated month name (Jan, Feb, etc.) to a number.

function getMonthNumber(month) {
    const lookup = { jan: 01, feb: 02, mar: 03, apr: 04, may: 05, jun: 06, jul: 07, aug: 08, sep: 09, oct: 10, nov: 11, dec: 12};
    return lookup[(month + '').toLowerCase()]
}

function parseSpan(str) {
    const pattern = /\(([a-z]{3})\s+(\d{1,2})\-([a-z]{3})?\s?(\d{1,2})\)/i
    const [, startMonth, startDay, endMonth, endDay] = str.match(pattern);
    return [
        { month: getMonthNumber(startMonth), day: +startDay },
        { month: getMonthNumber(endMonth || startMonth), day: +endDay }
    ];
}

let testInputs = [
  '(Feb 28-Mar 1)',
  '(Mar 2-3)',
  '(Sep 28-Oct 31)',
  '(Jan 3-17)'
]

testInputs.map(parseSpan).forEach(span => console.log(span))
.as-console-wrapper { max-height: 100% !important; }

紫罗兰の梦幻 2025-01-18 01:00:07

我会先删除括号,然后用 /[ -]/ 分隔。这样您就可以得到这两种形式之一的数组

["Feb", "28", "Mar", "1"]

,或者

["Mar", "2", "3"]

现在,如果数组有 4 个元素,则第一个和第三个元素始终是月份,第二个和第四个元素始终是日期。如果数组有 3 个元素,第一个元素是月份(开始和结束),第二个和第三个元素是日期。

要获取月份的数字,您可以进行简单的查找,例如

{ Jan:1, Feb:2, ... }

let months = { Jan: 1, Feb: 2, Mar: 3 /*  you get the idea*/}
let spans = ["(Jan 28 - Feb 3)", "(Mar 1-3)"]

let parse = (span) => {
  let parts = span.replace(/[()]/g, "").split(/[ -]/).filter(x => !!x);
  switch (parts.length) {
    case 4: return [{month: months[parts[0]], date: +parts[1]}, {month: months[parts[2]], date: +parts[3]}];
    case 3: return [{month: months[parts[0]], date: +parts[1]}, {month: months[parts[0]], date: +parts[2]}];
    default: return undefined;
  }
}


console.log(parse(spans[0]));
console.log(parse(spans[1]))

I'd remove the parentheses first and then split by /[ -]/. This way you get an array in one of these two forms

["Feb", "28", "Mar", "1"]

or

["Mar", "2", "3"]

Now if the array has 4 elements the first and third are always the month and second and forth are the day. If the array has 3 elements, the first is a month for both, start and end, the second and third are the days.

For getting the number of the month you can have a simple lookup like

{ Jan:1, Feb:2, ... }

let months = { Jan: 1, Feb: 2, Mar: 3 /*  you get the idea*/}
let spans = ["(Jan 28 - Feb 3)", "(Mar 1-3)"]

let parse = (span) => {
  let parts = span.replace(/[()]/g, "").split(/[ -]/).filter(x => !!x);
  switch (parts.length) {
    case 4: return [{month: months[parts[0]], date: +parts[1]}, {month: months[parts[2]], date: +parts[3]}];
    case 3: return [{month: months[parts[0]], date: +parts[1]}, {month: months[parts[0]], date: +parts[2]}];
    default: return undefined;
  }
}


console.log(parse(spans[0]));
console.log(parse(spans[1]))

ぶ宁プ宁ぶ 2025-01-18 01:00:07

你可以试试这个

function rangeCalcFunc(range = null) {
  if(range && range.length){
    const [start, end] = range.substring(1, range.length-1).split("-");
    console.log(start);console.log(end);
    const [startMon, startDt] = start.split(" ");
    const [endMon, endDt] = end.split(" ");
    
    return [
    {
      month: calcMonthInNumber(startMon.trim()),
      date: startDt
    },
    {
      month: calcMonthInNumber(endMon.trim()),
      date: endDt
    }
    ]
  }
}

function calcMonthInNumber(month) {
    switch(month.toLowerCase()){
      case 'jan': return '01'
      case 'feb': return '02'
      //add for other months
      default: break;
    }
}

console.log(rangeCalcFunc("(Jan 28-Feb 1)"));

You can try this

function rangeCalcFunc(range = null) {
  if(range && range.length){
    const [start, end] = range.substring(1, range.length-1).split("-");
    console.log(start);console.log(end);
    const [startMon, startDt] = start.split(" ");
    const [endMon, endDt] = end.split(" ");
    
    return [
    {
      month: calcMonthInNumber(startMon.trim()),
      date: startDt
    },
    {
      month: calcMonthInNumber(endMon.trim()),
      date: endDt
    }
    ]
  }
}

function calcMonthInNumber(month) {
    switch(month.toLowerCase()){
      case 'jan': return '01'
      case 'feb': return '02'
      //add for other months
      default: break;
    }
}

console.log(rangeCalcFunc("(Jan 28-Feb 1)"));

一身骄傲 2025-01-18 01:00:07

首先,我们将为几个月创建一个映射器。像这样:

let MonthsMapper = new Map([['Jan', 1], ['Feb', 2], ['Mar', 3] /*...*/])

然后我们需要一个函数,通过删除括号并用连字符将其分割来将字符串切割成块。
第一个块是开始日期和结束日期。
有了这两个日期,我们可以进一步得到开始月份、开始日期、结束月份和结束日期。 (通过用空格分割我们的块)

从您的示例中我只能看到一种特殊情况,即结束日期未指定月份的情况,在这种情况下,它隐式是开始月份。

let DateObjectParser = (dateString) => {
    const [startDate, endDate] = dateString.replace(/[()]/g, '').split('-')
    const [startMonth, startDay] = startDate.split(' ')
    let [endMonth, endDay] = endDate.split(' ')

    // in case a second month is not provided
    if (endDay === undefined) {
        endDay = endMonth
        endMonth = startMonth
    }

    return [
       {
           month: MonthsMapper.get(startMonth),
           day: parseInt(startDay),
       },
       {
            month: MonthsMapper.get(endMonth),
            day: parseInt(endDay),
       }
  ]
}

First we are going to create a mapper for the months. like this:

let MonthsMapper = new Map([['Jan', 1], ['Feb', 2], ['Mar', 3] /*...*/])

Then we need a function which cutes the string into chunks by removing the parenthesis and splitting it by its hyphen.
The first chunks are the start and end dates.
With these two dates we can further get the start month, start day, end month, and end day. (By splitting our chunks by there whitespaces)

There is only one special case I can see from your example and that is the case when the end date does not specify a month, in which case it is implicitly the start month.

let DateObjectParser = (dateString) => {
    const [startDate, endDate] = dateString.replace(/[()]/g, '').split('-')
    const [startMonth, startDay] = startDate.split(' ')
    let [endMonth, endDay] = endDate.split(' ')

    // in case a second month is not provided
    if (endDay === undefined) {
        endDay = endMonth
        endMonth = startMonth
    }

    return [
       {
           month: MonthsMapper.get(startMonth),
           day: parseInt(startDay),
       },
       {
            month: MonthsMapper.get(endMonth),
            day: parseInt(endDay),
       }
  ]
}
初吻给了烟 2025-01-18 01:00:07

除了代码之外,这种方法的优点是,如果输入类似于 Jan 1-3-Mar 7 ,它就可以工作,而所有其他答案都没有考虑到这一点,因此返回 <代码>未定义或错误。

简单的正则表达式和月份到数字的列表应该可以工作,这对我来说似乎是最简单的。使用 String.prototype.match 我们可以“忽略”所有额外的数据(即月份之间的括号和破折号),只需提取必要的数据:

function rD(str) {
  // have a list of the numbers of each month
  const monthNum = {
    jan: 1,
    feb: 2,
    mar: 3,
    apr: 4,
    may: 5,
    jun: 6,
    jul: 7,
    aug: 8,
    sep: 9,
    oct: 10,
    nov: 11,
    dec: 12
  };

  // regex to extract the patterns "Feb 23" or "Aug 15-23"
  let spl = str.match(/[a-z]{3} \d{1,2}(\-\d{1,2})?/gi);

  // loop through matches
  const result = spl.map(s => {
    // first 3 letters is the month; get the month number
    const month = monthNum[s.substr(0, 3).toLowerCase()],
      rest = s.substr(4); // get the rest of the string sans the month and extra space
    const e = rest.split("-");
    return e.map(q => ({
      month,
      day: +q
    }));
  }).flat(); // our array may occasionally be multidimensional if the user provides something like "Nov 7-12". We flatten the array to fix that
  return result;
}

console.log("(Feb 28-Mar 1):", rD("(Feb 28-Mar 1)"));
console.log("(Mar 2-3):", rD("(Mar 2-3)"));
console.log("(Nov 7-12-Dec 15):", rD("(Nov 7-12-Dec 15)"));
.as-console-wrapper { min-height: 100% !important; }

Besides the code, the advantage to this approach is that it works if the input is something like Jan 1-3-Mar 7, while all the other answers don't put this into consideration, thus returning undefined or an error.

Simple regex and a list of month to numbers should work, and it seems the most straightforward to me. Using String.prototype.match we can "ignore" all the extra data (i.e. the parentheses and dashes between months), just extract the necessary data:

function rD(str) {
  // have a list of the numbers of each month
  const monthNum = {
    jan: 1,
    feb: 2,
    mar: 3,
    apr: 4,
    may: 5,
    jun: 6,
    jul: 7,
    aug: 8,
    sep: 9,
    oct: 10,
    nov: 11,
    dec: 12
  };

  // regex to extract the patterns "Feb 23" or "Aug 15-23"
  let spl = str.match(/[a-z]{3} \d{1,2}(\-\d{1,2})?/gi);

  // loop through matches
  const result = spl.map(s => {
    // first 3 letters is the month; get the month number
    const month = monthNum[s.substr(0, 3).toLowerCase()],
      rest = s.substr(4); // get the rest of the string sans the month and extra space
    const e = rest.split("-");
    return e.map(q => ({
      month,
      day: +q
    }));
  }).flat(); // our array may occasionally be multidimensional if the user provides something like "Nov 7-12". We flatten the array to fix that
  return result;
}

console.log("(Feb 28-Mar 1):", rD("(Feb 28-Mar 1)"));
console.log("(Mar 2-3):", rD("(Mar 2-3)"));
console.log("(Nov 7-12-Dec 15):", rD("(Nov 7-12-Dec 15)"));
.as-console-wrapper { min-height: 100% !important; }

燃情 2025-01-18 01:00:07

在下面的代码片段中添加了内联的所有步骤。

// const str = "(Feb 28-Mar 1)";
const str = "(Mar 2-3)";

// An Object which contains numeric value of months.
const monthMap = {
  Jan: 1,
  Feb: 2,
  Mar: 3
};

/**
 * convertStringToObject() method used to convert the input string into an object.
 * @param : inputString
 */
function convertStringToObject(inputString) {
  // Removing open and closed paranthesis and splitting the inputString with '-'
    const split = inputString.replace('(', '').replace(')', '').split('-');
  // If splitted array element does not contain month, appending that. 
  split[1] = (split[1].trim().length === 1) ? split[0].split(' ')[0] + ' ' + split[1] : split[1];
  // Looping over the splitted array and then creating the object with keys 'month' and 'day'
  return split.map((item) => {
    const splittedItem = item.split(' ');
    return {
        month: monthMap[splittedItem[0]],
      day: Number(splittedItem[1])
    }
  });
}

// Calling the convertStringToObject() method by passing the input string as a param.
console.log(convertStringToObject(str));

Added all the steps inline in below code snippet.

// const str = "(Feb 28-Mar 1)";
const str = "(Mar 2-3)";

// An Object which contains numeric value of months.
const monthMap = {
  Jan: 1,
  Feb: 2,
  Mar: 3
};

/**
 * convertStringToObject() method used to convert the input string into an object.
 * @param : inputString
 */
function convertStringToObject(inputString) {
  // Removing open and closed paranthesis and splitting the inputString with '-'
    const split = inputString.replace('(', '').replace(')', '').split('-');
  // If splitted array element does not contain month, appending that. 
  split[1] = (split[1].trim().length === 1) ? split[0].split(' ')[0] + ' ' + split[1] : split[1];
  // Looping over the splitted array and then creating the object with keys 'month' and 'day'
  return split.map((item) => {
    const splittedItem = item.split(' ');
    return {
        month: monthMap[splittedItem[0]],
      day: Number(splittedItem[1])
    }
  });
}

// Calling the convertStringToObject() method by passing the input string as a param.
console.log(convertStringToObject(str));

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文