JavaScript
GoogleAppsScript
spreadsheet
More than 1 year has passed since last update.

この記事はGoogle Apps Scriptを実例交えて基礎からざっくり学ぶ Advent Calendar 2017 4日目の記事です。

本アドベントカレンダーは@rt_pの個人プロジェクトですが、筆者はAteam Brides Inc. Advent Calendar 2017にも参加しています。そちらでも出張版記事を書いているので、覗いていただけると嬉しいです。

はじめに

JavaScriptを使っていて、日付を

php
<?php echo date('Y-m-d H:i:s') // 2017-12-04 12:01:10みたいな形式 ?>

のように簡単に整形したいなぁ…と思うこと多くないですか?
Moment.jsを入れるという選択肢もありますが、毎回入れるのも面倒。

GASでは標準でフォーマットを整えることができます。

format.PNG

1.スクリプトエディタを開く

毎度のことながらスプレッドシートを作成。
ツール→スクリプトエディタからスクリプトエディタを開き、以下コードに置き換えて実行します。

format_date.gs
function myFunction() {
  var date = Utilities.formatDate(new Date(), 'Asia/Tokyo', 'yyyy-MM-dd HH:mm:ss');
  Logger.log(date);
}

formatDate(date, timeZone, format)

https://developers.google.com/apps-script/reference/utilities/utilities#formatdatedate-timezone-format

format.PNG

使用できる文字
https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html

2.日付比較の罠

GASを触っていると分かるのですが、JavaScriptの日付はかなり闇が深いです…

new Date や Date.parse で時刻を含まない日付文字列をパースすると、UTC 00:00:00 になる。

参考:JavaScript の Date は罠が多すぎる
https://qiita.com/labocho/items/5fbaa0491b67221419b4

他にも、ハイフン区切りとスラッシュ区切りで挙動が違ったり。

sheet.PNG

new_date.gs
function myFunction() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var sheetDate1 = sheet.getRange(1, 1).getValue(); // 2017/12/12
  Logger.log(sheetDate1);

  var sheetDate2 = sheet.getRange(1, 2).getValue(); // 2017-12-12
  Logger.log(sheetDate2);

  var gasDate1   = new Date('2017/12/12');
  Logger.log(gasDate1);
  var gasDate2   = new Date('2017-12-12');
  Logger.log(gasDate2);
}

これ、実行したらsheetDate1, sheetDate2, gasDate1, gasDate2で同じ結果が返ってくることを期待しますよね?
でも何故か

new_date.PNG

こんな結果になったりします。

通常Web開発のJavaScriptで日付比較をする際はDateオブジェクトのgetTime()で比較が一般的なのですが、GASにおいてはUtilities.formatDate()を使って比較すると事故が少ないのかなとか思っていたりします。

実例としては以下の通りです。

compare_date.gs
function myFunction() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var sheetDate = sheet.getRange(1, 2).getValue(); // 2017-12-12
  var gasDate = new Date('2017-12-12');

  Logger.log(sheetDate == gasDate);
  Logger.log(sheetDate.getTime() == gasDate.getTime());
  Logger.log(Utilities.formatDate(sheetDate, 'Asia/Tokyo', 'yyyy-MM-dd') == Utilities.formatDate(gasDate, 'Asia/Tokyo', 'yyyy-MM-dd'));
}

compare.PNG

gasDateの方が9時間ズレてしまうのですが、Utilitiesで日付フォーマットを指定することで単純な日付で比較しています。

この使い方が綺麗かと言うと悩ましいところではありますが…。

おわりに

今回は日付のフォーマットについてお伝えしました。
本アドベントカレンダーは、1日目~9日目あたりは基礎編でGASに関する基本的な操作を紹介していきます。
10日目以降は応用編ということで、実際に作ったアプリケーションとそれに関する技術の紹介になります。お楽しみに!

明日

【Google Apps Script】その5 該当する日付の行が存在したら上書き、存在しなかったら挿入する
となります。
今日の記事の内容を活用して、デイリー数値を溜めていくシートを作ってみます。
お楽しみに。

前の記事
【Google Apps Script】その3 外部スプレッドシートをDBとして利用する
次の記事
【Google Apps Script】その5 該当する日付の行が存在したら上書き、存在しなかったら挿入する