JS time -为两个日期之间的每一年创建一个数组

JS time - make an array for each year between two dates

本文关键字:数组 一个 年创建 之间 两个 time JS 日期      更新时间:2023-09-26

我有两个变量:开始,结束基本上,我需要为这两个日期之间的每个完整年份创建一个数组。

我需要在数组中记录每年的总提款,但不确定如何开始为每个政策年创建数组。

对于简单的场景(使用库是多余的),我将使用如下:

const rangeOfYears = (start, end) => Array(end - start + 1)
  .fill(start)
  .map((year, index) => year + index)

如果输入的不是整数而是Date对象,则使用.getFullYear()


例如,如果我们想要20142020(包括)之间的年份,这将是:
// Using integers for years
rangeOfYears(2014, 2020)
// Using `Date` objects for years
rangeOfYears(new Date("Jun 26 2014").getFullYear(), new Date().getFullYear())
// For both the result would be:
// [2014, 2015, 2016, 2017, 2018, 2019, 2020]

虽然题目没有说明这一点,但问题作者提到"这两个日期之间的每一个完整的年份"。没有提到"完整"一年的确切定义,但可以是:

  1. 满12个月的年份
    在这种情况下,第一项和最后一项应该始终被删除:

    .slice(1, -1)
    // Which gives: [2015, 2016, 2017, 2018, 2019]
    
  2. 自开始日期起每12个月
    在这种情况下,需要一个过滤器来查看最近一年是否在范围内:
    (这将需要Date对象来工作)

    .filter((year, index) => 
        // 31536000000 = 60 * 60 * 24 * 365 * 1000 = one year in milliseconds
        index < (end.getTime() - start.getTime()) / 31536000000)
        // Which gives: [2014, 2015, 2016, 2017, 2018, 2019]
    

代码示例

把所有这些放在一起,我们得到:

不带"完整年份"过滤器

/* Example without "complete year" filter */
const rangeOfYears = (start, end) => Array(end - start + 1)
  .fill(start)
  .map((year, index) => year + index)
let a = rangeOfYears(2014, 2020)
let b = rangeOfYears(new Date("Jun 26 2014").getFullYear(), new Date().getFullYear())
console.log(a)
console.log(b)

带有"完整的一年= 12个完整的月"过滤器

/* Example with "complete year = 12 full months" filter */
const rangeOfYears = (start, end) => Array(end - start + 1)
  .fill(start)
  .map((year, index) => year + index)
  .slice(1, -1)
let c = rangeOfYears(2014, 2020)
let d = rangeOfYears(new Date("Jun 26 2014").getFullYear(), new Date().getFullYear())
console.log(c)
console.log(d)

带有"完整的一年=每12个月"过滤器

/* Example with "complete year = each 12 months" filter */
const rangeOfFullYears = (start, end) => {
  
  // Lets not do this inside the "filter"...
  const fullYears = (end.getTime() - start.getTime()) / 31536000000
  
  return Array(end.getFullYear() - start.getFullYear() + 1)
    .fill(start.getFullYear())
    .map((year, index) => year + index)
    .filter((year, index) => index < fullYears)
}
let e = rangeOfFullYears(new Date("Jun 26 2014"), new Date())
console.log(e)

如果要进行大量的日期操作,我建议使用Moment.js。使用Moment.js的diff函数,Moment.js将对差异进行精确计算,而不仅仅是减去Date对象上的年份组件。

跨2年的例子:

var Start = new Date("June 26, 2012 11:13:00");
var End = new Date("January 1, 2015 11:13:00");
var years = moment(End).diff(Start, 'years');
var yearsBetween = [];
for(var year = 0; year < years; year++)
    yearsBetween.push(Start.getFullYear() + year);

的回报:

yearsBetween
[2012, 2013]

时间跨度为3年的例子:

var Start = new Date("June 26, 2012 11:13:00");
var End = new Date("June 26, 2015 11:13:00");
var years = moment(End).diff(Start, 'years');
var yearsBetween = [];
for(var year = 0; year < years; year++)
    yearsBetween.push(Start.getFullYear() + year);

的回报:

yearsBetween
[2012, 2013, 2014]

第一个示例只跨越2年,因为它没有3个完整的年份,即使End年份比Start年份晚3年。在以后的年份中,超过开始日期的同一个月/天的任何时间都算作一个完整的年份。这就是为什么第二个例子跨越了整整3年。

编辑:如何做一个没有瞬间的差异的例子:

const msPerYear = 1000 * 60 * 60 * 24 * 365;
function diffYear(d1, d2) {
  const utc1 = Date.UTC(d1.getFullYear(), d1.getMonth(), d1.getDate());
  const utc2 = Date.UTC(d2.getFullYear(), d2.getMonth(), d2.getDate());
  return Math.floor((utc2 - utc1) / msPerYear);
}

跨越7年:

var Start = new Date("June 26, 2012 11:13:00");
var End = new Date("January 1, 2020 11:13:00");
var diff = diffYear(Start, End);

的回报:

7

跨越8年:

var Start = new Date("June 26, 2012 11:13:00");
var End = new Date("June 26, 2020 11:13:00");
var diff = diffYear(Start, End);

的回报:

8

注意:当计算闰年的差异时,它会变得复杂,因为它们每年只改变闰年的毫秒数。

该函数接受一个开始日期对象和一个结束日期对象,并返回两个日期之间的年份数组。它不会为您处理任何错误。它只是接受开始日期和结束日期,并期望它们是有效的日期对象,结束日期晚于开始日期。

var calculateYearsBetween = function(startDate, endDate) {
    var startYear = startDate.getYear() + 1900, //The start year
        endYear = endDate.getYear() + 1900,     //The end year
        output = []                             //Initialize the output
    // For each year between push that year into the output
    for ( var year = startYear; year <= endYear; year++ ) output.push(year)
    // Return the output
    return output
}
使用

calculateYearsBetween( new Date("Jan 1 2012"), new Date() )

这是一个小提琴

所以我尝试了第一个解决方案,我得到了一个负数,所以for循环不会运行。以下是我后来想到的解决方案:

export function yearsBetween() {
    const currentYear = moment();
    const backYear = new Date("January 1, 2015");
    const years = moment(backYear).diff(currentYear, 'years');
    const iterator = Math.abs(years) + 1;
    const yearsArray = [];
    for (var year = 0; year < iterator; year++) {
        console.log(currentYear.format("YYYY"))
        yearsArray.push(parseInt(currentYear.format("YYYY")) - year);
    }
    return yearsArray;
}

我所做的是使用math .abs()将其更改为正数,然后添加1以获得混合中的实际年份。