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

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

新規登録して質問してみよう
ただいま回答率
85.48%
Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

Q&A

解決済

2回答

3352閲覧

IFTTTの{{CreatedAt}}を使って取得した日時(May 05, 2018 at 11:57PM)を「2018/05/05 23:57」という表記に書き換えたい。

koromo_t

総合スコア60

Google Apps Script

Google Apps ScriptはGoogleの製品と第三者のサービスでタスクを自動化するためのJavaScriptのクラウドのスクリプト言語です。

0グッド

0クリップ

投稿2018/05/05 15:14

編集2018/05/12 16:18

IFTTTを使ってTwitterのツイートの日時を取得する際、{{CreatedAt}}を使ったら、
「May 05, 2018 at 11:57PM」という表記で出力されることがわかりました。
これを、「2018/05/05 23:57」という表記に書き換えたいのですが、
方針としては、どのようにすればよいでしょうか。
「May 05, 2018 at 11:57PM」は文字列として認識されているようなので、
スプレッドシートのツールバー?の「123」と書かれたボタンからは、
表記の変更はできないようです。

追記(2018/05/07 23:12)

papinianusさんの回答を参考に、ちょっと書いてみたスクリプトです!
じわじわとゴールへ向かっている感が…♪

javaScript

1function myFunction() { 2 var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 3 var sheet = spreadsheet.getSheetByName('生ログ'); 4 var sheet_hiduke = spreadsheet.getSheetByName('日付成形'); 5 6 // シート「生ログ」関連 7 var lastRow = sheet.getLastRow(); 8 var lastRow_range = sheet.getRange(lastRow,1); 9 var lastRow_val = sheet.getRange(lastRow,1).getValue(); 10 Logger.log(lastRow_val); 11 12 // シート「日付成形」関連 13 var lastRow_hiduke = sheet_hiduke.getLastRow(); 14 var lastRow_hiduke_range = sheet_hiduke.getRange(lastRow_hiduke,1); // ←ここに日付を書き込みたい。 15 16 var str = lastRow_val; 17 Logger.log(str); 18 19 // 日付を抽出 20 var parse = str.replace(",", "").split(" "); 21 return new Date(parse[2], ToMonth(parse[0]), parse[1]); 22 23function ToMonth(str) { 24 switch(str) 25 { 26 case "May": return 4; 27 } 28} 29}

追記2(2018/05/08 19:02)

javaScript

1function DateConverter() { 2 var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 3 4 // シート「生ログ」関連 5 var sheet = spreadsheet.getSheetByName('生ログ'); 6 var lastRow = sheet.getLastRow(); 7 var lastRow_val = sheet.getRange(lastRow,1).getValue(); 8 Logger.log(lastRow_val); 9 10 // シート「日付成形」関連 11 var sheet_hiduke = spreadsheet.getSheetByName('日付成形'); 12 var lastRow_hiduke = sheet_hiduke.getLastRow(); 13 var lastRow_hiduke_range = sheet_hiduke.getRange(lastRow_hiduke,1); // ←ここに日付を書き込みたい。 14 15 var str = lastRow_val; 16 Logger.log(str); 17 18 var year = str.split(" ")[2]; 19 Logger.log(year); 20 var month = MonthNameToNumber(str.split(" ")[0]) - 1;//Dateを作るとき月は0はじまり 21 Logger.log(month); 22 var day = str.replace(",", "").split(" ")[1]; 23 Logger.log(day); 24 var hour_min_ampm = str.split(" ")[4]; 25 Logger.log(hour_min_ampm); 26 var hour = hour_min_ampm.slice(0,2); 27 Logger.log(hour); 28 var min = hour_min_ampm.slice(3,5); 29 Logger.log(min); 30 var ampm = hour_min_ampm.slice(5,8); 31 Logger.log(ampm); 32 var date = new Date(year, month, day, hour, min); 33 Logger.log(date); 34 lastRow_hiduke_range.setValue(date); 35} 36function MonthNameToNumber(shortname) { 37 switch(shortname) { 38 case "January" : return 1; 39 case "February" : return 2; 40 case "March" : return 3; 41 case "April" : return 4; 42 case "May" : return 5; 43 case "June" : return 6; 44 case "July" : return 7; 45 case "August" : return 8; 46 case "September" : return 9; 47 case "October" : return 10; 48 case "November" : return 11; 49 case "December" : return 12; 50 } 51}

追記3(2018/05/08 19:49)

javaScript

1function DateConverter() { 2 var spreadsheet = SpreadsheetApp.getActiveSpreadsheet(); 3 4 // シート「生ログ」関連 5 var sheet = spreadsheet.getSheetByName('生ログ'); 6 var lastRow = sheet.getLastRow(); 7 var lastRow_val = sheet.getRange(lastRow,1).getValue(); 8 Logger.log(lastRow_val); 9 10 // シート「日付成形」関連 11 var sheet_hiduke = spreadsheet.getSheetByName('日付成形'); 12 var lastRow_hiduke = sheet_hiduke.getLastRow(); 13 var lastRow_hiduke_range = sheet_hiduke.getRange(lastRow_hiduke,1); // ←ここに日付を書き込みたい。 14 15 var str = lastRow_val; 16 Logger.log(str); 17 18 var year = str.split(" ")[2]; 19 Logger.log(year); 20 var month = MonthNameToNumber(str.split(" ")[0]) - 1;//Dateを作るとき月は0はじまり 21 Logger.log(month); 22 var day = str.replace(",", "").split(" ")[1]; 23 Logger.log(day); 24 var hour_min_ampm = str.split(" ")[4]; 25 Logger.log(hour_min_ampm); 26 var hour = hour_min_ampm.slice(0,2); 27 Logger.log(hour); 28 var min = hour_min_ampm.slice(3,5); 29 Logger.log(min); 30 var ampm = hour_min_ampm.slice(5,8); 31 Logger.log(ampm); 32 var date_AM = new Date(year, month, day, hour, min); 33 Logger.log(date_AM); 34 var hour_PM = date_AM.getHours()+12; 35 Logger.log(hour_PM); 36 if(ampm=="AM"){ 37 lastRow_hiduke_range.setValue(date_AM); 38 } 39 else{ 40 var date_PM = new Date(year, month, day, hour_PM, min); 41 Logger.log(date_PM); 42 lastRow_hiduke_range.setValue(date_PM); 43 } 44} 45function MonthNameToNumber(shortname) { 46 switch(shortname) { 47 case "January" : return 1; 48 case "February" : return 2; 49 case "March" : return 3; 50 case "April" : return 4; 51 case "May" : return 5; 52 case "June" : return 6; 53 case "July" : return 7; 54 case "August" : return 8; 55 case "September" : return 9; 56 case "October" : return 10; 57 case "November" : return 11; 58 case "December" : return 12; 59 } 60}

追記4【スクリプト完成】(2018/05/08 20:34)

IFTTT側にて「=DateConverter({{CreatedAt}})」と設定すると、
{{CreatedAt}}部分が数字として認識されるようなので、
「=DateConverter(“{{CreatedAt}}”)」とダブルクオーテーションで囲ったところ、
期待通りの結果を得ることができました!

javaScript

1function DateConverter(str) { 2 var year = str.split(" ")[2]; 3 Logger.log(year); 4 var month = MonthNameToNumber(str.split(" ")[0]) - 1;//Dateを作るとき月は0はじまり 5 Logger.log(month); 6 var day = str.replace(",", "").split(" ")[1]; 7 Logger.log(day); 8 var hour_min_ampm = str.split(" ")[4]; 9 Logger.log(hour_min_ampm); 10 var hour = hour_min_ampm.slice(0,2); 11 Logger.log(hour); 12 var min = hour_min_ampm.slice(3,5); 13 Logger.log(min); 14 var ampm = hour_min_ampm.slice(5,8); 15 Logger.log(ampm); 16 var date_AM = new Date(year, month, day, hour, min); 17 Logger.log(date_AM); 18 var hour_PM = date_AM.getHours()+12; 19 Logger.log(hour_PM); 20 if(ampm=="AM"){ 21 return date_AM; 22 } 23 else{ 24 var date_PM = new Date(year, month, day, hour_PM, min); 25 Logger.log(date_PM); 26 return date_PM; 27 } 28} 29function MonthNameToNumber(shortname) { 30 switch(shortname) { 31 case "January" : return 1; 32 case "February" : return 2; 33 case "March" : return 3; 34 case "April" : return 4; 35 case "May" : return 5; 36 case "June" : return 6; 37 case "July" : return 7; 38 case "August" : return 8; 39 case "September" : return 9; 40 case "October" : return 10; 41 case "November" : return 11; 42 case "December" : return 12; 43 } 44}

追記5【微調整】(2018/05/13 0:57)

日付が変わったら、hour部分が0になって、00:00AMという表記になると思うじゃろ。
それがなぜか、IFTTTのCreatedAtを使って取得した文字列は12:00AMとなるようなので(※)、
スクリプトのhour部分に「.replace("12", "0")」を足すことで、
日付が変われば24時間制表記の「00:00」となるようにしました。
(※:調べてみると、英米式の12時間制表記はそういうものらしいですね。)

正午にどのような反応をするかは未確認ながら、おそらく12:00PMとなるはずなので、
hourの12を0に置き換えて、PMなのでhourに12が足されるスクリプトが働き、
結果、24時間制表記の「12:00」を得ることができるはず。

javaScript

1function DateConverter(str) { 2 var year = str.split(" ")[2]; 3 Logger.log(year); 4 var month = MonthNameToNumber(str.split(" ")[0]) - 1;//Dateを作るとき月は0はじまり 5 Logger.log(month); 6 var day = str.replace(",", "").split(" ")[1]; 7 Logger.log(day); 8 var hour_min_ampm = str.split(" ")[4]; 9 Logger.log(hour_min_ampm); 10 var hour = hour_min_ampm.slice(0,2).replace("12", "0"); 11 Logger.log(hour); 12 var min = hour_min_ampm.slice(3,5); 13 Logger.log(min); 14 var ampm = hour_min_ampm.slice(5,8); 15 Logger.log(ampm); 16 var date_AM = new Date(year, month, day, hour, min); 17 Logger.log(date_AM); 18 var hour_PM = date_AM.getHours()+12; 19 Logger.log(hour_PM); 20 if(ampm=="AM"){ 21 return date_AM; 22 } 23 else{ 24 var date_PM = new Date(year, month, day, hour_PM, min); 25 Logger.log(date_PM); 26 return date_PM; 27 } 28} 29function MonthNameToNumber(shortname) { 30 switch(shortname) { 31 case "January" : return 1; 32 case "February" : return 2; 33 case "March" : return 3; 34 case "April" : return 4; 35 case "May" : return 5; 36 case "June" : return 6; 37 case "July" : return 7; 38 case "August" : return 8; 39 case "September" : return 9; 40 case "October" : return 10; 41 case "November" : return 11; 42 case "December" : return 12; 43 } 44}

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

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

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

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

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

guest

回答2

0

ベストアンサー

詰まっているところ、が私の推測になるのですが関数(function)の働きで詰まっていると理解しました。
つまり、lastRow_hiduke_range.setValue("出したい日付")とすればいいということは分かっているはずなので、lastRow_valをなんやかんやして"出したい日付"にしたいが、どう加工するかが今一つということですよね。

GASというよりjavascriptの関数の話になりますが、関数は「これこれをする」(シートに書くとか)以外に、「何か(引数)を入れたら別のものが戻ってくる(返り値)」という処理ができます。returnがそのキーワードです。
(コメントで、「そのあと、月の英名を数字に置き換えている。」と書かれている理解はちょっと違うように思います。"月の英明を数字にかえてくれる人に加工を投げて、数字化されたものを利用する"がreturn new Date(parse[2], ToMonth(parse[0]), parse[1]);ToMonth(parse[0])のところで起こっています。計算機がToMonthに出会ったところで、一旦処理がfunction ToMonth(){}に飛んでreturnしたら, parse[1]の直前から再開している感じです。後でおきかえたのではなく、途中で置き換えが起こっています)

返り値を持つ関数については、代入に使えるので例えば

javascript

1var dateObj = myfunction("May, 01, 2018 00:00AM");

とすることができます(当初はこういう想定でした。下記脇道参照)

仮に追記された方法であれば、

javascript

1 // 日付を抽出 2 var parse = str.replace(",", "").split(" "); 3 return new Date(parse[2], ToMonth(parse[0]), parse[1]);

と書いているところではreturnではなく

javascript

1var post_date = new Date(parse[2], ToMonth(parse[0]), parse[1]); 2lastRow_hiduke_range.setValue(post_date);

みたいな感じではないかと思います。

---脇道
ちょっとお考えから外れます。
IFTTTだったので、IFTTTのレシピで、入力する文字列を指定できるはずですが、createdの文字列をうまいこと加工する(returnできる)関数が作れるのであれば、レシピの設定値のほうで=DateConverter({{createdat}})をシートに書き込むようにしたほうがいいと思ってました。
そのようにするとしたら

javascript

1function DateConverter(str) { 2 var year = str.split(" ")[2]; 3 var month = MonthNameToNumber(str.split(" ")[0]) - 1;//Dateを作るとき月は0はじまり 4 var day = str.split(" ")[1]; 5 var hour = ...; 6 var min = ...; 7 return new Date(year, month, day, hour, min); 8} 9function MonthNameToNumber(shortname) { 10 switch(shortname) { 11 case "Jan" : return 1; 12... 13 case "May" : return 5; 14... 15 case "Dec" : return 12; 16 } 17}

の、「...」のところを埋めたらできるのではないかなーという提案でした。

投稿2018/05/08 02:46

papinianus

総合スコア12705

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

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

koromo_t

2018/05/08 15:20 編集

回答、ありがとうございます! ・ほぉー! functionとは、式の途中で別の命令を経由?させるみたいな、  こういう使い方もできるのですね! 便利です! ・returnの部分?に名前を付けるには、  「return」部分を「var ~ =」にすればよいということを学習しました。 解説の「var dateObj = myfunction("May, 01, 2018 00:00AM");」は、 「dateObjはmyfunctionに”May, 01, 2018 00:00AM”を入れたものの答え」 という理解でよいのでしょうか? そういえば、前回の回答でいただいたスクリプトを使って、 セルに「=myFunction(A1)」と書いたら、A1を式に代入した答えが出てましたね! すみません、文章にしているうちに、ひとり納得してしまいました。 ---脇道 ほぉー、IFTTTには関数も入れられるのでしょうか? もしそうなら、いただいたスクリプトはとてもわかりやすいように思います。 最終的にはそうしてみようと思います! が、そのためには、あと時間部分をやっつけないと?いけないですね。 とりあえず区切り番号4から「11:57PM」という文字列を取得することをしました。 しかしこれだと、new Dateでは認識してくれないみたいなので、 文字数を数えてちぎって、hourとminとampmをそれぞれ定義?することにしました。 そして、「var date = new Date(year, month, day, hour, min);」というふうにくっつけました。 すると、とてもそれっぽいものが出来上がりました。 が、これでは、午前と午後の判定ができていませんよね。 あとはAMPM表記のところをどうするかなのですが、詰まりました。 なにかよい方法はありますでしょうか…。 スクリプトの現状を、質問文に追記したいと思います!(追記2) ---追記 IF関数かなにかで、もしampmがAMならそのままのhourを表示、 もしampmがPMならhourに12を足したものを表示、的な感じでいけるような気がしました。 もう少しで答えに辿り着けそうな…。ぐぬぬ。 ---追記2 …?!! あれっ、あれ、できたかもしれません…?! ちょ、ちょっと、質問文に追記3を追記したいと思います…! あとは、「=DateConverter({{CreatedAt}})」とIFTTTのレシピに書き込む想定で、 スクリプトを書き換えれば完成なのかもしれないです…? ---追記3 IFTTTのレシピに関数を書き込む想定でスクリプトを書き換え、 期待通りの結果を得ることにも成功しましたので、 質問文に追記4を追記したいと思います!
papinianus

2018/05/08 12:02 編集

「dateObjはmyfunctionに”May, 01, 2018 00:00AM”を入れたものの答え」 は合ってると思います。 おそらく、質問文の追記3でよいと思います。 (AMPMに悩まれたようですが、具体的なかきかたは様々ですが原理的にはAMなのかPMなのかを見て処理を分けることになります) 一応補足ですが、IFTTTはそれを文字列だと思っています。スプレッドシートがイコールで始まると関数だと思って処理してくれる(評価する)、ということだと思います。
koromo_t

2018/05/08 15:06

前回の質問に引き続き、お手伝いいただき、ありがとうございました! おかげさまで、複雑に思われた今回の件も、 少しずつ進めていくと、ゴールにたどり着くことが出来ました! とても助かりました! ありがとうございます!
koromo_t

2018/05/08 15:10

そしてこれは余談なのですが、 papinianusさんのハンドルネームの由来は、古代ローマの法学者の人ですか? どういう意味の言葉なのだろうと興味を引かれたので調べてみると、 そういう人がいることがわかりました。 パイナップルでもピーナッツでもなさそうだなとは思っていたのですが、 食べ物とはまったく違う、人名でした…(笑)。 もしよかったら、どうしてこの名前なのかとか、教えていただけると嬉しいです! もしよければですけども!
papinianus

2018/05/09 08:51 編集

ローマ法をかじったからです(「古代ローマの法学者の人」ではないけども「古代ローマ法学者の人」だからってことになりますかね)。javascript言語だけでなく、"ラテン語"のタグの質問もお待ちしています~
koromo_t

2018/05/09 09:30 編集

あっ、古代ローマ法学者の人、なるほど…。 なるほど、ローマ法…。聞いたことはあってもピンとこないやつです…(笑)。 ちなみにパピニアヌスさんのカラカラ帝?とのエピソード、深いですね。 ラテン語も同様ピンとこなかったのでちょっと調べてみたのですが、 なにやら難解であるということがわかりました…(笑)。 ラテン語のタグ…、ということは、 プログラミングをする上で、ラテン語を使う状況もあるのでしょうか…?(笑) あるいは、「実はこれラテン語なんだよ」的なこと…? あと、なぜアイコン画像がオレンジの断面?なのかも、聞いてみてもよいですか? 余談にも関わらず、ハテナがいっぱいのコメントになってしまい、すみません…。
papinianus

2018/05/10 04:24

ラテン語のタグはないと思います(プログラムと無関係です。言語という点で似てます) オレンジはテキトーです
koromo_t

2018/05/11 15:01

あっ、つまり、ラテン語の質問もしていいよ的な、 ある種のボケ?的なことだったんでしょうか…(笑)。 ラテン語で困るという状況がまずないわ(笑)的なツッコミを入れたくなる…?(笑) 違ったらすみません\(^o^)/ (言語という点で似てる、とは、文法とかそういう…?) しかし万が一、ラテン語で困ることがあったら、 そのときはよろしくお願いします(笑)。 というか、ラテン語を理解されるというのは、 その時点ですごいことなのではないかと思いました(笑)。 ではでは、余談にも付き合っていただき、ありがとうございました!
guest

0

方針としては、

  1. シート関数を探す
  2. 自分で関数を作る

ではないかと考えました。結論として後者となりました。

関数を探したのですが、そのまま(あるいはSUBSTITUTEでの置換)ではDATEVALUEには解釈できない形式のよう。正規表現(REGEXEXTRACT)をつかって加工してからDATEVALUEするには、月名が英語のため煩雑になるように思いました。
次に、下記みたいなものをスクリプトにして(スクリプトにしたものはスプレッドシートから関数として呼べます。セルに=myFunction(A1)など)利用する方法を考えました。(方針としての参考程度なので処理・名前とも適切に書き直してください)

javascript

1function myFunction(str) { 2 var parse = str.replace(",", "").split(" "); 3 return new Date(parse[2], ToMonth(parse[0]), parse[1]); 4} 5function ToMonth(str) { 6 switch(str) 7 { 8 case "May": return 4; 9 } 10}

---追記
質問での要望とは異なり↑では時間が無視されます。回答は「文字列を加工して、欲しい形式にして戻す関数を作る」という方針の提案とご理解ください。

投稿2018/05/07 07:34

編集2018/05/07 07:38
papinianus

総合スコア12705

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

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

koromo_t

2018/05/07 14:52 編集

回答ありがとうございます! 前回の質問のときもそうでしたが、丁寧に考えてくださってありがとうございます! これは、なかなかできることではないのではないかと思います。。。 私も、甘えぬよう頑張りたいと思います! では本題。 なるほど、このスクリプトを利用すれば、文字列から日付を抽出できますね! カンマを空白に置換して、空白で区切っているわけですね。 それで、区切り3番目と1番目と2番目をくっつけて、日付データにしている…。 そのあと、月の英名を数字に置き換えている。 あとは時間部分も抽出して(AMPM表記の部分がまたネックになりそうな気配ですが…;)、 先に作った日付データとくっつければ、私が期待している日時データの表記となりますね! なので、とりあえず、日付データを、「日付成形」という名前のシートの (lastRow,1)に書き込まれるようにしてはどうかと考えました。 追々、時間データを(lastRow,2)に書き込まれるようにして、 (lastRow,3)に、(lastRow,1)と(lastRow,2)をくっつけたデータを書き込まれるようにする。 …みたいな。 さっそくこのスクリプトを、GASに取り込もうと思って、ちょっと書いてみたのですが、 switchのあたりをどのように書けばよいのかと、詰まりました。 lastRow_hiduke_rangeにsetValueしたいと思うのですが…。 と、文章で書いてもよくわからないですし、 現状のスクリプトを見ていただきたいので、質問文に追記します! (ちなみにですが、先に述べていただいたシート関数に関しては、 どれも聞いたことがないものだったのですが、今回は使わない方向性ということですし、 とりあえず研究はしないでおこうと思います。。。)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問