Google Formで記入された日付をGASで扱うための備忘録

Google Formを作成する際に、日付の欄を入れることができます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583212/4062d53f-120a-f18d-850c-7040e25c42be.png" width=240px>

面談やMTGを開催するために挙げられた候補日に対して、自分のGoogle Calendar上で予定が入っているかどうかを確認するスクリプトをGoogle Apps Script（以下、GAS）で作成しました。この記事は、**日付の扱い方に関する備忘録**です。
(注)Google Formに関する情報は割愛します。

# Google Formの内容を取得する
Google Formで記入された内容は、GASで以下のようにすると取得できます。
詳しくは、こちらの記事を参考にしてください。
[Googleformからのslack通知設定方法](https://qiita.com/pchan52/items/574e930a3cc42cf7f8b9)

```javascript
var itemResponse = e.response.getItemResponses();
for (var j = 0; j < itemResponse.length; j++){    
  var formData = itemResponse[j];
  var title = formData.getItem().getTitle();
  var response = formData.getResponse();
  switch (title) {
    case "氏名":
      name = response;
      break;
    case "メールアドレス":
      mailaddress = response;
      break;
    // 略 //
    default:
      break;
  }
}
```

このとき、取得される日付・時間はGAS上では文字列扱いになります。
**このままカレンダーの関数に代入しても、日付として認識されません。**変換する必要があります。

# Dataオブジェクトに変換する
はじめに、取得された日時がGAS上でどのように出力されるか、確認します。
`Logger.log()`に日時代入すると、以下のように出力されます。
> 日付：2021-01-12
> 時刻：13:00

日付は`-`で、時刻は`:`でつながれていることがわかります。
この文字列をそのままDateオブジェクトに入れることはできますが、CalendarAppが日付として扱うことができません。
(invalid~ というエラーが出るはずです。)

調べてみたところ、Dateオブジェクトでフォーマットによっては変換できないことがあるようです。
（参考：[Google Apps Scriptの日付文字列の変換](https://imabari.hateblo.jp/entry/2015/06/15/115047)）
以下のフォーマットに一致するように、スクリプト上で調整します。
> 2021-01-12T13:00:00.000"

その上で、Dateオブジェクトに代入します。

```javascript

var date= new Date("2021-01-12T13:00:00.000");
```

### 注意
出力した時刻が意図したものでない場合、スクリプトのタイムゾーンが`Asia/Tokyo`になっていない可能性があります。
その場合は、`appsscript.json`というファイル内に記載されているタイムゾーンを`Asia/Tokyo`に変更します。
`appsscript.json`は、**プロジェクトの設定**内`「appsscript.json」マニフェスト ファイルをエディタで表示する`にチェックを入れると表示されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583212/3a7b66d7-e5fa-79de-c984-1dbc9418d70e.png" width=540px>
チェック後に、以下のように変更すれば問題ないです。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583212/735d0980-aa52-f515-c78f-109929a1951f.png" width=540px>
参考：[Google Apps Scriptで日付のタイムゾーンを日本に直す方法](https://masa-enjoy.com/gas-dateobject-timezone)

# CalendarApp
Google CalendarをGASで扱うときのスクリプトを一部紹介します。
[公式サイト](https://developers.google.com/apps-script/reference/calendar/calendar-app)

まず、予定を記載する、記載されている予定を取得するカレンダーのIDを取得します。
カレンダーIDは、設定 > カレンダーの統合にあります。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583212/01533e72-0da9-1e13-36bd-b0ebf1ff029d.png" width=640px>

`getCalendarById`を使用します。

```javascript
var cals = CalendarApp.getCalendarById("Calendar ID");
```

こちらは、第一希望、第二希望と順番に予定が入っているか確認し、入っていなければ予定を追加するスクリプトです。
Google Calendarに入っている予定を取得するには`getEvents()`、予定を追加するには`createEvent()`を使用します。

```javascript
for(var i=0; i < candidate_days.length; i++){ 
  //Dateオブジェクトに変換
  var start_date= new Date(candidate_days[i]+"T"+candidate_start_time+":00.000");
  var end_date= new Date(candidate_days[i]+"T"+candidate_end_time+":00.000");

  // 先約があるかどうか調べる
  if(cals.getEvents(start_date, end_date).length==0){
    //予約情報をカレンダーに追加
    var thing = name+"さん　面談予約";
    var event = cals.createEvent(thing, start_date, end_date);
    break
  } else {
    var res = name+"さん 第"+(i+1)+"希望に先約がありました。";
    Logger.log(res);
  }
}
```

先約がなければ、以下のように予定が追加されます。
<img src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/583212/c2a7ed04-fb61-334b-e8e3-718f46ff60e6.png" width=540px>

## 参考
* [【GAS】Google Form ＋ SpreadSheetで作る予約システムを作ってみた　簡単ですね。【Google App Script】](https://tom2rd.sakura.ne.jp/wp/2017/07/27/post-5346/)
* [【GAS】2つのcreateEventメソッドを完全マスター](https://google-apps-script.net/instructions/?p=367)
* [【GAS】getEventsメソッドを完全マスター](https://google-apps-script.net/instructions/?p=489)