【问题标题】:Google Apps Script add month to a date until specific date is reachedGoogle Apps 脚本将月份添加到日期,直到到达特定日期
【发布时间】:2022-01-26 01:20:01
【问题描述】:

我有以下使用 Google Apps 脚本的代码,但是当我将其注销时,我得到以下结果。我希望 GAS 在下个月记录并在到达“lastDateofYear”时停止。无论出于何种原因,这一年在我的结果中都没有改变,它只是不断重复今年。请帮忙。

var thisDate = "Mon Dec 20 00:00:00 GMT-06:00 2021";
var nextYear = Number(currentYear)+1;
var lastDateofYear = new Date("12-31-"+nextYear);

  for(var i=thisDate; i <= lastDateofYear; ){  
    var currentiDate = new Date(i);     
    var month = currentiDate.getMonth()+1;
    i.setMonth((month) % 12);
    i.setDate(currentiDate.getDate());
    Logger.log(currentiDate);
  }

结果:

2021 年 12 月 20 日星期一 00:00:00 GMT-06:00
2021 年 1 月 20 日星期三 00:00:00 GMT-06:00
2 月 20 日星期六 00:00:00 GMT-06:00 2021
2021 年 3 月 20 日星期六 00:00:00 GMT-05:00
2021 年 4 月 20 日星期二 00:00:00 GMT-05:00
2021 年 5 月 20 日星期四 00:00:00 GMT-05:00
2021 年 6 月 20 日星期日 00:00:00 GMT-05:00
2021 年 7 月 20 日星期二 00:00:00 GMT-05:00
2021 年 8 月 20 日星期五 00:00:00 GMT-05:00
2021 年 9 月 20 日星期一 00:00:00 GMT-05:00
2021 年 10 月 20 日星期三 00:00:00 GMT-05:00
2021 年 11 月 20 日星期六 00:00:00 GMT-06:00
2021 年 12 月 20 日星期一 00:00:00 GMT-06:00
2021 年 1 月 20 日星期三 00:00:00 GMT-06:00
2 月 20 日星期六 00:00:00 GMT-06:00 2021
2021 年 3 月 20 日星期六 00:00:00 GMT-05:00
2021 年 4 月 20 日星期二 00:00:00 GMT-05:00

【问题讨论】:

    标签: javascript date for-loop google-apps-script


    【解决方案1】:

    关于你的代码有很多话要说:

    var thisDate = "Mon Dec 20 00:00:00 GMT-06:00 2021";
    

    ECMA-262 不支持该时间戳格式,所以不要使用内置解析器来解析它,参见Why does Date.parse give incorrect results?

    var nextYear = Number(currentYear)+1;
    

    currentYear 来自哪里?

    var lastDateofYear = new Date("12-31-"+nextYear);
    

    解析不支持的格式,见上文。在 Safari 中,它返回一个无效的日期。

      for(var i=thisDate; i <= lastDateofYear; ){  
    

    i 设置为分配给 thisDate 的字符串值。由于 lastDateOfYear 在 Safari 和 Firefox 中是无效日期,因此测试 i &lt;= NaN 永远不会为真,并且永远不会进入循环。

        var currentiDate = new Date(i);
    

    解析i,见上文。

        var month = currentiDate.getMonth()+1;
        i.setMonth((month) % 12);
    

    i 是一个字符串,它没有 setMonth 方法,所以我预计会出现类型错误,例如“i.setMonth is not a function " 如果循环实际运行。

        i.setDate(currentiDate.getDate());
    

    上面的另一个类型错误(但不会到这一步)。

        Logger.log(currentiDate);
      }
    

    您似乎希望将一个日期按顺序添加 1 个月,直到它到达下一年的同一日期。简单地说,您可以添加 1 个月,直到您到达明年的同一日期,例如:

    let today = new Date();
    let nextYear = new Date(today.getFullYear() + 1, today.getMonth(), today.getDate());
    let result = [];
    do {
      result.push(today.toString());
      today.setMonth(today.getMonth() + 1);
    } while (today <= nextYear)
    

    但是,添加月份并不是那么简单。如果您将 1 个月添加到 1 月 1 日,您将获得 3 月 2 日或 3 日,具体取决于它是否是闰年。将 1 个月添加到 8 月 31 日将返回 10 月 1 日。

    许多“添加月份”函数会检查日期是否超过一个月,如果是,则通过将日期设置为 0 将日期设置回上个月的月底,因此 1 月 31 日 + 1 个月2 月 28 日或 29 日。

    但是,如果您使用该算法循环超过一年,您会得到 1 月 31 日、2 月 28 日、3 月 28 日、4 月 28 日等,而不是 1 月 31 日、2 月 28 日、3 月 31 日、4 月 30 日等。

    JavaScript function to add X months to a dateHow to add months to a date in JavaScript?

    一个更健壮的方法是有一个函数将 n 个月添加到日期并增加要添加的月份而不是日期本身,这样就可以分别处理每个月的月底问题加法,例如

    /* Add n months to a date. If date rolls over an extra month,
     * set to last day of previous month, e.g.
     * 31 Jan + 1 month => 2 Mar, roll back => 28 Feb
     *
     * @param {number} n - months to add
     * @param {Date} date - date to add months to, default today
     * @returns {Date} new Date object, doesn't modify passed Date
     */
    function addMonths(n, date = new Date()) {
      let d = new Date(+date);
      let day = d.getDate();
      d.setMonth(d.getMonth() + n);
      if (d.getDate() != day) d.setDate(0);
      return d;
    }
    
    /* return array of n dates at 1 month intervals. List is
     * inclusive so n + 1 Dates returned.
     *
     * @param {Date} start - start date
     * @param {number} n - number of months to return
     * @returns {Array} array of Dates
     */
    function getMonthArray(n, start = new Date()) {
      let result = [];
      for (let i=0; i<n; i++) {
        result.push(addMonths(i, start));
      }
      return result;
    }
    
    // Examples
    // Start on 1 Dec
    getMonthArray(12, new Date(2021,11,1)).forEach(
      d => console.log(d.toDateString())
    );
    // Start on 31 Dec
    getMonthArray(12, new Date(2021,11,31)).forEach(
      d => console.log(d.toDateString())
    );

    这些函数不会尝试将时间戳解析为日期,该责任留给调用者。

    【讨论】:

    • 感谢您分享此内容。这非常详细,但也比我需要的要复杂一些。我能够使用上面的 Burhan Savci 代码来解决我的问题。我非常感谢您的贡献。
    【解决方案2】:

    据我了解,您希望从给定日期到日志中给定日期的下一年的最后一个月打印每个月。

    您可以在以下代码中执行此操作:

    let start = new Date("Mon Dec 20 00:00:00 GMT-06:00 2021");
    let currentYear = new Date().getFullYear();
    let nextYear = currentYear + 1;
    let end = new Date(nextYear, 11, 31);
    while (start <= end) {
      // You can use Logger.log() here if you want. I use console.log() for demo purpose
      console.log(new Date(start).toDateString());
      start.setMonth(start.getMonth() + 1);
    }

    如果我有任何错误,请随时在 cmets 中向我指出。

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    • 2022-10-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多