В целом дорого сделать это. Для использования отражения класс должен быть загружен. Если Вы хотите загрузить каждый класс, доступный на пути к классу, который займет время и память и не рекомендуется.
, Если бы Вы хотите избежать этого, необходимо было бы реализовать собственный синтаксический анализатор файла класса, который работал более эффективно вместо отражения. Библиотека разработки кода байта может помочь с этим подходом.
механизм Поставщика услуг является стандартными средствами перечислить реализации сменного сервиса. Используйте ServiceLoader
в Java 6 или реализуйте свое собственное в более ранних версиях. Я обеспечил пример в другом ответе.
function daysInMonth(m, y) { // m is 0 indexed: 0-11
switch (m) {
case 1 :
return (y % 4 == 0 && y % 100) || y % 400 == 0 ? 29 : 28;
case 8 : case 3 : case 5 : case 10 :
return 30;
default :
return 31
}
}
function isValid(d, m, y) {
return m >= 0 && m < 12 && d > 0 && d <= daysInMonth(m, y);
}
Я делал это с помощью объекта Date (предполагая, что он скомпилирован и, следовательно, ослепляюще быстр по сравнению со сценарием).
Уловка в том, что если вы введете слишком большое число для date, объект Date переносится в следующий месяц. Итак:
var year = 2009;
var month = 1;
var date = 29;
var presumedDate = new Date(year, month, date);
if (presumedDate.getDate() != date)
WScript.Echo("Invalid date");
else
WScript.Echo("Valid date");
Это будет эхом "Invalid date", потому что presumedDate на самом деле 1 марта.
Это оставляет все проблемы високосных лет и т. Д. Объекту Date, о котором мне не нужно беспокоиться.
Хороший трюк, а? Грязно, но это сценарий для тебя ...
Это не будет работать так хорошо, как принятый ответ. Я добавил это сюда, потому что считаю, что это самый простой код. Большинству людей не нужно оптимизировать эту функцию.
function validateDaysInMonth(year, month, day)
{
if (day < 1 || day > 31 || (new Date(year, month, day)).getMonth() != month)
throw new Error("Frack!");
}
Он использует тот факт, что конструктор Date javascript будет выполнять арифметические операции с датами, выходящими за пределы диапазона, например, если вы это сделаете:
var year = 2001; //not a leap year!
var month = 1 //February
var day = 29; //not a valid date for this year
new Date(year, month, day);
объект вернет Mar Дата 1 января 2001 года.
Если месяц не февраль, получите число из массива. В противном случае проверьте, является ли год високосным для возврата 29 или для возврата 28. Есть ли здесь проблема?
function caldays(m,y)
{
if (m == 01 || m == 03 || m == 05 || m == 07 || m == 08 || m == 10 || m == 12)
{
return 31;
}
else if (m == 04 || m == 06 || m == 09 || m == 11)
{
return 30;
}
else
{
if ((y % 4 == 0) || (y % 400 == 0 && y % 100 != 0))
{
return 29;
}
else
{
return 28;
}
}
}
Я согласен с Моаядом и TED. Придерживайтесь таблицы поиска, если только не февраль. Если вам нужен алгоритм для проверки високосных лет, в википедии есть два :
if year modulo 400 is 0 then leap
else if year modulo 100 is 0 then no_leap
else if year modulo 4 is 0 then leap
else no_leap
A more direct algorithm (terms may be grouped either way):
function isLeapYear (year):
if ((year modulo 4 is 0) and (year modulo 100 is not 0)) or (year modulo 400 is 0)
then true
else false
Я в основном согласен с Моаядом. Я бы использовал поиск по таблице с проверкой if для февраля и года.
псевдокод:
Last_Day = Last_Day_Of_Month[Month];
Last_Day += (Month == February && Leap_Year(Year)) ? 1 : 0;
Обратите внимание, что Leap_Year () не может быть реализован просто как (Year% 4 == 0)
, потому что правила для високосных лет намного сложнее. Вот алгоритм , заимствованный из Википедии
bool Leap_Year (int year) {
return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
}
вся эта логика уже встроена в движок javascript ... Зачем ее перекодировать? Если вы не делаете это просто как упражнение, вы можете использовать объект Date javascript:
Примерно так:
function daysInMonth(aDate) {
return new Date(aDate.getYear(), aDate.getMonth()+1, 0).getDate();
}
Вы можете использовать DateTime, чтобы решить эту проблему:
new DateTime('20090901')->format('t'); // gives the days of the month
Предполагая, что стандарт объекта JS Date, в котором месяцы нумеруются от 0, и у вас есть массив daysInMonth:
var days = daysInMonth[month] + ((month === 1) && (year % 4 === 0) && ((year % 100 !== 0) || (year % 400 === 0)));
даст вам количество дней в месяце, с 28 увеличенным до 29, если месяц февраль и год. год високосный.