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

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

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

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

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

Q&A

解決済

1回答

1267閲覧

moment.jsの期間の操作方法

kinoko8800

総合スコア16

JavaScript

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

React.js

Reactは、アプリケーションのインターフェースを構築するためのオープンソースJavaScriptライブラリです。

0グッド

0クリップ

投稿2020/07/09 06:25

実現したいこと

moment.jsを使って以下のように、2つの期間の差を求めて、残時間を抜き出したいと思っております。

所要時間 01:00:00
経過時間 00:10:00

所要時間 ー 経過時間 = 残時間
01:00:00 - 00:10:00 = 00:50:00

うまくいかないこと

上記の例のように二つの期間のformatがあっていいれば、差分は取れるのですが、、
以下のようにformatが違うため、うまく差分が取れないという状況です。
formatをコロンを使う方に統一してからmoment.jsで計算したいと思っています。

所要時間 01:00:00
経過時間 00h01m02s

format変更方法についてどなたかヒント頂けると幸いです。
宜しくお願い致します。

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

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

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

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

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

kei344

2020/07/09 06:49

ご自身で試されたコードを質問文に追記し、「何をしたときに」「どうなると思って」「どうなったのか」、コードのどの部分で詰まっているのかなどを具体的に追記されたほうがより回答が望めると思います。
kinoko8800

2020/07/10 08:22

ご指摘ありがとうございます。おっしゃる通りです。 次回から気を付けます。
guest

回答1

0

ベストアンサー

こんにちは
以下のようにするのはいかがでしょう?

javascript

1const timeRequired = moment('01:00:00', 'HH:mm:ss'); 2const timeElapsed = moment('00h01m02s', 'HHhmmmsss'); 3 4const timeRemaining = timeRequired.diff(timeElapsed, 'seconds'); 5 6console.log(timeRemaining); // => 3538

追記

上記のコードでやっていることは、

  • 今日の日付の1時0分0秒という日時を持ったmomentオブジェクトを作り、timeRequired に入れる。
  • 今日の日付の0時1分2秒という日時を持ったmomentオブジェクトを作り、timeElapsed に入れる。
  • 上記の2つの日時の差分を秒換算で、timeRemaining に得る。

というものです。ですので、timeRequiredtimeElapsed は日時を表すものであって、1時間や1分2秒だったりの時間幅を表しているわけではないです。この点がちょっとすっきりしないということであれば、時間幅を表すオブジェクトとして、より適切な

Durations
https://momentjs.com/docs/#/durations/

を使ったほうがよいかもしれません。以下はこれを使ったサンプルです。

ただしこの場合は、文字列の'01:00:00''00h01m02s' から、moment.duration() に渡すパラメータを作るところを自分で書く必要があります。

投稿2020/07/09 07:41

編集2020/07/10 06:47
jun68ykt

総合スコア9058

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

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

kinoko8800

2020/07/09 08:09 編集

ご丁寧にご回答ありがとうございます。 00h01m02sが以下のように変数に格納された状態で渡される場合はどうすればいいのでしょうか? time = moment("00h01m02s"); const timeRequired = moment('01:00:00', 'HH:mm:ss'); const timeElapsed = moment('time', 'HHhmmmsss'); const timeRemaining = timeRequired.diff(timeElapsed, 'seconds'); console.log(timeRemaining); // => NaN NaNが返ってきてしまいます。 変数に格納する部分で以下のようにフォーマットを指定する以外で何か方法があればご教示願いたいです。 const time = moment('00h01m02s','HHhmmmsss' );
jun68ykt

2020/07/09 08:27

コメントありがとうございます。 変数 time には、文字列 "00h01m02s" が入ってくるようにしておいて、 const timeElapsed = moment(time, 'HHhmmmsss'); とすればよいかと思います。以下その例です。 https://codepen.io/jun68ykt/pen/zYrjWwz?editors=0012
jun68ykt

2020/07/09 09:08

上記コメントの例では、kinoko8800さんの問題解決になっていないようでしたら、お手数ですが、またコメント頂ければと思います。
kinoko8800

2020/07/09 09:27

ありがとうございます。おかげさまで解決いたしましたorz ただちょっとあやふやなところがあるのでお聞きしたいのですが、 下記の例を見ると、別々のformatが指定されてmomentインスタンスを生成していると思うのですが、 日付や時間(期間)同士の計算を行うときはformatをそろえる必要はないのでしょうか? const timeRequired = moment('01:00:00', 'HH:mm:ss'); const timeElapsed = moment('00h01m02s', 'HHhmmmsss');
jun68ykt

2020/07/09 10:17 編集

> 日付や時間(期間)同士の計算を行うときはformatをそろえる必要はないのでしょうか? はい。必要ないです。 moment('01:00:00', 'HH:mm:ss') や、 moment('00h01m02s', 'HHhmmmsss') のようにして得られた2つのmomentオブジェクト同士の差を計算したり、比較したりする場合には、それらのmomentオブジェクトが生成されるときに与えた文字列が、ご質問の例でいえば 一方は '01:00:00' で、他方は '00h01m02s' というようにフォーマットが異なっていても問題ありません。ですので、回答に挙げているコードにある、差を秒で求める以下の行 const timeRemaining = timeRequired.diff(timeElapsed, 'seconds'); も、momentオブジェクトを作るときに与えた文字列のフォーマットがどうであったかには依存しないコードになっています。
kinoko8800

2020/07/09 16:53

なるほどです。formatは違っていてもいいのですね。 moment('01:00:00', 'HH:mm:ss') moment('00h01m02s', 'HHhmmmsss') のようにmomentオブジェクト生成時にformatを指定してあげないと、isValid()でfalseになるのはなぜなんですかね?
jun68ykt

2020/07/10 04:19

たとえば、以下 https://codepen.io/jun68ykt/pen/zYraYeP?editors=0012 のように const m = moment('01:00:00'); としてmomentオブジェクトをmに得ようとすると、以下で始まるwarningがコンソールに表示されると思います。 Deprecation warning: value provided is not a recognized RFC2822 or ISO format.・・・ この後、m に対して m.isValid() はおっしゃるとおりfalseになります。上記のwarningメッセージに value provided is not a recognized RFC2822 or ISO format. とあるとおり、与えられた文字列 '01:00:00' がRFC2822またはISOフォーマットとして認識できないので、正しい日時情報を保持したmomentオブジェクトが作られず、そのためにm.isValid() がfalseになります。 回答のコードのような moment('01:00:00', 'HH:mm:ss') ではなく、 moment('01:00:00') と、第2引数にフォーマット指定をしないで、第1引数の文字列からisValid()がtrueになるようなmomentオブジェクトが作られるためには、第1引数はどのような形式の文字列が許容されるかについては、以下に記載されています。 https://momentjs.com/docs/#/parsing/string/ 上記を読むと分かるとおり、第2引数で明示的にフォーマットを指定しない場合は、第1引数の文字列には、必ず、日付(年月日)の情報が含まれていなければならないです。 moment('01:00:00') というように、第1引数に日付を含まない時刻の文字列を与え、第2引数なしの場合、それを今日の日付のその時刻という日時を持つ(isValid()がtrueになる)momentオブジェクトを返してくれてもよさそうな気もしますが、そういう仕様にはなっていないということです。
jun68ykt

2020/07/10 04:46

moment.duration を使ったコードを追記しました。参考になれば幸いです。
kinoko8800

2020/07/10 08:20

ご丁寧かつ、分かりやすいご回答ありがとうございます。 momentオブジェクトを生成時に 第二引数に、formatを指定しない場合は、 第一引数には、有効な形式かつ日付情報を渡してあげる必要があるということですね。 よく分かりました!リンクもありがとうございます。非常に助かりました!
jun68ykt

2020/07/10 11:58

どういたしまして???? > 非常に助かりました! とのことでよかったです。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問