質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.35%
Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

date

dateは、date型や日付に関する関数や処理についてのタグです

Google カレンダー

Google カレンダーは、Google社が提供する無料のスケジュール管理ツールです。パソコンやスマートフォン、タブレットなどからアクセスし、スケジュールの追加・変更が可能。Googleアカウントがあれば誰でも使用できます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

Q&A

解決済

1回答

1307閲覧

GAS_GoogleAppsScriptでGoogle スプレッドシートの内容をGoogleカレンダーに登録したいのですが、date型で躓いてます。

DrqYuto

総合スコア432

Google スプレッドシート

Google スプレッドシートは、フリーで利用できる表計算ソフト。Webアプリのためインターネットに接続することで利用できます。チャートやグラフの作成のほか、シートを他のユーザーと共有したり、同時に作業を進めることも可能です。

date

dateは、date型や日付に関する関数や処理についてのタグです

Google カレンダー

Google カレンダーは、Google社が提供する無料のスケジュール管理ツールです。パソコンやスマートフォン、タブレットなどからアクセスし、スケジュールの追加・変更が可能。Googleアカウントがあれば誰でも使用できます。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Google

Googleは、アメリカ合衆国に位置する、インターネット関連のサービスや製品を提供している企業です。検索エンジンからアプリケーションの提供まで、多岐にわたるサービスを提供しています。

0グッド

0クリップ

投稿2020/05/01 09:24

編集2020/05/01 11:15

参考にしたサイトは一つのセル内に日付と時間を入れてました。
そのサンプルコードでカレンダー登録はできたのですが、日付と時間で2つのセルに分けて正規化(?)した方が再利用しやすいだろうと思いました。
そこで、日付と時間を2つのセルに分けました。

startをstart1とstart2に分けたところは、Loggerで値を確認できました。
僕の書いたコードだと、開始日が意図しない時間になってしまいました。

function createEventFromSheet() { // シートを選択 var sheet = SpreadsheetApp.getActiveSheet(); // 行を選択 for(var i = 23; i <= sheet.getLastRow(); i++) { // セルの値を取得 var start1 = sheet.getRange(i, 1).getValue().toString(); var start2 = sheet.getRange(i, 2).getValue().toString(); var end = sheet.getRange(i, 3).getValue().toString(); var title = sheet.getRange(i, 4).getDisplayValue().toString(); // タイトルがない場合、終了する if(title.length <= 0) { break; } // 開始と終了の日時を取得 var startTime = new Date(start1+" "+start2); Logger.log(start1); Logger.log(start2); var endTime = new Date(end); // オプションを設定 var options = { location: "静大", description: "詳細情報" } // カレンダーを取得 var cal = CalendarApp.getDefaultCalendar(); // カレンダーにイベントを追加 cal.createEvent(title, startTime, endTime, options); } }

イメージ説明

イメージ説明

参考

function createEventFromSheet() {     // シートを選択     var sheet = SpreadsheetApp.getActiveSheet();       // 行を選択     for(var i = 2; i <= sheet.getLastRow(); i++) {         // セルの値を取得         var start = sheet.getRange(i, 1).getValue().toString();         var end = sheet.getRange(i, 2).getValue().toString();         var title = sheet.getRange(i, 3).getDisplayValue().toString();           // タイトルがない場合、終了する         if(title.length <= 0) {             break;         }           // 開始と終了の日時を取得         var startTime = new Date(start);         var endTime = new Date(end);           // オプションを設定         var options = {             location: "名古屋市",             description: "詳細情報"         }           // カレンダーを取得         var cal = CalendarApp.getDefaultCalendar();           // カレンダーにイベントを追加         cal.createEvent(title, startTime, endTime, options);     } }

追記
試してみたこと

var date = new Date(); // 今日の日付を表示 Logger.log(Utilities.formatDate( date, 'Asia/Tokyo', 'yyyy/MM/dd hh:mm:ss'));

で、
[20-05-01 20:10:54:919 JST] 2020/05/01 08:10:54
を得ることができました。近づいてはいるような気がしますが、まだ分かりません。

参考
GoogleAppsScriptで現在日時の取得

var date = new Date(); // 今日の日付を表示 Logger.log(Utilities.formatDate( date, 'Asia/Tokyo', 'yyyyMMdd: hhmmss'));

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

dodox86

2020/05/01 09:54

> startをstart1とstart2に分けたところは、Loggerで値を確認できました。 とは、 > var startTime = new Date(start1+" "+start2); > Logger.log(start1); > Logger.log(start2); の部分だと思いますが、startTimeの方をLoggerで確認して質問文中に追記してください。恐らく意図しないようなかたちの文字列になっていると思います。
DrqYuto

2020/05/01 10:01

了解です。確認します。
DrqYuto

2020/05/01 10:25

Loggerした結果です。 [20-05-01 19:23:09:612 JST] Mon May 04 2020 00:00:00 GMT+0900 (日本標準時) [20-05-01 19:23:09:615 JST] Sat Dec 30 1899 10:10:00 GMT+0900 (日本標準時) [20-05-01 19:23:09:617 JST] Thu Jan 01 09:00:00 GMT+09:00 1970 コード ``` // 開始と終了の日時を取得 var startTime = new Date('start1 start2'); Logger.log(start1); Logger.log(start2); Logger.log(startTime); var endTime = new Date(end); ```
DrqYuto

2020/05/01 10:27

意図しない時間になっていました。 確認したところ、1970年の1月1日9:00- が開始時刻になってしまいました。
dodox86

2020/05/01 10:29

そういうことですね。その値は、(ご存じだと思いますが)UNIX時間のepochの0です。
dodox86

2020/05/01 10:30

ご自分で改修して、直ったら自己解決で質問を閉じてもらえれば、と思います。
DrqYuto

2020/05/01 10:31

UNIX時間のデフォルトということなんですね。 参考 UNIX時間 - Wikipedia https://ja.wikipedia.org/wiki/UNIX%E6%99%82%E9%96%93 "UNIX時刻の表示例[編集] UNIX時間の例 UNIX時間 協定世界時 (UTC) 日本標準時 (JST) 0 1970-01-01T00:00:00 1970-01-01T09:00:00"
dodox86

2020/05/01 10:32

そうです。そこからC言語でいうところのtime_t単位で時間が進みます。
DrqYuto

2020/05/01 10:38

C言語はあまり触ったことなかったので、勉強になりました。 コードの話になりますが、 'start1 start2' は、 内部で '2020/05/04 10:20' になるかと思ってました。ですが、そうは行かないんですね。 参考 time_t - Wikipedia https://ja.wikipedia.org/wiki/Time_t "UNIXとPOSIX互換システムでは、UNIX時間(協定世界時 (UTC) 1970年1月1日0時00分00秒からの秒数)を表す符号付の整数(通常は32または64ビット)でtime_t型を実装している(閏秒は数えない)。"
dodox86

2020/05/01 10:46

> コードの話になりますが、 実際にstart1 と start2 を文字列として連結しているのはDateインスタンス生成部分ですが、 > var startTime = new Date(start1+" "+start2); Dateのコンストラクタへ渡す文字列が、日時文字列としてふさわしくないのだと思います。で、たぶん0になっちゃう。JavaScriptのリファレンスで確認してください。 https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date
DrqYuto

2020/05/01 10:51

なるほど…日時文字列としてふさわしくなかったのですね。 URL見ました。UNIX元期も知りませんでした。 参考 Date - JavaScript | MDN https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date "JavaScript の日時は、基本的に協定世界時 (UTC) の1970年1月1日深夜0時からの経過ミリ秒数で指定されます。この日付と時刻は、コンピューターに記録される日付と時刻の値の主な基準値である UNIX 元期と同じです。"
dodox86

2020/05/01 10:59

そうですね。ちなみにそのリファレンスでは「UNIX元期」と訳しているようですが、単に「UNIXエポック」(UNIX epoch)と言う方が一般的かと思います。(あまり元期とは聴かない。私が知らないだけかもしれませんけど)
DrqYuto

2020/05/01 11:01

これからは、UNIXエポックで覚えます。ありがとうございます。
dodox86

2020/05/01 15:02

話が戻りますが、まず、そももそもスプレッドシート上で日付と時間の2つのセルに分け、start1とstart2 としたことだと思います。それをLoggerに出力したところ、以下のようになった訳ですよね。 [20-05-01 19:23:09:612 JST] Mon May 04 2020 00:00:00 GMT+0900 (日本標準時)<=ここがstart1 [20-05-01 19:23:09:615 JST] Sat Dec 30 1899 10:10:00 GMT+0900 (日本標準時)<=ここがstart2 [20-05-01 19:23:09:617 JST] Thu Jan 01 09:00:00 GMT+09:00 1970<=ここがstartTime セル上のstart1相当の日付部分の文字列と、start2相当の時間部分の文字列はどうなっているのでしょうか。start1 "2020/05/04" で、start2 "10:10:10" (いずれも日本時間JST) ですか? Loggerの出力で、"Sat Dec 30 1899 10:10:00 GMT+0900"となっていますが、1899年になのも解せないところです。 Loggerの出力の文字列を考えてみると、 start1 + start2 ではstartTimeがおかしくなるのも当然です。
guest

回答1

0

ベストアンサー

苦戦している様子なので、僭越ながら補足させて頂きます。

意図した日時を得るにはDateコンストラクターに日時を表す文字列を与えることです。

簡単な対処としては、スプレッドシートの年月日と時分秒のセルを文字列にすることです。
表示形式を書式なしテキストに変更すれば文字列として取得できます。

もし、表示形式を変えたくない場合は次のようにします。
セルの表示形式が日付や時刻の場合はDateオブジェクトとして取得します。

diff

1- var start1 = sheet.getRange(i, 1).getValue().toString(); 2- var start2 = sheet.getRange(i, 2).getValue().toString(); 3+ var start1 = sheet.getRange(i, 1).getValue().toLocaleDateString(); 4+ var start2 = sheet.getRange(i, 2).getValue().toLocaleTimeString();

toLocaleDateString
toLocaleTimeString
start1start2の内容をログで確認してみてください。

この日時を表す文字列は様々な形式を解釈しますが、今後はISO8601形式に統一しようという風潮になっていますので従ったほうが無難です。

ISO 8601形式の時刻表記例
基本形式 20200501T201936+0900
拡張形式 2020-05-01T20:19:36+09:00

そして、日時処理の面倒くささを味わってからMoment.js(GAS版)というライブラリの導入を考えてみてください。

蛇足ですが、dodox86さんとのやりとりの中に、なぜstart2Sat Dec 30 1899 10:10:00 GMT+0900なのかとありましたが、これはExcelの仕様(バグ)に合わせるため、シリアル値は「1899年12月30日午前0時」からの経過秒数としたそうです。
Excelでは1900年は閏年ではないのに「1900年2月29日」が存在します。
GoogleスプレッドシートとGoogle Apps Scriptの日付

投稿2020/05/02 01:28

編集2022/05/30 21:03
aobaoba

総合スコア63

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

DrqYuto

2020/05/02 03:34

ありがとうございます。 [[20-05-02 12:32:22:248 JST] 2020/5/4 [20-05-02 12:32:22:252 JST] 10:20:00 [20-05-02 12:32:22:254 JST] Mon May 04 10:20:00 GMT+09:00 2020 となりました。 そして、うまくカレンダーに登録することができました。 また、Momont.js(GAS版)も入れて試してみました。
DrqYuto

2020/05/02 04:01

// 行を選択 for(var i = 9; i <= sheet.getLastRow(); i++) { // セルの値を取得 var start1 = sheet.getRange(i, 1).getValue().toLocaleDateString(); var start2 = sheet.getRange(i, 2).getValue().toLocaleTimeString(); var end = sheet.getRange(i, 3).getValue().toString(); var title = sheet.getRange(i, 4).getDisplayValue().toString(); 位置を変えてみたところ、登録できました。 しかし、TypeErrorが出ました。 TypeError: sheet.getRange(...).getValue(...).toLocaleDateString is not a function(行 8、ファイル「calender」) Errorが出ても動いているのは、少し変な感じがします。
aobaoba

2020/05/02 04:49

toLocaleDateString は Dateオブジェクトのメソッドです。 セルの表示形式を確認してください。
DrqYuto

2020/05/03 02:33

了解です。うまくいきました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.35%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問