Moment: .add()または.subtract()浮動小数点値を取得する方法ですか?

作成日 2015年06月20日  ·  3コメント  ·  ソース: moment/moment

moment().add(1, "months") // >> Mon Jul 20 2015 13:36:12 GMT+0200
moment().add(1.9, "months") // >> Mon Jul 20 2015 13:36:12 GMT+0200
// Excpected: Mon Aug 17 2015 09:34:37 GMT+0200

今のところ、私はしなければなりません:

var duration = moment.duration(1.9, "months"); 
var ms = duration.asMilliseconds();
var date = moment().add(ms, "ms");

これらのメソッドがfloat値を加算または減算できないのはなぜですか?

最も参考になるコメント

これは仕様によるものですが、おそらくドキュメントでより適切に説明できます。

時間、分、秒、またはミリ秒を加算または減算するときに小数を使用できますが、日またはそれより大きいコンポーネントを細分化することはできません。

その理由は、時間計算と日付計算の間に論理的な違いがあるためです。

時間計算は、UTCベースのタイムスタンプをインクリメントまたはデクリメントするだけの線形タイムスケールを想定しています。 これにより、DST遷移がリアルタイムで処理されます。 たとえば、米国のほとんどの場所では、DST移行のために2:00から3:00までの時間がスキップされたため、 2015-03-08T01:00:00に1時間を加えたものが2015-03-08T03:00:00ます。

日付の計算では、線形の時間スケールは使用されませんが、カレンダーの日付が使用されます。 同じ例を使用すると、23時間しか経過していなくても、 2015-03-08T01:00:00と1つの_day_は2015-03-09T01:00:00になります。 したがって、「日」とは、このコンテキストが一定の時間ではないため、それを細分化することは無意味です。 (半日は12時間後ですか、それともこの日の11.5時間後ですか?)

DSTがなくても、すべての月が30日であるとは限らず、すべての年が365日であるとは限らないことを考慮してください。 年を「追加する」とは、実際には「365日を追加する」という意味ではなく、「カレンダー上の位置を翌年の同じ月と日に進める」という意味です。 これにより、うるう年の2月29日に1年を追加したり、うるう年以外の年で終了したりする場合など、特定のあいまいさが生じます。 2月28日に着陸することを選択しますが、3月1日に着陸することも同様に有効です。

別の例として、8月31日プラス1か月マイナス1か月が8月30日であると考えてください。

日付の計算は、数学の通常の加算および減算の規則に従わないため、除算または乗算の演算も処理できず、1.9か月を加算することはできません。

別の見方をすれば、6月15日深夜+ 1.5か月の結果はどうなると思いますか? 次のいずれかが人間によって行われる可能性があります。

  • 2015-06-15T00:00 +(0.5 * 6月の30日)= 2015-06-30T00:00 +(1か月= 30日)= 2015-07-30T00:00
  • 2015-06-15T00:00 +(0.5 * 6月の30日)= 2015-06-30T00:00 +(1か月= 31日)= 2015-07-31T00:00
  • 2015-06-15T00:00 +1か月= 2015-07-15T00:00 +(0.5 * 7月の31日)= 2015-07-30T12:00
  • 2015-06-15T00:00 + [(6月と7月の61日/ 2 =これらの月の平均日数は30。5日)* 1.5か月= 45。 2015-07-30T18:00日] =

したがって、ここに4つの異なる答えがありますが、これらはすべて論理的な結果です。これが、日付の計算を行うときに単位を細分化できない理由です。

全てのコメント3件

これは仕様によるものですが、おそらくドキュメントでより適切に説明できます。

時間、分、秒、またはミリ秒を加算または減算するときに小数を使用できますが、日またはそれより大きいコンポーネントを細分化することはできません。

その理由は、時間計算と日付計算の間に論理的な違いがあるためです。

時間計算は、UTCベースのタイムスタンプをインクリメントまたはデクリメントするだけの線形タイムスケールを想定しています。 これにより、DST遷移がリアルタイムで処理されます。 たとえば、米国のほとんどの場所では、DST移行のために2:00から3:00までの時間がスキップされたため、 2015-03-08T01:00:00に1時間を加えたものが2015-03-08T03:00:00ます。

日付の計算では、線形の時間スケールは使用されませんが、カレンダーの日付が使用されます。 同じ例を使用すると、23時間しか経過していなくても、 2015-03-08T01:00:00と1つの_day_は2015-03-09T01:00:00になります。 したがって、「日」とは、このコンテキストが一定の時間ではないため、それを細分化することは無意味です。 (半日は12時間後ですか、それともこの日の11.5時間後ですか?)

DSTがなくても、すべての月が30日であるとは限らず、すべての年が365日であるとは限らないことを考慮してください。 年を「追加する」とは、実際には「365日を追加する」という意味ではなく、「カレンダー上の位置を翌年の同じ月と日に進める」という意味です。 これにより、うるう年の2月29日に1年を追加したり、うるう年以外の年で終了したりする場合など、特定のあいまいさが生じます。 2月28日に着陸することを選択しますが、3月1日に着陸することも同様に有効です。

別の例として、8月31日プラス1か月マイナス1か月が8月30日であると考えてください。

日付の計算は、数学の通常の加算および減算の規則に従わないため、除算または乗算の演算も処理できず、1.9か月を加算することはできません。

別の見方をすれば、6月15日深夜+ 1.5か月の結果はどうなると思いますか? 次のいずれかが人間によって行われる可能性があります。

  • 2015-06-15T00:00 +(0.5 * 6月の30日)= 2015-06-30T00:00 +(1か月= 30日)= 2015-07-30T00:00
  • 2015-06-15T00:00 +(0.5 * 6月の30日)= 2015-06-30T00:00 +(1か月= 31日)= 2015-07-31T00:00
  • 2015-06-15T00:00 +1か月= 2015-07-15T00:00 +(0.5 * 7月の31日)= 2015-07-30T12:00
  • 2015-06-15T00:00 + [(6月と7月の61日/ 2 =これらの月の平均日数は30。5日)* 1.5か月= 45。 2015-07-30T18:00日] =

したがって、ここに4つの異なる答えがありますが、これらはすべて論理的な結果です。これが、日付の計算を行うときに単位を細分化できない理由です。

この非常に詳細な回答を書くために時間を割いていただきありがとうございます。 これらの関数の操作の背後にあるロジックをよりよく理解しています。

マットに感謝したことで自分自身に抵抗できませんでした。デルガンが経験したのと同じ問題を乗り越えて、仲間になりました。 あなたの答えはとても完全です、ありがとう。

このページは役に立ちましたか?
0 / 5 - 0 評価