JavaScriptで月の最終日を計算する


277

0として提供する場合、前月の最終日を取得dayValueDate.setFullYearます。

d = new Date(); d.setFullYear(2008, 11, 0); //  Sun Nov 30 2008

mozillaでこの動作への参照があります。これは信頼できるクロスブラウザ機能ですか、それとも別の方法を検討する必要がありますか?


指定した月の最後の日ということですか?11月は30日、10月は31日です。
Chris Serra、

16
月はJavaScriptでゼロベースなので、11は12月
グレッグは

2
@TheCloudlessSky-コンソールで試してみてください...(2008,11,0)は12月のゼロ日なので、11月の最終日
Ken

@ケン-ええ-「0」があることに気づかなかった:)...早すぎた
TheCloudlessSky

回答:


425
var month = 0; // January
var d = new Date(2008, month + 1, 0);
alert(d); // last day in January

IE 6:                     Thu Jan 31 00:00:00 CST 2008
IE 7:                     Thu Jan 31 00:00:00 CST 2008
IE 8: Beta 2:             Thu Jan 31 00:00:00 CST 2008
Opera 8.54:               Thu, 31 Jan 2008 00:00:00 GMT-0600
Opera 9.27:               Thu, 31 Jan 2008 00:00:00 GMT-0600
Opera 9.60:               Thu Jan 31 2008 00:00:00 GMT-0600
Firefox 2.0.0.17:         Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Firefox 3.0.3:            Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Google Chrome 0.2.149.30: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)
Safari for Windows 3.1.2: Thu Jan 31 2008 00:00:00 GMT-0600 (Canada Central Standard Time)

出力の違いはtoString()、日付の違いではなく、実装の違いによるものです。

もちろん、上記で特定されたブラウザが前月の最終日として0を使用しているからといって、継続することを意味するわけではありません。すべてのブラウザで同じように。


19
それは完全にうまくいくようです。好奇心から、これらすべてのエンジンでJavaScriptを実行するために何を使用していますか?すべてのセットアップまたは何らかのツールを手に入れましたか?
ネオンスキー2008年

5
実際の日を取得するには、d.getDate()を使用できます。
rynop

35
「ブラウザが…前月の最終日として0を使用しているからといって、継続して使用することを意味するわけではありません。」はい、あります。ECMA-262でそうする必要があります。
RobG 2014

3
使用new Dateは他の計算方法よりも非常に遅いため、パフォーマンスチャートにも表示されないことに注意してください:jsperf.com/days-in-month-perf-test/6
Gone Coding

4
Chrome 48.0.2564.116では動作しません。おそらく、この方法は「標準」ではなくなったのでしょう。
xarlymg89 2016

77

次の月の最初の日で中間日付を使用し、前日の日付を返します。

int_d = new Date(2008, 11+1,1);
d = new Date(int_d - 1);

ECMAScript仕様によると、指摘したとおりに「Date」コンストラクターを使用することは有効です。「MakeDay」関数で指定されたアルゴリズムに従って、問題を適切に処理する必要があります。
Pablo Cabrera、

1
これがIMOの最良のソリューションです。受け入れられた回答を試しましたが、今月の最後を取得するときにいくつかのバグがあります。今日の日付を返します。それがなぜ起こるのかわからない。
Gogol 2014年

1
バグを再現できません。これは、すべてのブラウザで私に正しい日付を与える:today = new Date(); new Date(today.getFullYear(), today.getMonth()+1, 0).toString();
orad

これにより、最後のミリ秒に設定された時刻(つまり23:59:59.999)で、月の最後の日のDateオブジェクトが作成されます。OPでメソッドを使用して、追加のステップと日付オブジェクトを保存することをお勧めします。
RobG 2014

@RobG:同意する!ただし、月の最終日に0を使用するという考えは、私の意見では少し不格好に感じられるため、私の解決策は理解しやすいかもしれません。
karlipoppins 2014年

72

これが私にとって最良の解決策であると思います。Dateオブジェクトに計算させてください。

var today = new Date();
var lastDayOfMonth = new Date(today.getFullYear(), today.getMonth()+1, 0);

dayパラメータを0に設定すると、前月の最終日である月の最初の日よりも1日少なくなります。


1
大丈夫です。選択した回答が同じことを示唆していることに気付きました。これは、最も高速で信頼性の高い方法であり、カレンダーの種類に関係なく機能します。たとえば、日付がグレゴリオ暦以外のものを実装した場合でも、それは機能します。Dateオブジェクトの非グレゴリオ暦実装の例については、intldate.codeplex.comを参照してください。
orad

1
@orad:この方法は実際には一部の代替手段よりもかなり遅いため何かが「最も速い」と主張する場合注意してください。使用new Date非常に遅いため、パフォーマンスチャートにも表示されませんjsperf.com/days-in-month-perf-test/6
Gone Coding

@TrueBlueAussie OKです。それがネイティブだったので、それはより速いと思いました。しかし、あなたは正しい、それは速くはありません。実際にテストしていただきありがとうございます。とにかく、このソリューションは簡潔で読みやすく、他のすべてのソリューションとは異なり、グレゴリオ暦にバインドされていないため、私にとって最も効果的です。
orad

「他のすべてのソリューションがグレゴリオ暦にバインドされていないのとは異なります」!!! このアルゴリズムは、1〜4000年の間、私のものと同じ値を返します。jsfiddle.net/2973x9m3/3これがサポートすると主張する追加の日付範囲は何ですか(それは役に立ちます)?:)
Gone Coding

1
ネイティブJS日付はグレゴリオ暦のみを使用します。ただし、他の実装でモックアップして、他の種類のカレンダーを取得することもできます。たとえば、IntlDateを参照してください。Dateオブジェクトを使用して月次ビューを作成する日付ピッカーがある場合、同じインターフェイスを持つ限り、どのDate実装(ネイティブまたはモック)を使用しているかは関係ありません。したがって、共有インターフェースを使用すると、各カレンダーの月の日数を知らなくても、異なる種類のカレンダーを切り替えることができます。
orad

25

コンピュータの観点から、new Date()そしてregular expression解決策は遅いです!あなたは超高速(超不可解な)ワンライナーをしたい場合は、仮定(これを試してみてくださいmですJan=1フォーマットがます)。最高のパフォーマンスを得るために、さまざまなコードの変更を試み続けています。

私の現在の最速バージョン:

この関連する質問うるう年チェックをビットごとの演算子(驚異的な速度)を使用して確認し、25と15のマジックナンバーが何を表しているかを発見した後、この最適化された答えの組み合わせを思いつきました。

function getDaysInMonth(m, y) {
    return m===2 ? y & 3 || !(y%25) && y & 15 ? 28 : 29 : 30 + (m+(m>>3)&1);
}

ビットシフトを考えると、これは明らかにあなたのmy文字列として数値を渡すと奇妙な結果が生じるためパラメーターが両方とも整数である。

JSFiddle: http ://jsfiddle.net/TrueBlueAussie/H89X3/22/

JSPerfの結果: http

何らかの理由で、(m+(m>>3)&1)より効率的である(5546>>m&1)、ほぼすべてのブラウザ。

速度に関する唯一の真の競争は@GitaarLabからのものであるため、私はテストするための直接のJSPerfを作成しました:http ://jsperf.com/days-in-month-head-to-head/5


ここで私のうるう年の答えに基づいて機能します:ここでうるう年を見つけるためのjavascriptここでうるう年を見つけるビットワイズ演算子(驚異的な速度)と次のバイナリロジックを使用しうるう年チェック

バイナリ月の簡単なレッスン:

目的の月(Jan = 1)のインデックスをバイナリで解釈すると、31日の月のビット3がクリアでビット0が設定されているか、ビット3がセットでビット0がクリアであることがわかります。

Jan = 1  = 0001 : 31 days
Feb = 2  = 0010
Mar = 3  = 0011 : 31 days
Apr = 4  = 0100
May = 5  = 0101 : 31 days
Jun = 6  = 0110
Jul = 7  = 0111 : 31 days
Aug = 8  = 1000 : 31 days
Sep = 9  = 1001
Oct = 10 = 1010 : 31 days
Nov = 11 = 1011
Dec = 12 = 1100 : 31 days

手段はあなたが値3つの場所をシフトすることができる>> 3、XORオリジナルとビット^ mと結果があるかどう1か、0 ビット位置0に使用& 1。注:+XOR(^)よりもわずかに速く(m >> 3) + m、ビット0でも同じ結果が得られます。

JSPerfの結果http : //jsperf.com/days-in-month-perf-test/6



1
@GitaarLAB:あなたはすでに言及がありますが、ご存知のように、これはあなたのものとまったく同じではありませんでした。他の各アルゴリズムの増分更新は、「元のアルゴ」と同じではありません。私もこの回答に多くの労力を費やしました:P
Gone Coding

@TrueBlueAussie:私は将来の読者に私たちのより多くの情報の宝物を紹介したかっただけです(私は両方の答えをリンクしたので、それを気にしたり、もう一度やりたい人は私たちが編集履歴を見ていつをしたのなぜそうしたのを確認できます)。私は一日中競技をしたことを今でも覚えています。:)私が投稿した最初の回答バージョンには、実際には不要なブラケットのセットがありましたが、削除されたので(私があなたに貸し付けました)、キャラクターを剃り、これで終わりました。あの楽しい日はまだありがたい、乾杯!
GitaarLAB

1
ことを明記してくださいym、変数が整数でない文字列でなければなりません!たとえば、2月の場合は30を返します。これをparseInt()機能させるには関数を使用する必要がありました。
代わりに


16

lebreezeが提供するソリューションを少し変更します。

function daysInMonth(iMonth, iYear)
{
    return new Date(iYear, iMonth, 0).getDate();
}

これはreturn new Date(iYear, 1 + iMonth, 0).getDate();、@ lebreezeのソリューションと同等になるはずです。
Moos

6

私は最近同様のことをしなければなりませんでした、これは私が思いついたものです:

/**
* Returns a date set to the begining of the month
* 
* @param {Date} myDate 
* @returns {Date}
*/
function beginningOfMonth(myDate){    
  let date = new Date(myDate);
  date.setDate(1)
  date.setHours(0);
  date.setMinutes(0);
  date.setSeconds(0);   
  return date;     
}

/**
 * Returns a date set to the end of the month
 * 
 * @param {Date} myDate 
 * @returns {Date}
 */
function endOfMonth(myDate){
  let date = new Date(myDate);
  date.setMonth(date.getMonth() +1)
  date.setDate(0);
  date.setHours(23);
  date.setMinutes(59);
  date.setSeconds(59);
  return date;
}

日付を渡すと、月初または月末のいずれかに設定された日付が返されます。

begninngOfMonth機能はかなり自明ですが、どのようにして起こっているendOfMonth機能は、私は次の月に月をインクリメントした後、使用しているということですsetDate(0)の一部であり、前月の最後の日に日ロールバックしますsetDate仕様:

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/setDate https://www.w3schools.com/jsref/jsref_setdate.asp

次に、時間/分/秒を1日の終わりに設定します。これにより、日付範囲を想定しているある種のAPIを使用している場合、その最終日の全体をキャプチャできるようになります。その部分は、元の投稿が求めているものを超える可能性がありますが、同様の解決策を探している誰かを助けることができます。

編集:setMilliseconds()さらに正確にしたい場合は、さらに1マイル進んでミリ秒を設定することもできます。


4

これを試してみてください。

lastDateofTheMonth = new Date(year, month, 0)

例:

new Date(2012, 8, 0)

出力:

Date {Fri Aug 31 2012 00:00:00 GMT+0900 (Tokyo Standard Time)}

5
ただし、その月はゼロベースであるため、月は実際には8月ではなく9月であるため、「8」を渡すことを忘れないでください。
スティーブJ

3

これは私にとってはうまくいきます。指定された年と月の最後の日を提供します:

var d = new Date(2012,02,0);
var n = d.getDate();
alert(n);

1
"2"の前の0は8進数として解釈されるので注意してください。
Walfrat

1

これはうまくいきます:

Date.prototype.setToLastDateInMonth = function () {

    this.setDate(1);
    this.setMonth(this.getMonth() + 1);
    this.setDate(this.getDate() - 1);

    return this;
}

1

これにより、現在の月が最初と最後の日になります。

「年」を変更する必要がある場合は、d.getFullYear()を削除して年を設定します。

「月」を変更する必要がある場合は、d.getMonth()を削除して年を設定します。

var d = new Date();
var days = ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"];
var fistDayOfMonth = days[(new Date(d.getFullYear(), d.getMonth(), 1).getDay())];
	var LastDayOfMonth = days[(new Date(d.getFullYear(), d.getMonth() + 1, 0).getDay())]; 
console.log("First Day :" + fistDayOfMonth); 
console.log("Last Day:" + LastDayOfMonth);
alert("First Day :" + fistDayOfMonth); 
alert("Last Day:" + LastDayOfMonth);


1

これを試して:

function _getEndOfMonth(time_stamp) {
    let time = new Date(time_stamp * 1000);
    let month = time.getMonth() + 1;
    let year = time.getFullYear();
    let day = time.getDate();
    switch (month) {
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
            day = 31;
            break;
        case 4:
        case 6:
        case 9:
        case 11:
            day = 30;
            break;
        case 2:
            if (_leapyear(year))
                day = 29;
            else
                day = 28;
            break
    }
    let m = moment(`${year}-${month}-${day}`, 'YYYY-MM-DD')
    return m.unix() + constants.DAY - 1;
}

function _leapyear(year) {
    return (year % 100 === 0) ? (year % 400 === 0) : (year % 4 === 0);
}

1

以下の関数は、月の最終日を示します。

function getLstDayOfMonFnc(date) {
  return new Date(date.getFullYear(), date.getMonth(), 0).getDate()
}

console.log(getLstDayOfMonFnc(new Date(2016, 2, 15))) // Output : 29
console.log(getLstDayOfMonFnc(new Date(2017, 2, 15))) // Output : 28
console.log(getLstDayOfMonFnc(new Date(2017, 11, 15))) // Output : 30
console.log(getLstDayOfMonFnc(new Date(2017, 12, 15))) // Output : 31

同様に、月の最初の日を取得できます。

function getFstDayOfMonFnc(date) {
  return new Date(date.getFullYear(), date.getMonth(), 1).getDate()
}

console.log(getFstDayOfMonFnc(new Date(2016, 2, 15))) // Output : 1


0
function getLastDay(y, m) {
   return 30 + (m <= 7 ? ((m % 2) ? 1 : 0) : (!(m % 2) ? 1 : 0)) - (m == 2) - (m == 2 && y % 4 != 0 || !(y % 100 == 0 && y % 400 == 0)); 
}

0
const today = new Date();

let beginDate = new Date();

let endDate = new Date();

// fist date of montg

beginDate = new Date(

  `${today.getFullYear()}-${today.getMonth() + 1}-01 00:00:00`

);

// end date of month 

// set next Month first Date

endDate = new Date(

  `${today.getFullYear()}-${today.getMonth() + 2}-01 :23:59:59`

);

// deducting 1 day

endDate.setDate(0);

0

日付を指定する必要がある月を設定し、日をゼロに設定します。そのため、月は日付関数で1〜31で始まり、最後の日を取得します^^

var last = new Date(new Date(new Date().setMonth(7)).setDate(0)).getDate();
console.log(last);


0

これは、最初の日付のGMTと時刻を保存する答えです

var date = new Date();

var first_date = new Date(date); //Make a copy of the date we want the first and last days from
first_date.setUTCDate(1); //Set the day as the first of the month

var last_date = new Date(first_date); //Make a copy of the calculated first day
last_date.setUTCMonth(last_date.getUTCMonth() + 1); //Add a month
last_date.setUTCDate(0); //Set the date to 0, this goes to the last day of the previous month

console.log(first_date.toJSON().substring(0, 10), last_date.toJSON().substring(0, 10)); //Log the dates with the format yyyy-mm-dd


0

私はそれが意味論の問題であることを知っていますが、私はこの形でそれを使用することになりました。

var lastDay = new Date(new Date(2008, 11+1,1) - 1).getDate();
console.log(lastDay);

関数は内側の引数から外側に向かって解決されるため、同じように機能します。

その後、年、月/年を現在の日付からのものであるかどうかにかかわらず、必要な詳細で置き換えることができます。または特定の月/年。


0

ミリ秒単位の正確な月末が必要な場合(タイムスタンプなど):

d = new Date()
console.log(d.toString())
d.setDate(1)
d.setHours(23, 59, 59, 999)
d.setMonth(d.getMonth() + 1)
d.setDate(d.getDate() - 1)
console.log(d.toString())

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.