【问题标题】:JS time - make an array for each year between two datesJS 时间 - 在两个日期之间为每年创建一个数组
【发布时间】:2014-06-26 14:41:49
【问题描述】:

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

我需要在数组中记录每年提取的总提款,但不知道如何开始为每个保单年度创建数组。

任何帮助将不胜感激。

【问题讨论】:

  • StartEnd 是什么?日期对象?字符串?
  • 我们可以看看你尝试过的代码吗?
  • 你需要对你创建的数组做什么?用记录填充它们,并将它们存储在哪里?

标签: javascript arrays time


【解决方案1】:

对于简单的场景(使用库会过大),我会使用这个:

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)

【讨论】:

  • 这可行,但它只获取 Date 对象的年份组件,而不考虑完整的年份是否在两个日期之间。 OP 要求在 StartEnd 日期之间提供完整的年份。这就是为什么使用库或函数来计算两个日期之间的差异可能是首选的原因。
  • “一整年”的定义对我来说似乎相当模糊......为了解释我的意思,我将使用“2014 年 6 月 26 日”作为开始日期和今天(5 月 12 日) 2020)作为结束日期。 --- 我应该包括 2014 年并排除 2020 年(因为从 2014 年 6 月 26 日到 2015 年 6 月 26 日有全年,但从 2019 年 6 月 26 日到 2020 年 6 月 26 日没有)?或者我应该排除 2014 年和 2020 年(因为它们本身都没有 12 个月)?
  • @CameronTinker 我已更新我的答案以反映您评论中的见解。 ?
  • 是的,“全年”的概念很模糊,但这看起来很好地解决了全年的日期范围。我唯一的建议是使用 UTC 日期,因为它们不受时区时间变化的影响。这是一个不错的干净更新!
  • @bertdida 因为Array(n) 创建了一个包含n 项的数组,而[n] 创建了一个包含一个 项且值为n 的数组。你可以通过运行n=8; console.log(Array(n), [n]) 看到这一点。欲了解更多详情,请访问developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/… 并查看arrayLength
【解决方案2】:

如果您进行大量日期操作,我建议您使用 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 年的原因。

编辑: 如何在没有 moment.js 的情况下进行 diff 示例:

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

注意:计算与闰年的差异时会变得复杂,因为它们仅在闰年的年份更改每年的毫秒数。

【讨论】:

    【解决方案3】:

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

    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() )
    

    这是fiddle

    【讨论】:

      【解决方案4】:

      所以我尝试了第一个解决方案,我得到了一个负数,所以 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;
      }
      

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-05-18
        • 1970-01-01
        • 2021-03-14
        • 1970-01-01
        • 2021-07-08
        • 1970-01-01
        相关资源
        最近更新 更多