3

カレンダーのタイムゾーンを使用して、日付オブジェクトのタイムゾーンを設定したいと思います。適切なテクニックを探しています。全国にいくつかの拠点があり、それぞれに日記や日常の活動のための独自のカレンダーがあります。カレンダーに投稿するスクリプトが複数あります。カレンダーのタイムゾーンを使用して日付オブジェクトのタイムゾーンを設定したいのは、ユーザーがさまざまな拠点に移動し、コンピューターが正しいタイムゾーンに設定されていない可能性があるためです。誤った時間設定を避けたい。

  1. スクリプトのtimeZoneをUTCに設定する必要がありますか?

  2. これは私が現在いるところです:

    function submitUiTest(e) {
      var app = UiApp.getActiveApplication();
      var cal = CalendarApp.getCalendarById('calendarId');
      var timeZone = cal.getTimeZone();
    
      var ss = SpreadsheetApp.getActiveSpreadsheet();
      var sheet = ss.getSheetByName('Sheet1');
    
      var startTime = e.parameter.startDate
      startTime.setHours(e.parameter.startHour, e.parameter.startMin, 0)
      startTime = formatTime(startTime, timeZone);
      Logger.log(startTime)
    
      var endTime = e.parameter.endDate
      endTime.setHours(e.parameter.endHour, e.parameter.endMin, 0);
      endTime = formatTime(endTime, timeZone);
      Logger.log(endTime)
    
      cal.createEvent('TimeZone Test', new Date(startTime), new Date(endTime));
    
      ss.appendRow([startTime, endTime]);
    
      return app;
    }
    
    function formatTime(time, timeZone){
      return Utilities.formatDate(time, (timeZone-time.getTimezoneOffset()), 'M/d/yyyy HH:mm');
    }
    

編集:現在3つのカレンダーがあり、それらはユーザーカレンダーではなく、個々のエアステーション用に作成された個別のカレンダーです。エアステーションはそれぞれ別々のタイムゾーンにあります。乗組員はこれらのステーションで作業するため、毎日のアクティビティをカレンダーに投稿します。また、同じカレンダーに投稿するUiスクリプトもいくつかあります。フライトログ。カレンダーへのエントリがいずれかのカレンダーに投稿されると、時間はスクリプトで設定されたタイムゾーンにのみ関連し、カレンダーのタイムゾーンには関連しません。日付またはタイムスタンプオブジェクトが作成されたときに、カレンダー自体が設定されているtimeZoneを使用するにはどうすればよいですか。

さまざまなタイムゾーンの日付を記録するスクリプトのベストプラクティスは何ですか?スクリプトのタイムゾーンをUTCに設定し、変換を行いますか?ユーザーのタイムゾーンを取得するために何を使用しますか。この場合、ユーザーのタイムゾーンが何に設定されているかは関係ありません。カレンダーのタイムゾーンを使用する必要があります。

4

5 に答える 5

4

これは、UIを含まない、回答の修正バージョンです。

function gasTimezoneOffset(date, hour){
  var cal,calTimeZone,calTz,date,dateString,scriptTimeZone,sessionTz;

  var testMonth = "March",
      testDayOfMnth = "26",
      testYr = "2016",
      hour = "10:00",
      timeZoneDiff = 0;

  Logger.log("Script Time Zone: " + Session.getScriptTimeZone());

  dateString = testMonth + " " + testDayOfMnth + ", " + testYr;
  Logger.log("dateString: " + dateString);

  date = new Date(dateString);

  cal = CalendarApp.getDefaultCalendar();
  calTimeZone = cal.getTimeZone();

  calTimeZone = Utilities.formatDate(date, calTimeZone, 'Z');
  scriptTimeZone = Utilities.formatDate(date, Session.getTimeZone(), 'Z');

  calTz = Number(calTimeZone.slice(0,3));
  sessionTz = Number(scriptTimeZone.slice(0,3));

  //If both time zones are the same sign, get the difference between the
  //two.  E.g. -4 and -2.  Difference is 2
  //if each time zone is a different sign, add the absolute values together.
  //-4 and +1 should be 5
  if (calTz < 0 && sessionTz > 0 || calTz > 0 && sessionTz < 0){
    timeZoneDiff = Math.abs(Math.abs(calTz) + Math.abs(sessionTz));
  } else {
    timeZoneDiff = Math.abs(Math.abs(calTz) - Math.abs(sessionTz));
  };

  hour = Number(hour.slice(0,2));    
  return hour + timeZoneDiff;
};
于 2016-02-29T03:06:47.567 に答える
1

編集:小さなテストUIを作成し、2つの異なるタイムゾーンで2つのカレンダーを使用して実行しました。カレンダーイベントはカレンダータイムゾーンで作成され、ユーザーインターフェイスにユーザー値が表示されます。Googleは両方のカレンダーのタイムゾーン設定を処理しますが、異常はありませんでした。つまり、予定どおりに作成されたイベント、つまりカレンダーのタイムゾーンのUIに表示された時間です。

(画面キャプチャ)

ここに画像の説明を入力してください

これが私がテストに使用したコードです:

var tz = [['test_agenda(pacific Time)','test_agenda'],['testencodage(Belgium time)','testencodage']]

function doGet() {
  var app = UiApp.createApplication().setStyleAttribute('padding','15PX');
  var hpanel = app.createHorizontalPanel();
  var dateBox = app.createDateBox().setId('dateBox').setName('dateBox');
  var hour = app.createListBox(false).setId('hour').setName('hour')
  for(h=0;h<25;++h){
    if(h/2==parseInt(h/2)){hour.addItem(parseInt(h/2)+':00')
                         }else{
                          hour.addItem(parseInt(h/2)+':30')
                         }
  }
  var amPm = app.createListBox(false).setId('am').setName('amPm')
  .addItem('AM').addItem('PM');
  var dateTimeLabel = app.createLabel('',false).setId('dateTimeLabel');
  var submit = app.createButton('Submit').setId('submit');
  var tzList = app.createListBox().setName('tzList');
    for(var c in tz){tzList.addItem(tz[c][0],tz[c][1])}
  var handler1 = app.createClientHandler().validateMatches(dateBox, '2','g').forEventSource().setEnabled(false);
  var handler2 = app.createServerHandler('createE').validateMatches(dateBox, '2','g').addCallbackElement(hpanel).addCallbackElement(tzList);
  submit.addClickHandler(handler1).addClickHandler(handler2);
  hpanel.add(dateBox).add(hour).add(amPm)
  app.add(hpanel);
  app.add(tzList).add(submit);
  app.add(dateTimeLabel);
  return app;
}

function createE(e) {
  var app = UiApp.getActiveApplication();
  var date = e.parameter.dateBox;
  var cal = CalendarApp.getCalendarsByName(e.parameter.tzList)[0]
  var timeZone = cal.getTimeZone();
  var sessionTz = Session.getTimeZone()
  Logger.log(sessionTz)
  Logger.log(timeZone)
  var hour = Number(e.parameter.hour.split(':')[0]);  
  var min = Number(e.parameter.hour.split(':')[1]);
  var amPm = e.parameter.amPm;
  if (amPm == 'PM' ){hour = hour+12};  // ADD 12 HOURS TO PM HOURS, EXCEPT 12PM
  if (hour == 24){hour = 0;amPm='AM'};  // HANDLE 12AM HOUR CORRECTLY
  var newDate=new Date(date)
  newDate.setHours(hour,min,0,0)
  Logger.log('start : '+newDate)
  var newDateString = Utilities.formatDate(newDate, sessionTz, 'MM/dd/yyyy hh:mm aaa');
  app.getElementById('dateTimeLabel').setText('tz = '+timeZone+' - '+newDateString);
  Logger.log('end : '+new Date(newDate.getTime()+3600000))
  cal.createEvent('test Event in TZ '+timeZone, newDate, new Date(newDate.getTime()+3600000))

  app.getElementById('submit').setEnabled(true);
  return app;
}

最初のコメント:

私はあなたにいくつかの質問をするためにコメントを書き始めました、しかしそれは長すぎました...それでこれを答えではなくコメントとして考えてください;-)。「コンピュータが適切なタイムゾーンに設定されていない」についてあなたが言っていることを理解できません。Googleカレンダーを使用している場合、コンピュータのタイムゾーンは関係ありません。これは、GoogleCalのパラメータの問題です。あなたの目標が、スクリプトが午前8時に予定を設定した場合、どこにいてもカレンダーの午前8時に表示されることです(「ローカル」タイムゾーンでは午前8時)。
要約すると、このスクリプトを1つの場所から実行し、他のタイムゾーンの人々のイベントを自分のカレンダーで作成していますか?また、ユーザーは異なるタイムゾーンを移動していますか?これらは2つの別々の質問であり、単一の解決策はありません。1人のユーザーがタイムゾーンを移動している場合、GCalパラメータを変更しない限り、すべてのイベントがシフトされます。しかし、そうすると、適切なタイミングで通知が届かず、カレンダーのインターフェイスが時間切れになります...そのため、これは合理的な解決策ではありません。私の最後の質問:あなたが別のカレンダー(別のtz)でイベントを作成するとき、それはあなたとこの人の間の約束である可能性がありますか?言い換えれば、ユースケースにとって重要な絶対時間ですか?

于 2013-03-26T20:41:32.483 に答える
1

ここに問題の解決策があります。私はおそらく自分の邪魔にならないか、何か簡単なことを見逃したことがありますが、これは最終的に私が望んでいたように機能します。気軽に批評してください。わかりやすくするために、webappのタイムゾーンをGMT-0000に設定しました。

function uiTest() {
  var app = UiApp.createApplication();

  var startDate = app.createDateBox().setName('startDate').setId('startDate').setWidth('75');
  var startHour = app.createListBox().setName('startHour').setId('startHour').setWidth('45');
  var startMin = app.createListBox().setName('startMin').setId('startMin').setWidth('45');

  var endDate = app.createDateBox().setName('endDate').setId('endDate').setWidth('75');
  var endHour = app.createListBox().setName('endHour').setId('endHour').setWidth('45');
  var endMin = app.createListBox().setName('endMin').setId('endMin').setWidth('45');

  for (h=0;h<24;++h){
  if(h<10){
    var hourstr='0'+h
  }else{
    var hourstr=h.toString()
    }
  startHour.addItem(hourstr)
  endHour.addItem(hourstr)
  }
  for (m=0;m<60;++m){
  if(m<10){
    var minstr='0'+m
  }else{
    var minstr=m.toString()
    }
  startMin.addItem(minstr)
  endMin.addItem(minstr)
  }


  var grid = app.createFlexTable().setId('grid');
  app.add(grid);

  grid.setWidget(0, 0, app.createLabel('Start Date'));
  grid.setWidget(1, 0, startDate);

  grid.setWidget(0, 1, app.createLabel('Hour'));
  grid.setWidget(1, 1, startHour);


  grid.setWidget(0, 2, app.createLabel('Min'));
  grid.setWidget(1, 2, startMin);

  grid.setWidget(2, 0, app.createLabel('End Date'));
  grid.setWidget(3, 0, endDate);

  grid.setWidget(2, 1, app.createLabel('Hour'));
  grid.setWidget(3, 1, endHour);

  grid.setWidget(2, 2, app.createLabel('Min'));
  grid.setWidget(3, 2, endMin);



  app.add(app.createButton('Submit', app.createServerHandler('submitUiTest').addCallbackElement(grid)));

  SpreadsheetApp.getActiveSpreadsheet().show(app);  
}


function submitUiTest(e) {
  var app = UiApp.getActiveApplication();
  var cal = CalendarApp.getCalendarById('');//Info Sys Calendar set to Central Time
  //var cal = CalendarApp.getCalendarById('');//Fort Bliss (Mountain Time)
  var calTimeZone = cal.getTimeZone();

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = ss.getSheetByName('Sheet1');


  var startTime = e.parameter.startDate
  startTime.setHours(gasTimezoneOffset(startTime, e.parameter.startHour, calTimeZone), e.parameter.startMin, 0);
  Logger.log('startTime: '+Utilities.formatDate(startTime, calTimeZone, 'M/d/yyyy HH:mm z'));

  var endTime = e.parameter.endDate
  endTime.setHours(gasTimezoneOffset(endTime, e.parameter.endHour, calTimeZone), e.parameter.endMin, 0);
  Logger.log('endTime: '+endTime)

  var timeStamp = Utilities.formatDate(startTime, calTimeZone, 'M/d/yyyy HH:mm z');

  cal.createEvent(timeStamp, new Date(startTime), new Date(endTime));

  ss.appendRow([startTime, endTime]);

  return app;
}


function gasTimezoneOffset(date, hour, calTimeZone){
  var calTz = new Number(Utilities.formatDate(date, calTimeZone, 'Z').substr(1,2));
  var sessionTz = new Number(Utilities.formatDate(date, Session.getTimeZone(), 'Z').substr(1,2));

  switch (Utilities.formatDate(date, calTimeZone, 'Z').substring(0,1)){
    case '+':
      var timeZoneOffset = sessionTz - calTz;
      break;
    case '-':
      var timeZoneOffset = sessionTz + calTz;
      break;
  }

  hour = new Number(hour);

  return hour + timeZoneOffset;
}
于 2013-04-14T02:14:02.527 に答える
1

これは、Calendarオブジェクトと「スクリプト時間」を受け取り、「カレンダー時間」を返す関数を作成するために使用することになったSandyのコードのバージョンです。

/**
 * Given a script date object, return the time in the user's calendar
 *
 * Sandy Good's answer to this SO question:
 *
 *   http://stackoverflow.com/questions/15645343/how-to-use-timezone-of-calendar-to-set-timezone-for-date-object
 *
 * @param {Date} scriptDateTime
 * @param {Calendar} calendar
 *
 * @return {Date} calendarDateTime
 */

function getCalendarDateTime (scriptDateTime, calendar) {

  Logger.log('scriptDateTime: ' + scriptDateTime)

  var calendarTimeZoneString = calendar.getTimeZone() 
  var calendarTimeZone = Utilities.formatDate(scriptDateTime, calendarTimeZoneString, 'Z')
  var calendarTz = Number(calendarTimeZone.slice(0,3)) 
  Logger.log('calendarTimeZone: %s (%s)', calendarTimeZoneString, calendarTz)

  var scriptTimeZoneString = Session.getScriptTimeZone()
  var scriptTimeZone = Utilities.formatDate(scriptDateTime, scriptTimeZoneString, 'Z')
  var sessionTz = Number(scriptTimeZone.slice(0,3))
  Logger.log('scriptTimeZone: %s (%s)', scriptTimeZoneString, sessionTz)

  // If both time zones are the same sign, get the difference between the
  // two.  E.g. -4 and -2.  Difference is 2
  // 
  // If each time zone is a different sign, add the absolute values together.
  // -4 and +1 should be 5

  var timeZoneDiff

  if (calendarTz < 0 && sessionTz > 0 || calendarTz > 0 && sessionTz < 0) {

    timeZoneDiff = Math.abs(Math.abs(calendarTz) + Math.abs(sessionTz))

  } else {

    timeZoneDiff = Math.abs(Math.abs(calendarTz) - Math.abs(sessionTz)) 
  }

  Logger.log('timeZoneDiff: ' + timeZoneDiff)

  var scriptHour = scriptDateTime.getHours()
  var calendarHour = scriptHour + timeZoneDiff

  var calendarDateTime = new Date(
    scriptDateTime.getYear(), 
    scriptDateTime.getMonth(),
    scriptDateTime.getDate(),
    calendarHour,
    scriptDateTime.getMinutes())

  Logger.log('calendarDateTime: ' + calendarDateTime)

  return calendarDateTime  
}

// Script is PST (GMT-8) and calendar is GMT

function test_getCalendarDateTime() {
  var calendar = CalendarApp.getDefaultCalendar()
  var scriptDateTime = new Date(2017, 0, 30, 12, 0) // 2017-01-30 12:00 PST
  var calendarDateTime = getCalendarDateTime(scriptDateTime, calendar) // 2017-01-30 20:00 PST
}
于 2017-02-09T17:49:31.400 に答える
0

タイムゾーンごとに個別のWebアプリをデプロイしてみてください。各アプリのタイムゾーンを、それらがリンクされている一意のカレンダーのタイムゾーンと一致するように設定します。異なるタイムゾーンにカレンダーが3つしかないため、この場合はうまくいくようです。

于 2013-04-13T02:38:19.127 に答える