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

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

ただいまの
回答率

90.76%

  • Google Apps Script

    719questions

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

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

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 232

koromo_t

score 50

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

function myFunction() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
  var sheet = spreadsheet.getSheetByName('生ログ');
  var sheet_hiduke = spreadsheet.getSheetByName('日付成形');

  // シート「生ログ」関連
  var lastRow = sheet.getLastRow();
  var lastRow_range = sheet.getRange(lastRow,1);
  var lastRow_val = sheet.getRange(lastRow,1).getValue();
  Logger.log(lastRow_val);

  // シート「日付成形」関連
  var lastRow_hiduke = sheet_hiduke.getLastRow();
  var lastRow_hiduke_range = sheet_hiduke.getRange(lastRow_hiduke,1);  // ←ここに日付を書き込みたい。

  var str = lastRow_val;
  Logger.log(str);  

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

function ToMonth(str) {
  switch(str)
  {
    case "May": return 4;
  }
}
}

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

function DateConverter() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();

  // シート「生ログ」関連  
  var sheet = spreadsheet.getSheetByName('生ログ');
  var lastRow = sheet.getLastRow();
  var lastRow_val = sheet.getRange(lastRow,1).getValue();
  Logger.log(lastRow_val);

  // シート「日付成形」関連
  var sheet_hiduke = spreadsheet.getSheetByName('日付成形');
  var lastRow_hiduke = sheet_hiduke.getLastRow();
  var lastRow_hiduke_range = sheet_hiduke.getRange(lastRow_hiduke,1);  // ←ここに日付を書き込みたい。

  var str = lastRow_val;
  Logger.log(str);  

 var year = str.split(" ")[2];
  Logger.log(year);
 var month = MonthNameToNumber(str.split(" ")[0]) - 1;//Dateを作るとき月は0はじまり
  Logger.log(month);
 var day = str.replace(",", "").split(" ")[1];
  Logger.log(day);
 var hour_min_ampm = str.split(" ")[4];
  Logger.log(hour_min_ampm);
 var hour = hour_min_ampm.slice(0,2);
  Logger.log(hour);
 var min = hour_min_ampm.slice(3,5);
  Logger.log(min); 
 var ampm = hour_min_ampm.slice(5,8);
  Logger.log(ampm);
 var date = new Date(year, month, day, hour, min);
  Logger.log(date);
 lastRow_hiduke_range.setValue(date);
}
function MonthNameToNumber(shortname) {
  switch(shortname) {
    case "January" : return 1;
    case "February" : return 2;
    case "March" : return 3;
    case "April" : return 4; 
    case "May" : return 5;
    case "June" : return 6;
    case "July" : return 7;
    case "August" : return 8;
    case "September" : return 9;
    case "October" : return 10;
    case "November" : return 11;
    case "December" : return 12;
  }
}

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

function DateConverter() {
  var spreadsheet = SpreadsheetApp.getActiveSpreadsheet();

  // シート「生ログ」関連  
  var sheet = spreadsheet.getSheetByName('生ログ');
  var lastRow = sheet.getLastRow();
  var lastRow_val = sheet.getRange(lastRow,1).getValue();
  Logger.log(lastRow_val);

  // シート「日付成形」関連
  var sheet_hiduke = spreadsheet.getSheetByName('日付成形');
  var lastRow_hiduke = sheet_hiduke.getLastRow();
  var lastRow_hiduke_range = sheet_hiduke.getRange(lastRow_hiduke,1);  // ←ここに日付を書き込みたい。

  var str = lastRow_val;
  Logger.log(str);  

 var year = str.split(" ")[2];
  Logger.log(year);
 var month = MonthNameToNumber(str.split(" ")[0]) - 1;//Dateを作るとき月は0はじまり
  Logger.log(month);
 var day = str.replace(",", "").split(" ")[1];
  Logger.log(day);
 var hour_min_ampm = str.split(" ")[4];
  Logger.log(hour_min_ampm);
 var hour = hour_min_ampm.slice(0,2);
  Logger.log(hour);
 var min = hour_min_ampm.slice(3,5);
  Logger.log(min); 
 var ampm = hour_min_ampm.slice(5,8);
  Logger.log(ampm);
 var date_AM = new Date(year, month, day, hour, min);
  Logger.log(date_AM);
 var hour_PM = date_AM.getHours()+12;
  Logger.log(hour_PM);
 if(ampm=="AM"){
 lastRow_hiduke_range.setValue(date_AM);
 }
 else{
 var date_PM = new Date(year, month, day, hour_PM, min);
  Logger.log(date_PM);
 lastRow_hiduke_range.setValue(date_PM);
 }
}
function MonthNameToNumber(shortname) {
  switch(shortname) {
    case "January" : return 1;
    case "February" : return 2;
    case "March" : return 3;
    case "April" : return 4; 
    case "May" : return 5;
    case "June" : return 6;
    case "July" : return 7;
    case "August" : return 8;
    case "September" : return 9;
    case "October" : return 10;
    case "November" : return 11;
    case "December" : return 12;
  }
}

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

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

function DateConverter(str) {
 var year = str.split(" ")[2];
  Logger.log(year);
 var month = MonthNameToNumber(str.split(" ")[0]) - 1;//Dateを作るとき月は0はじまり
  Logger.log(month);
 var day = str.replace(",", "").split(" ")[1];
  Logger.log(day);
 var hour_min_ampm = str.split(" ")[4];
  Logger.log(hour_min_ampm);
 var hour = hour_min_ampm.slice(0,2);
  Logger.log(hour);
 var min = hour_min_ampm.slice(3,5);
  Logger.log(min); 
 var ampm = hour_min_ampm.slice(5,8);
  Logger.log(ampm);
 var date_AM = new Date(year, month, day, hour, min);
  Logger.log(date_AM);
 var hour_PM = date_AM.getHours()+12;
  Logger.log(hour_PM);
 if(ampm=="AM"){
 return date_AM;
 }
 else{
 var date_PM = new Date(year, month, day, hour_PM, min);
  Logger.log(date_PM);
 return date_PM;
 }
}
function MonthNameToNumber(shortname) {
  switch(shortname) {
    case "January" : return 1;
    case "February" : return 2;
    case "March" : return 3;
    case "April" : return 4; 
    case "May" : return 5;
    case "June" : return 6;
    case "July" : return 7;
    case "August" : return 8;
    case "September" : return 9;
    case "October" : return 10;
    case "November" : return 11;
    case "December" : return 12;
  }
}

 追記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」を得ることができるはず。

function DateConverter(str) {
 var year = str.split(" ")[2];
  Logger.log(year);
 var month = MonthNameToNumber(str.split(" ")[0]) - 1;//Dateを作るとき月は0はじまり
  Logger.log(month);
 var day = str.replace(",", "").split(" ")[1];
  Logger.log(day);
 var hour_min_ampm = str.split(" ")[4];
  Logger.log(hour_min_ampm);
 var hour = hour_min_ampm.slice(0,2).replace("12", "0");
  Logger.log(hour);
 var min = hour_min_ampm.slice(3,5);
  Logger.log(min); 
 var ampm = hour_min_ampm.slice(5,8);
  Logger.log(ampm);
 var date_AM = new Date(year, month, day, hour, min);
  Logger.log(date_AM);
 var hour_PM = date_AM.getHours()+12;
  Logger.log(hour_PM);
 if(ampm=="AM"){
 return date_AM;
 }
 else{
 var date_PM = new Date(year, month, day, hour_PM, min);
  Logger.log(date_PM);
 return date_PM;
 }
}
function MonthNameToNumber(shortname) {
  switch(shortname) {
    case "January" : return 1;
    case "February" : return 2;
    case "March" : return 3;
    case "April" : return 4; 
    case "May" : return 5;
    case "June" : return 6;
    case "July" : return 7;
    case "August" : return 8;
    case "September" : return 9;
    case "October" : return 10;
    case "November" : return 11;
    case "December" : return 12;
  }
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

checkベストアンサー

+2

詰まっているところ、が私の推測になるのですが関数(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]の直前から再開している感じです。後でおきかえたのではなく、途中で置き換えが起こっています)

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

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


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

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

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


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

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


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

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

function DateConverter(str) {
 var year = str.split(" ")[2];
 var month = MonthNameToNumber(str.split(" ")[0]) - 1;//Dateを作るとき月は0はじまり
 var day = str.split(" ")[1];
 var hour = ...;
 var min = ...;
 return new Date(year, month, day, hour, min);
}
function MonthNameToNumber(shortname) {
  switch(shortname) {
    case "Jan" : return 1;
...
    case "May" : return 5;
...
    case "Dec" : return 12;
  }
}


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

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/08 19:01 編集

    回答、ありがとうございます!

    ・ほぉー! 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を追記したいと思います!

    キャンセル

  • 2018/05/08 20:57 編集

    「dateObjはmyfunctionに”May, 01, 2018 00:00AM”を入れたものの答え」
    は合ってると思います。

    おそらく、質問文の追記3でよいと思います。
    (AMPMに悩まれたようですが、具体的なかきかたは様々ですが原理的にはAMなのかPMなのかを見て処理を分けることになります)

    一応補足ですが、IFTTTはそれを文字列だと思っています。スプレッドシートがイコールで始まると関数だと思って処理してくれる(評価する)、ということだと思います。

    キャンセル

  • 2018/05/09 00:06

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

    キャンセル

  • 2018/05/09 00:10

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

    キャンセル

  • 2018/05/09 17:32 編集

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

    キャンセル

  • 2018/05/09 18:22 編集

    あっ、古代ローマ法学者の人、なるほど…。
    なるほど、ローマ法…。聞いたことはあってもピンとこないやつです…(笑)。
    ちなみにパピニアヌスさんのカラカラ帝?とのエピソード、深いですね。

    ラテン語も同様ピンとこなかったのでちょっと調べてみたのですが、
    なにやら難解であるということがわかりました…(笑)。
    ラテン語のタグ…、ということは、
    プログラミングをする上で、ラテン語を使う状況もあるのでしょうか…?(笑)
    あるいは、「実はこれラテン語なんだよ」的なこと…?

    あと、なぜアイコン画像がオレンジの断面?なのかも、聞いてみてもよいですか?
    余談にも関わらず、ハテナがいっぱいのコメントになってしまい、すみません…。

    キャンセル

  • 2018/05/10 13:24

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

    キャンセル

  • 2018/05/12 00:01

    あっ、つまり、ラテン語の質問もしていいよ的な、
    ある種のボケ?的なことだったんでしょうか…(笑)。
    ラテン語で困るという状況がまずないわ(笑)的なツッコミを入れたくなる…?(笑)
    違ったらすみません\(^o^)/
    (言語という点で似てる、とは、文法とかそういう…?)

    しかし万が一、ラテン語で困ることがあったら、
    そのときはよろしくお願いします(笑)。
    というか、ラテン語を理解されるというのは、
    その時点ですごいことなのではないかと思いました(笑)。

    ではでは、余談にも付き合っていただき、ありがとうございました!

    キャンセル

+2

方針としては、

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

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

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

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

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

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/07 23:11 編集

    回答ありがとうございます!
    前回の質問のときもそうでしたが、丁寧に考えてくださってありがとうございます!
    これは、なかなかできることではないのではないかと思います。。。
    私も、甘えぬよう頑張りたいと思います!
    では本題。

    なるほど、このスクリプトを利用すれば、文字列から日付を抽出できますね!
    カンマを空白に置換して、空白で区切っているわけですね。
    それで、区切り3番目と1番目と2番目をくっつけて、日付データにしている…。
    そのあと、月の英名を数字に置き換えている。

    あとは時間部分も抽出して(AMPM表記の部分がまたネックになりそうな気配ですが…;)、
    先に作った日付データとくっつければ、私が期待している日時データの表記となりますね!
    なので、とりあえず、日付データを、「日付成形」という名前のシートの
    (lastRow,1)に書き込まれるようにしてはどうかと考えました。
    追々、時間データを(lastRow,2)に書き込まれるようにして、
    (lastRow,3)に、(lastRow,1)と(lastRow,2)をくっつけたデータを書き込まれるようにする。
    …みたいな。

    さっそくこのスクリプトを、GASに取り込もうと思って、ちょっと書いてみたのですが、
    switchのあたりをどのように書けばよいのかと、詰まりました。
    lastRow_hiduke_rangeにsetValueしたいと思うのですが…。
    と、文章で書いてもよくわからないですし、
    現状のスクリプトを見ていただきたいので、質問文に追記します!

    (ちなみにですが、先に述べていただいたシート関数に関しては、
    どれも聞いたことがないものだったのですが、今回は使わない方向性ということですし、
    とりあえず研究はしないでおこうと思います。。。)

    キャンセル

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

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

同じタグがついた質問を見る

  • Google Apps Script

    719questions

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