Javascript 谷歌表单上提交获取值和格式的时间

Javascript 谷歌表单上提交获取值和格式的时间,javascript,google-apps-script,timezone,google-forms,Javascript,Google Apps Script,Timezone,Google Forms,我正在使用谷歌应用程序脚本和谷歌表单。当用户提交Google表单时,我从一个问题中得到一个值。然后我取那个值,把它变成一个日期对象,根据我在上面看到的,我用它来确定时区。我通过Utilities.formatDate运行date对象,希望获得格式正确的日期 示例:上午9:00 但事实上,我得到的时间与预期完全不同 我的问题是:有人能帮我理解为什么下面的代码输出的时间是3小时不同的吗 function onSubmit(e) { var values = e.values; Logg

我正在使用谷歌应用程序脚本和谷歌表单。当用户提交Google表单时,我从一个问题中得到一个值。然后我取那个值,把它变成一个日期对象,根据我在上面看到的,我用它来确定时区。我通过Utilities.formatDate运行date对象,希望获得格式正确的日期

示例:上午9:00

但事实上,我得到的时间与预期完全不同

我的问题是:有人能帮我理解为什么下面的代码输出的时间是3小时不同的吗

function onSubmit(e) {

  var values = e.values;  
  Logger.log(values);

  try {    
    var start1 = new Date(values[3]);
    var startN = new Date(start1).toString().substr(25,6)+"00";
    var startT = Utilities.formatDate(start1, startN, "h:mm a");
    Logger.log(startT);

  } catch(error) {
    Logger.log(error);
  }
}
请尝试以下方法:

var timeZone = Session.getScriptTimeZone();
var startT = Utilities.formatDate(start1, timeZone, "h:mm a");
Utilities.formatDate
函数需要一个有效的IANA时区(如
America/Los_Angeles
),而不是像
GMT+0700
那样的GMT偏移量

我假设
Session.getScriptTimeZone()
返回适当的区域。如果没有,那么您可能需要硬编码一个特定的区域,或者使用不同的函数来确定它


此外,脚本中的
+“00”
假设所有时区都使用整小时偏移量。在现实中,有几个有30分钟或45分钟的偏移量。

假设实用程序formatDate不支持GMT。。。参数不正确

您在参考资料中提到的帖子用于获取日历事件,当您从另一个夏时制期间获取事件(从日历事件本身获取TZ信息)时,这是获取正确值的有用方法,例如,下个月的事件将在“夏季”,而我们仍在“冬季”

您的问题可能来自不同的来源,具体取决于脚本的时区设置和来源的时区。您能描述一下使用此脚本的确切配置吗

同时,下面是一个小代码,演示了代码如何工作以及记录器结果:

function testOnSubmit() {
  var eventInfo = {};
  var values = {};  
  values['3'] = new Date();
  eventInfo['values'] = values;
  Logger.log('eventInfo = '+JSON.stringify(eventInfo)+'\n\n');
  onSubmit(eventInfo);
}

function onSubmit(e) {
  var values = e.values;  
  try {    
    var start1 = new Date(values[3]);
    Logger.log('onSubmit log results : \n');
    Logger.log('start1 = '+start1)
    var startN = new Date(start1).toString().substr(25,6)+"00";
    Logger.log('startN = '+startN);
    var startT = Utilities.formatDate(start1, startN, "h:mm a");
    Logger.log('result in timeZone = '+startT);
  } catch(error) {
    Logger.log(error);
  }
}
function testOnSubmit() {
  var eventInfo = {};
  var values = {};  
  values['3'] = new Date(2014,0,1,8,0,0,0);
  eventInfo['values'] = values;
  Logger.log('eventInfo = '+JSON.stringify(eventInfo)+'\n\n');
  onSubmit(eventInfo);
  values['3'] = new Date(2014,6,1,8,0,0,0);
  eventInfo['values'] = values;
  Logger.log('eventInfo = '+JSON.stringify(eventInfo)+'\n');
  onSubmit(eventInfo);
}

function onSubmit(e) {
  var values = e.values;  
  var start1 = new Date(values[3]);
  Logger.log('onSubmit log results : ');
  Logger.log('start1 = '+start1)
  var startN = new Date(start1).toString().substr(25,8);
  Logger.log('startN = '+startN);
  Logger.log('result in timeZone using GMT string = '+Utilities.formatDate(start1, startN, "MMM,d  h:mm a"));
  Logger.log('result in timeZone using Joda.org string = '+Utilities.formatDate(start1, 'Europe/Brussels', "MMM,d  h:mm a"));
  Logger.log('result in timeZone using Session.getScriptTimeZone() = '+Utilities.formatDate(start1, Session.getScriptTimeZone(), "MMM,d  h:mm a")+'\n');
}

编辑:此外,关于30和45'偏移,可以通过如下更改子字符串长度轻松解决:

var startN = new Date(start1).toString().substr(25,8);
结果是一样的,几年前我不得不使用另一个版本,因为Google在某个时刻()更改了Utilities.formatDate方法,但这已经被修复了

编辑2:在同一主题上,两种方法实际上返回相同的结果,GMT字符串的唯一优点是您不必知道确切的时区名称。。。还有
Session.getScriptTimeZone()
方法。下面是一个演示脚本,显示了1月和7月两个日期的结果以及日志结果:

function testOnSubmit() {
  var eventInfo = {};
  var values = {};  
  values['3'] = new Date();
  eventInfo['values'] = values;
  Logger.log('eventInfo = '+JSON.stringify(eventInfo)+'\n\n');
  onSubmit(eventInfo);
}

function onSubmit(e) {
  var values = e.values;  
  try {    
    var start1 = new Date(values[3]);
    Logger.log('onSubmit log results : \n');
    Logger.log('start1 = '+start1)
    var startN = new Date(start1).toString().substr(25,6)+"00";
    Logger.log('startN = '+startN);
    var startT = Utilities.formatDate(start1, startN, "h:mm a");
    Logger.log('result in timeZone = '+startT);
  } catch(error) {
    Logger.log(error);
  }
}
function testOnSubmit() {
  var eventInfo = {};
  var values = {};  
  values['3'] = new Date(2014,0,1,8,0,0,0);
  eventInfo['values'] = values;
  Logger.log('eventInfo = '+JSON.stringify(eventInfo)+'\n\n');
  onSubmit(eventInfo);
  values['3'] = new Date(2014,6,1,8,0,0,0);
  eventInfo['values'] = values;
  Logger.log('eventInfo = '+JSON.stringify(eventInfo)+'\n');
  onSubmit(eventInfo);
}

function onSubmit(e) {
  var values = e.values;  
  var start1 = new Date(values[3]);
  Logger.log('onSubmit log results : ');
  Logger.log('start1 = '+start1)
  var startN = new Date(start1).toString().substr(25,8);
  Logger.log('startN = '+startN);
  Logger.log('result in timeZone using GMT string = '+Utilities.formatDate(start1, startN, "MMM,d  h:mm a"));
  Logger.log('result in timeZone using Joda.org string = '+Utilities.formatDate(start1, 'Europe/Brussels', "MMM,d  h:mm a"));
  Logger.log('result in timeZone using Session.getScriptTimeZone() = '+Utilities.formatDate(start1, Session.getScriptTimeZone(), "MMM,d  h:mm a")+'\n');
}


另请注意记录器有自己的方式显示日期对象值!它使用ISO 8601时间格式,即UTC值。

并对我之前的回答表示歉意。我不是故意居高临下的。我只是错过了这段代码在GoogleApps脚本的上下文中运行,而不是在web浏览器中运行。我删除了那个答案。我希望这会更有帮助。谢谢你@Matt Johnson这会更有帮助。