根据月份名称获取 ISO 日期字符串

Get ISO date string based on month name

我必须根据长月份名称在数组中创建两个 ISO 日期字符串。

Input: 'August'
Output: ['2020-08-01T00:00:00', '2020-08-31T00:00:00']

我正在考虑每月检查一个 switch 案例,但我不确定如何使用此信息创建 ISO 字符串。我可以将 August08 匹配并替换预定义的 ISO 字符串并根据输入替换它,但这听起来不是很聪明。

您可以从 toLocaleString 中获取您所在区域的月份名称,或者对数组进行硬编码。

然后计算本月的第一天和下个月的第0天

我不得不将时间标准化为 15:00 以处理时区。

const yyyy = new Date().getFullYear();
const months = Array.from(Array(12).keys())
   .map(month => new Date(yyyy, month, 5, 15, 0, 0, 0) 
     .toLocaleString('default', { month: 'long'}) );
const zeroTime = str => `${str.split("T")[0]}T00:00:00`;     
const getDates = month => {
  const monthNum = months.indexOf(month);
  const start = new Date(yyyy, monthNum, 1, 15, 0, 0, 0),
          end = new Date(yyyy, monthNum+1, 0, 15, 0, 0, 0)
  return [zeroTime(start.toISOString()), zeroTime(end.toISOString())];
};
console.log(getDates("August"))

有很多方法可以解决这个问题,唯一真正的问题是如何生成月份名称列表。以下使用 mplungian 的方法以浏览器默认语言生成它们,但我不确定这是个好主意。

问题的另一部分是为月初和月底生成时间戳。给定年份和月份数字,这非常简单。您可以使用 UTC 值和 toISOString,然后 trim 尾随 Z 来获取本地时间戳。

以下应该是有效的,因为它只生成一个日期和数组来获取月份名称,然后在每次调用 getMonthDates 时再生成一个。它还使用 for 循环而不是创建数组并使用数组方法进行迭代。

它还提供了从名称中获取月份编号以及从月份编号和年份中获取日期的单独函数。他们使用 ECMAScript 月份编号(0 = Jan 等),但可以轻松转换为使用日历月份编号(1 = Jan 等)。

// Given year and ECMAScript month number, return an array of ISO 8601
// formatted local timestamps for first and last days of the month
let getMonthDates = (monthNum = 0, year = new Date().getFullYear()) => {
  let date = new Date(Date.UTC(year, monthNum));
  let start = date.toISOString().substring(0, 19);
  date.setUTCMonth(monthNum + 1, 0);
  return [start, date.toISOString().substring(0, 19)];  
}
// Given a month name, return it's ECMAScript month number
// Uses host default language for month name
let getMonthDatesFromName = (() => {
  let date = new Date();
  let monthNames = (() => {
    date.setMonth(0, 1);
    for (var arr=[], i=0; i<12; i++) {
      arr.push(date.toLocaleString('default',{month:'long'}));
      date.setMonth(i+1)
    }
    return arr;
  })();

  return (monthName, year) => {
    let monthNum = monthNames.indexOf(monthName);
    // If month name not found, return undefined
    return monthNum < 0? void 0 : getMonthDates(monthNum, year);
  }
})();

/** getMonthDatesFromName examples 
 */
// Undefined if month name not valid
console.log('foo: ' + getMonthDatesFromName('foo'));
// Current month name
let monthName = new Date().toLocaleString('default',{month: 'long'});
console.log(monthName + ': ' + getMonthDatesFromName(monthName).toString());
// February, 2024
console.log('February, 2024: ' + getMonthDatesFromName('February', 2024).toString());

/** getMonthDates examples
 */
// January of current year by default
console.log('Default: ' + getMonthDates().toString());
// Month of current year by default, e.g. for April
console.log('April: ' + getMonthDates(3).toString());
// Month and year - February 2024
console.log('1, 2024: ' + getMonthDates(1, 2024).toString());