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

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

新規登録して質問してみよう
ただいま回答率
85.35%
JavaScript

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

Q&A

解決済

3回答

1601閲覧

JavaScriptで「X分前」を実装

curryrice

総合スコア2

JavaScript

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

0グッド

1クリップ

投稿2020/10/30 10:25

前提・実現したいこと

JavaScriptで、データベースにある「2020-10-30 12:00:00.000000」の形式の日付を「X分前」と変換したいです。
ただし、ブラウザ言語に沿った変換を求めています。

発生している問題・エラーメッセージ

エラーメッセージは特に出ていませんが、ブラウザ言語に沿った変換ができません。
おそらくですが問題は下記ソースコード21行目の「// ←ここがおかしい?」とある部分だと思います(違うかもしれません)。

該当のソースコード

データベースにあるのが「created_at」で、それを関数ago()で変換しようという意図です。

JavaScript

1// データベースにある値(INSERTしたときの標準時)であるcreated_atを「X分前」のように変換 2var created_at = '2020-10-30 12:00:00.000000'; 3console.log( 'ago =', ago(created_at) );

全体は次のようになります。

JavaScript

1// ブラウザ言語取得 2var BROWSER_LANG = document.getElementsByTagName('html')[0].getAttribute('data-lang'); 3var BROWSER_LANG = (window.navigator.languages && window.navigator.languages[0]) || 4 window.navigator.language || 5 window.navigator.userLanguage || 6 window.navigator.browserLanguage; 7console.log( 'BROWSER_LANG =', BROWSER_LANG ); 8 9// データベースにある値(INSERTしたときの標準時)であるcreated_atを「X分前」のように変換 10var created_at = '2020-10-30 12:00:00.000000'; 11console.log( 'ago =', ago(created_at) ); 12 13// 変換を実行 14function ago(created_at){ 15 var result; 16 17 // 日付オブジェクト 18 created_at = new Date(created_at); 19 var created_at_local = created_at.toLocaleString(BROWSER_LANG, { timeZone: 'UTC' }); 20 created_at_local = new Date(created_at_local); 21 console.log( 'created_at_local =', created_at_local ); // ←ここがおかしい? 22 23 // 現在時刻との差分=経過時間 24 var diff = new Date().getTime() - created_at_local.getTime(); 25 26 // 経過時間をDateに変換 27 var elapsed = new Date(diff); 28 29 // 大きい単位から順に表示 30 if (elapsed.getUTCFullYear() - 1970) { 31 result = elapsed.getUTCFullYear() - 1970 + '年前'; 32 } else if (elapsed.getUTCMonth()) { 33 result = elapsed.getUTCMonth() + 'ヶ月前'; 34 } else if (elapsed.getUTCDate() - 1) { 35 result = elapsed.getUTCDate() - 1 + '日前'; 36 } else if (elapsed.getUTCHours()) { 37 result = elapsed.getUTCHours() + '時間前'; 38 } else if (elapsed.getUTCMinutes()) { 39 result = elapsed.getUTCMinutes() + '分前'; 40 } else { 41 result = elapsed.getUTCSeconds() + 'たった今'; 42 } 43 return result; 44} 45

試したこと

先に申し上げましたように、上記ソースコード21行目の「// ←ここがおかしい?」とある部分をコンソールに出し、おかしいのではと思いました。

この21行目は
created_at = 2020-10-30 12:00:00.000000
から日本の「+9」を加味して
created_at_local = 2020-10-30 19:00:00.000000
となっているのが本来だと思うのですがしかし
created_at_local = 2020-10-30 03:00:00.000000
となっていて、つまり「-9」されてしまっているものと見えます。

変換が逆なのかと思い次のように逆転させるとエラーでした。

js

1var created_at_local = created_at.toLocaleString(BROWSER_LANG, { timeZone: 'UTC' }); 2// ↓逆転させるとエラー 3var created_at_local = created_at.toLocaleString('UTC', { timeZone: BROWSER_LANG });

補足情報(FW/ツールのバージョンなど)

変換はフロントで実装したく、ツールはPHPなどでなくJavaScriptを考えています。
宜しくお願い致します。

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

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

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

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

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

yambejp

2020/10/30 10:29

今の「X分前」?
curryrice

2020/10/30 11:28

「UTCであるcreated_atを、言語別にローカライズした日時」と「今」とを比較します。 なので仰るとおり、今の「X分前」でお間違えないかと思います。伝わりにくくて申し訳ございません。
guest

回答3

0

javascript

1var str="2020-10-30 12:00:00.000000"; 2var t1=new Date(str).getTime(); 3var t2=new Date().getTime(); 4var t3=(t2-t1)/1000/60; 5console.log(t3+"分前");

※更新

投稿2020/10/30 10:33

編集2020/10/30 11:30
yambejp

総合スコア116724

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

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

curryrice

2020/10/30 11:42

「str」と「今」の比較でしたら質問のコードで出来ています。 「UTCであるcreated_atを、言語別にローカライズした日時」と「今」との比較が出来ないというのが、「発生している問題・エラーメッセージ」にある通り問題になっていて、その解決を求めている状況です。
guest

0

yambejpさんのコードをお借りします。

js

1var str="2020-10-30 12:00:00.000000"; 2var now = new Date(); 3var t1=new Date(str).getTime() - now.getTimezoneOffset() * 60 * 1000; 4var t2=now.getTime(); 5var t3=(t2-t1)/1000/60; 6console.log(t3+"分前");

投稿2020/10/30 13:23

編集2020/10/30 13:35
plasticgrammer

総合スコア629

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

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

0

ベストアンサー

色々と気になるところはありますが、まず new Date もしくは Date.parse により文字列をDateに変換する場合、そのタイムゾーンに依存した変換になる気がします。

つまり「-9」されてしまっているものと見えます

上記の通り、文字列を日本時間として解釈した結果を標準時に直すと、9時間前になります。
標準時として解釈させる方法は何が適切かわからないので、別な方にお任せします。

逆転させるとエラー

toLocaleStringの第一引数は locale ですので、'UTC'ではなく'en-GB'ではないでしょうか。

わかる範囲でのコメントなので、中途半端になってしまいすみません。

投稿2020/10/30 12:30

編集2020/10/30 12:40
plasticgrammer

総合スコア629

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

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

curryrice

2020/10/30 12:40

'UTC'ではなく'en-GB'、というのはなるほどでした。 それでもエラーとなり、ログによれば'ja'が問題なようですが、かといってどうしたらいいのかという感じです。 'ja'でなく'Asia/Tokyo'としても「ago = 9時間前」でなく「ago = NaNたった今」となってしまいますし。
plasticgrammer

2020/10/30 12:54

まずやりたいことの確認をさせてください。 やりたいのは、下記①と②の差からX分前を編集する、だと理解しましたが正しいでしょうか。 ①ある文字列を標準時として解釈した日時 ②ブラウザで取得した現在日時 このロジックだと、時差がマイナスの場合、X分後の扱いとなりますが良いのでしょうか。
plasticgrammer

2020/10/30 12:58

それでも良いのでしたら、yambejpさんの回答に加えて、getTimezoneOffset()の結果を考慮してあげれば、上手くいくのではと思いました。
curryrice

2020/10/30 13:15

> このロジックだと、時差がマイナスの場合、X分後の扱いとなりますが良いのでしょうか はい、大丈夫だと思います。ロジック的にはそうですが、現実的にはそうならないためです。 まず今、世界のどこからデータベースにINSERTしても値はUTC±0が保存されます。 それを日本で出力する際に、今回の質問内容であるUTC+9を計算してこそ、「たった今」とできます。 同じようにUTC-9のアラスカでも同様に計算し「たった今」とできます。 もしこの質問の計算がない場合、日本ではUTC±0をそのまま出力することになるので「9時間前」となってしまいますし、アラスカでは「9時後」となってしまうわけです。 逆にplasticgrammer様でしたらこれ以外の方法で、「X分前」といった表示をどのように実現させますでしょうか。もし楽な方法があればぜひ教えてほしいです。
curryrice

2020/10/30 13:37 編集

> getTimezoneOffset ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.35%

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

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

質問する

関連した質問