Google apps script 生日电子邮件、空白行和错误日期

Google apps script 生日电子邮件、空白行和错误日期,google-apps-script,google-sheets,timezone,google-workspace,Google Apps Script,Google Sheets,Timezone,Google Workspace,我有一张谷歌表格,上面有姓名、电子邮件地址和生日。内容如下所示: -------------------------------------------- | Name | email | Birthday | -------------------------------------------- | John Doe | john@doe.com | 2018-05-13 | | Jane Doe | jane@doe.com | 2018-05-

我有一张谷歌表格,上面有姓名、电子邮件地址和生日。内容如下所示:

--------------------------------------------
| Name      | email        | Birthday      |
--------------------------------------------
| John Doe  | john@doe.com | 2018-05-13    |
| Jane Doe  | jane@doe.com | 2018-05-12    |
google sheet正在验证生日列中的日期是否为日期,我已经使用datepicker输入了这些日期。
接下来我想做的是在合适的生日给对方发封电子邮件,但我遇到了一些问题
下面是代码,我将在下面解释问题:

var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;  // First row of data to process
var numRows = 1000;   // Number of rows to process
// Fetch the range of cells B2:B1000
var dataRange = sheet.getRange(startRow, 1, numRows, 1000)
// Fetch values for each row in the Range.
var data = dataRange.getValues();

function sendBirthdayEmails() {
  for (i in data) {
    var row = data[i];
    var startday = Utilities.formatDate(row[2], "UTC+2", "MM-dd"); //Store birthday without year
    var today = Utilities.formatDate(new Date(), "UTC+2", "MM-dd"); //Store current date and remove year
    if (today == startday) { //Evaluate if today is a birthday
      var emailAddress = row[1]; // gather the email address
      var message = "Woop woop, " + row[0] + "!<br>Today is your " + (Utilities.formatDate(new Date(), "UTC+1", "yyyy") - Utilities.formatDate(row[2], "UTC+1", "yyyy")) + " year(s) birthday!"; // Create the email message
      var subject = "Your birthday!"; //Set email subject
      //MailApp.sendEmail(emailAddress, subject, message, {htmlBody: message, replyTo: "birthday@example.com", name: "Birthday wishes", bcc: "myself@exmaple.com"}); //Invoke sending the email
    }
  }
}
var sheet=SpreadsheetApp.getActiveSheet();
var startRow=2;//要处理的第一行数据
var numRows=1000;//要处理的行数
//获取单元格B2:B1000的范围
var dataRange=sheet.getRange(startRow,1,numRows,1000)
//获取范围中每行的值。
var data=dataRange.getValues();
函数sendBirthdayEmails(){
对于(数据中的i){
var行=数据[i];
var startday=Utilities.formatDate(第[2]行,“UTC+2”,“MM dd”);//存储生日,不含年份
var today=Utilities.formatDate(新日期(),“UTC+2”,“MM dd”);//存储当前日期并删除年份
if(today==startday){//评估今天是否是生日
var emailAddress=行[1];//收集电子邮件地址
var message=“Woop-Woop,“+row[0]+”!
今天是您的“+(Utilities.formatDate(new Date(),“UTC+1”,“yyyy”)-Utilities.formatDate(row[2],“UTC+1”,“yyyy”)+“year(s)Birth!”;//创建电子邮件 var subject=“你的生日!”//设置电子邮件主题 //MailApp.sendmail(电子邮件地址、主题、消息,{htmlBody:message,replyTo:“birthday@example.com,姓名:“生日祝福”,密件抄送:myself@exmaple.com“});//调用发送电子邮件 } } }
我相信有很多更顺利的方法来处理这些事情,如果有,请告诉我。然而,我主要遇到两个问题:
1.由于我无法解释的原因,生日栏中的日期计算为前一天的22:00。这听起来像是时区问题,因为我目前在UTC+2(CEST)。但我该如何应对呢?
2.脚本在处理空行/单元格时遇到问题并抛出错误,正确的处理方法是什么?我假设在获取第2行到第1000行时,我上面所做的工作可以以更好的方式完成


非常感谢您的帮助。

我查看了您的数据并复制了错误:

我有一个包含“2018-05-13”的单元格。列的格式为日期,数据验证设置为日期。电子表格设置显示时区为GMT,脚本属性显示时区为GMT

var value = SpreadsheetApp.getActiveSheet().getActiveCell();
Utilities.formatDate(value, "GMT", "MM-dd);
这将返回“05-12”,这是错误的1天

大量的挖掘表明:

返回正确的值


Session.getScriptTimeZone()
为我返回值“Europe/London”,该值必须考虑夏令时并导致Utilities.formatDate的行为不同。

抱歉,忘记添加该值。。。电子表格设置:地区:瑞典时区:GMT+1(斯德哥尔摩)您没有回答所有@pnuts qs。脚本项目中的时区为GMT+1(巴黎)。将其更改为斯德哥尔摩(即使这不重要),结果相同。需要更多信息。日志上说日期是什么?日志截图。。。。可能的解决方法:使用getDisplayValues()而不是getValues()。这将返回单元格中的确切字符串,而不是日期对象。如果需要,使用该字符串初始化新的日期对象。还可以使用
sheet.getLastRow
而不是任意1000 numrows谢谢!我将其更改为used sheet.getLastRow(和column),但当它处理最后一行时仍会出现问题,这被认为是空的。太好了!谢谢,这真的很有帮助!:)现在,当有一行中没有任何数据时,我只需要停止处理:)对每行的第一个单元格进行了以下验证,这似乎有效:if(row[0]==“”){Logger.log(“Breaking out”)break;}
Utilities.formatDate(value, Session.getScriptTimeZone(), "MM-dd");