जावास्क्रिप्ट के साथ एक महीने में दिनों की संख्या निर्धारित करने का सबसे अच्छा तरीका क्या है?


107

मैं इस फ़ंक्शन का उपयोग कर रहा हूं, लेकिन मैं जानना चाहता हूं कि इसे प्राप्त करने का सबसे कुशल और सटीक तरीका क्या है।

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

जवाबों:


200

function daysInMonth (month, year) { // Use 1 for January, 2 for February, etc.
  return new Date(year, month, 0).getDate();
}

console.log(daysInMonth(2, 1999)); // February in a non-leap year.
console.log(daysInMonth(2, 2000)); // February in a leap year.

दिन 0 पिछले महीने में आखिरी दिन है। क्योंकि महीने का निर्माणकर्ता 0-आधारित है, यह अच्छी तरह से काम करता है। हैक का एक सा है, लेकिन यह मूल रूप से आप 32 घटाकर क्या कर रहे हैं।


42
यह वाक्यविन्यास मुझे कुछ समय के लिए भ्रमित कर रहा है। जेएस पैटर्न का पालन करने के लिए, मैं इस तरह से चाल को लागू करने की सिफारिश करूंगा:return new Date(year, month + 1, 0).getDate();
fguillen

2
दुर्भाग्य से यह 1000 ईस्वी पूर्व की तारीखों के लिए विफल रहता है जहां आप केवल सेटफुलियर () का उपयोग करके वर्ष को सही ढंग से निर्धारित कर सकते हैं। इसे बुलेट प्रूफ बनाने के लिए नई तिथि (2000+ (वर्ष% 2000), माह, 0) .getDate ()
नोएल वाल्टर्स

4
मेरे भविष्य-स्व पर ध्यान दें: '+ 1' के साथ fugillen का समीकरण वर्ष 2014 होने पर 28 दिन देता है और महीना 1 है (जो, जावास्क्रिप्ट दिनांक-ऑब्जेक्ट में, फरवरी का मतलब है)। संभवत: कम से कम विस्मय के साथ जाना चाहते हैं। लेकिन फ्लाईस्वाट से क्या बढ़िया विचार है!
हैरी पेहोनेन

@ NoelWalters- आप सही हैं कि कुछ ब्राउज़र दो अंकों के वर्षों को 20 वीं सेंट्री में तारीखों में बदल देते हैं (इसलिए 100 ईस्वी सन् से पहले की तारीखें, 1000 ईस्वी पूर्व नहीं), हालाँकि आपका फिक्स उन ब्राउज़रों में सुधार नहीं करता है। दो अंकों वर्ष मज़बूती से स्थापित करने के लिए एक ही रास्ता उपयोग करने के लिए है setFullYear : var d=new Date();d.setFullYear(year, month, date);
रॉबग

1
क्या होगा अगर monthहै 12 ? क्या Dateकंस्ट्रक्टर को 0 से 11 तक मान नहीं लेना चाहिए ?
anddero

8

यदि आप इस फ़ंक्शन को अक्सर कहते हैं, तो बेहतर प्रदर्शन के लिए मूल्य को कैश करना उपयोगी हो सकता है।

यहाँ फ्लाईस्वाट के उत्तर का कैशिंग संस्करण है :

var daysInMonth = (function() {
    var cache = {};
    return function(month, year) {
        var entry = year + '-' + month;

        if (cache[entry]) return cache[entry];

        return cache[entry] = new Date(year, month, 0).getDate();
    }
})();

6
क्या आंतरिक C / C ++ दिनचर्या इतनी धीमी है कि इसके लिए कैशिंग की आवश्यकता है?
पीट एल्विन

1
@PeteAlvin यह कार्यान्वयन पर निर्भर करता है Date(इसलिए उस प्रश्न का कोई सार्वभौमिक उत्तर नहीं है) और कितनी बार आपका कोड dayInMonthसमान मूल्यों के साथ कॉल करेगा । तो एक ही समझदार उत्तर है: अपने कोड को प्रोफाइल करें और इसे बेंचमार्क करें!
dolmen

1
मुझें यह पसंद है! लेकिन एक नई वस्तु का उपयोग करने के बजाय cache, मैं उपयोग करता हूं localStorage
andrew

5

कुछ उत्तरों (अन्य प्रश्नों पर भी) में लीप-वर्ष की समस्याएं थीं या दिनांक-ऑब्जेक्ट का उपयोग किया गया था। हालाँकि Date object1 जनवरी 1970 के दोनों ओर जावास्क्रिप्ट के लगभग 285616 वर्ष (100,000,000 दिन) के कवर हैं, मुझे विभिन्न ब्राउज़रों में सभी प्रकार की अप्रत्याशित तारीख विसंगतियों (सबसे विशेष रूप से 0 से 99 वर्ष) से तंग किया गया था । मैं भी उत्सुक था कि इसकी गणना कैसे की जाए।

इसलिए मैंने सही ( प्रोलेप्टिक ग्रेगोरियन / एस्ट्रोनॉमिकल / आईएसओ 8601: 2004 (खंड 4.3.2.1) की गणना करने के लिए एक सरल और सबसे ऊपर, छोटा एल्गोरिथ्म लिखा है , इसलिए वर्ष मौजूद है और एक लीप वर्ष है और नकारात्मक वर्ष समर्थित हैं ) दिन की संख्या के लिए एक दिया महीना और साल। यह शॉर्ट-सर्किट बिटमास्क-मोडुलो लीपियर एल्गोरिथ्म (जेएस के लिए थोड़ा संशोधित) और सामान्य मॉड -8 महीने के एल्गोरिथ्म का उपयोग करता है। 0

ध्यान दें कि AD/BCसंकेतन में, वर्ष 0 AD / BC मौजूद नहीं है: इसके बजाय वर्ष 1 BCलीप-ईयर है!
यदि आपको बीसी नोटेशन की आवश्यकता है, तो पहले (अन्यथा सकारात्मक) वर्ष-मूल्य का एक वर्ष पहले घटाएं !! (या 1अगले वर्ष की गणना के लिए वर्ष घटाएं ।)

function daysInMonth(m, y){
  return m===2?y&3||!(y%25)&&y&15?28:29:30+(m+(m>>3)&1);
}
<!-- example for the snippet -->
<input type="text" value="enter year" onblur="
  for( var r='', i=0, y=+this.value
     ; 12>i++
     ; r+= 'Month: ' + i + ' has ' + daysInMonth(i, y) + ' days<br>'
     );
  this.nextSibling.innerHTML=r;
" /><div></div>

ध्यान दें, महीने 1-आधारित होने चाहिए!

ध्यान दें, यह एक अलग एल्गोरिथ्म है फिर मैंने अपने जावास्क्रिप्ट में जिस मैजिक नंबर लुकअप का इस्तेमाल किया है , वह साल के दिन (1 - 366) उत्तर की गणना करता है , क्योंकि यहां लीप-ईयर के लिए अतिरिक्त शाखा केवल फरवरी की जरूरत है।


4

भ्रम दूर करने के लिए मैं शायद महीने को आधार बनाऊंगा क्योंकि यह वर्तमान में 1 आधारित है।

function daysInMonth(month,year) {
    monthNum =  new Date(Date.parse(month +" 1,"+year)).getMonth()+1
    return new Date(year, monthNum, 0).getDate();
}

daysInMonth('feb', 2015)
//28

daysInMonth('feb', 2008)
//29

4

साथ moment.js आप DAYSINMONTH () विधि का उपयोग कर सकते हैं:

moment().daysInMonth(); // number of days in the current month
moment("2012-02", "YYYY-MM").daysInMonth() // 29
moment("2012-01", "YYYY-MM").daysInMonth() // 31


2

ईएस 6 सिंटेक्स

const d = (y, m) => new Date(y, m, 0).getDate();

रिटर्न

console.log( d(2020, 2) );
// 29

console.log( d(2020, 6) );
// 30

1
14 मौजूदा उत्तरों के साथ एक पुराने प्रश्न के नए उत्तर को जोड़ते समय यह ध्यान रखना महत्वपूर्ण है कि आपके उत्तर के प्रश्न का नया पहलू क्या है। यह सिर्फ ES6 सिंटैक्स है?
जेसन एलर

समझ गया। अब से उत्तर के संदर्भ में जोड़ देगा।
RASG

1
function numberOfDays(iMonth, iYear) {
         var myDate = new Date(iYear, iMonth + 1, 1);  //find the fist day of next month
         var newDate = new Date(myDate - 1);  //find the last day
            return newDate.getDate();         //return # of days in this month
        }

1

लीप वर्ष को ध्यान में रखते हुए:

function (year, month) {
    var isLeapYear = ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0);

    return [31, (isLeapYear ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
}

अच्छा लगा। देखने में आसान है। एक इनलाइन-मैप / तत्काल-कुंजी मूल्य के उपयोग के लिए [ertie] प्रोप।
कोडी

1

एक-लाइनर प्रत्यक्ष संगणना (कोई दिनांक ऑब्जेक्ट):

function daysInMonth(m, y) {//m is 1-based, feb = 2
   return 31 - (--m ^ 1? m % 7 & 1:  y & 3? 3: y % 25? 2: y & 15? 3: 2);
}

console.log(daysInMonth(2, 1999)); // February in a non-leap year
console.log(daysInMonth(2, 2000)); // February in a leap year

0-आधारित महीनों के साथ विविधता:

function daysInMonth(m, y) {//m is 0-based, feb = 1
   return 31 - (m ^ 1? m % 7 & 1:  y & 3? 3: y % 25? 2: y & 15? 3: 2);
}

1

यदि आप किसी दिनांक ऑब्जेक्ट के वर्तमान महीने में दिनों की संख्या चाहते हैं, तो निम्न विधि पर विचार करें:

Date.prototype.getNumberOfDaysInMonth = function(monthOffset) {
    if (monthOffset !== undefined) {
        return new Date(this.getFullYear(), this.getMonth()+monthOffset, 0).getDate();
    } else {
        return new Date(this.getFullYear(), this.getMonth(), 0).getDate();
    }
}

तो आप इसे इस तरह से चला सकते हैं:

var myDate = new Date();
myDate.getNumberOfDaysInMonth(); // Returns 28, 29, 30, 31, etc. as necessary
myDate.getNumberOfDaysInMonth(); // BONUS: This also tells you the number of days in past/future months!

1

एक पंक्ति में:

// month is 1-12
function getDaysInMonth(year, month){
    return month == 2 ? 28 + (year % 4 == 0 ? (year % 100 == 0 ? (year % 400 == 0 ? 1 : 0) : 1):0) : 31 - (month - 1) % 7 % 2;
}

1

चयनित उत्तर की तुलना में मारने पर थोड़ा हो सकता है :) लेकिन यहाँ यह है:

function getDayCountOfMonth(year, month) {
  if (month === 3 || month === 5 || month === 8 || month === 10) {
    return 30;
  }

  if (month === 1) {
    if (year % 4 === 0 && year % 100 !== 0 || year % 400 === 0) {
      return 29;
    } else {
      return 28;
    }
  }

  return 31;
};

console.log(getDayCountOfMonth(2020, 1));

मुझे यहाँ ऊपर कोड मिला: https://github.com/ElemeFE/element/blob/dev/src/utils/date-util.js

function isLeapYear(year) { 
  return ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0); 
};

const getDaysInMonth = function (year, month) {
  return [31, (isLeapYear(year) ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month];
};

console.log(getDaysInMonth(2020, 1));

मुझे यहाँ ऊपर कोड मिला: https://github.com/datejs/Datejs/blob/master/src/core.js


1

यदि आप किसी दिनांक चर को पारित करने जा रहे हैं तो यह उपयोगी हो सकता है

const getDaysInMonth = date =>
  new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();

daysInThisMonth = getDaysInMonth(new Date());

console.log(daysInThisMonth);


-1

शायद सबसे सुरुचिपूर्ण समाधान नहीं है, लेकिन समझने और बनाए रखने में आसान है; और, यह युद्ध-परीक्षण है।

function daysInMonth(month, year) {
    var days;
    switch (month) {
        case 1: // Feb, our problem child
            var leapYear = ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
            days = leapYear ? 29 : 28;
            break;
        case 3: case 5: case 8: case 10: 
            days = 30;
            break;
        default: 
            days = 31;
        }
    return days;
},
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.