Как я определяю, является ли данная дата Энным рабочим днем месяца?

Что такое NullPointerException?

Хорошим местом для начала является JavaDocs . Они охватывают это:

Брошено, когда приложение пытается использовать null в случае, когда требуется объект. К ним относятся:

  • Вызов метода экземпляра нулевого объекта.
  • Доступ или изменение поля нулевого объекта.
  • Выполнение длины null, как если бы это был массив.
  • Доступ или изменение слотов с нулевым значением, как если бы это был массив.
  • Бросать нуль, как если бы это было значение Throwable.

Приложения должны бросать экземпляры этого класса для указания других незаконных видов использования нулевого объекта.

blockquote>

Также, если вы попытаетесь использовать нулевую ссылку с synchronized, который также выдаст это исключение, за JLS :

SynchronizedStatement:
    synchronized ( Expression ) Block
  • В противном случае, если значение выражения равно null, NullPointerException.
blockquote>

Как это исправить?

Итак, у вас есть NullPointerException. Как вы это исправите? Возьмем простой пример, который выдает NullPointerException:

public class Printer {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer();
        printer.print();
    }
}

Идентифицирует нулевые значения

. Первый шаг - точно определить , значения которого вызывают исключение . Для этого нам нужно выполнить некоторую отладку. Важно научиться читать stacktrace . Это покажет вам, где было выбрано исключение:

Exception in thread "main" java.lang.NullPointerException
    at Printer.printString(Printer.java:13)
    at Printer.print(Printer.java:9)
    at Printer.main(Printer.java:19)

Здесь мы видим, что исключение выбрано в строке 13 (в методе printString). Посмотрите на строку и проверьте, какие значения равны нулю, добавив протоколирующие операторы или используя отладчик . Мы обнаруживаем, что s имеет значение null, а вызов метода length на него вызывает исключение. Мы видим, что программа перестает бросать исключение, когда s.length() удаляется из метода.

Трассировка, где эти значения взяты из

Затем проверьте, откуда это значение. Следуя вызовам метода, мы видим, что s передается с printString(name) в методе print(), а this.name - null.

Трассировка, где эти значения должны быть установлены

Где установлен this.name? В методе setName(String). С некоторой дополнительной отладкой мы видим, что этот метод вообще не вызывается. Если этот метод был вызван, обязательно проверьте порядок , что эти методы вызывают, а метод set не будет называться после методом печати. ​​

Этого достаточно, чтобы дать нам решение: добавить вызов printer.setName() перед вызовом printer.print().

Другие исправления

Переменная может иметь значение по умолчанию setName может помешать ему установить значение null):

private String name = "";

Либо метод print, либо printString может проверить значение null например:

printString((name == null) ? "" : name);

Или вы можете создать класс, чтобы name всегда имел ненулевое значение :

public class Printer {
    private final String name;

    public Printer(String name) {
        this.name = Objects.requireNonNull(name);
    }

    public void print() {
        printString(name);
    }

    private void printString(String s) {
        System.out.println(s + " (" + s.length() + ")");
    }

    public static void main(String[] args) {
        Printer printer = new Printer("123");
        printer.print();
    }
}

См. также:

Я все еще не могу найти проблему

Если вы попытались отладить проблему и до сих пор не имеете решения, вы можете отправить вопрос для получения дополнительной справки, но не забудьте включить то, что вы пробовали до сих пор. Как минимум, включите stacktrace в вопрос и отметьте важные номера строк в коде. Также попробуйте сначала упростить код (см. SSCCE ).

17
задан Bill the Lizard 16 September 2012 в 15:40
поделиться

6 ответов

Вы могли изменить проверку недели, таким образом, функция будет читать:

private bool NthDayOfMonth(DateTime date, DayOfWeek dow, int n){
  int d = date.Day;
  return date.DayOfWeek == dow && (d-1)/7 == (n-1);
}

, Кроме которого, это выглядит довольно хорошим и эффективным.

12
ответ дан 30 November 2019 в 13:28
поделиться

Здесь то, что MSDN должны сказать. Его VB, но это переводит легко.

1
ответ дан 30 November 2019 в 13:28
поделиться

В этот ответ , должен быть зеркально отражен следующий код:

// Complete the gap to the nth week
dt = dt.AddDays((nth - 1) * 7);

if(dt.Month != month)
{
// we skip to the next month, we throw an exception
throw new ArgumentOutOfRangeException(”The given month has less than ” nth.ToString() ” ”
day_of_the_week.ToString() “s”);
}
0
ответ дан 30 November 2019 в 13:28
поделиться

Похоже, что язык предоставляет методы даты/день для данной даты. Если кому-либо было интересно, можно считать приблизительно конгруэтность Zeller .

я не думаю, что это - то, что они хотели, чтобы Вы сделали, но Вы могли найти день недели первого дня месяца от этого. Теперь, когда я думал об этом, Вы могли найти день недели в течение данного дня как N и получить те 7 по модулю.

, О, ожидают, то, что Энное происшествие дня недели (как воскресенье) или как Энное рабочий день из месяца! Хорошо я вижу примеры.

, Возможно, это имело бы значение, если Вы могли бы создать дату такой как 1-й из месяца..

, Учитывая, что это Энное происшествие дня недели , и что Вы не можете играть с любым типом данных datetime, и что Вы имеете доступ к обоим получить день недели и получаете день функций месяца. В воскресенье был бы нуль?

1) Сначала, день недели должен был бы соответствовать дню данной недели.
2) N должен был бы быть по крайней мере 1 и самое большее 4.
3) день месяца расположился бы между n*7*dayOfWeek + 1 и n*7*dayOfWeek + 6 для того же n.
- Позволяют мне думать об этом. Если воскресенье было первым.. 0*7*0+1 = 1 и в субботу 6-е было бы 0*7*0+6.

Думают 1, и 3 выше достаточны, так как получить день функции месяца не должен нарушать 2.

(* first try, this code sucks *)

function isNthGivenDayInMonth(date : dateTime;
                              dow : dayOfWeek;
                              N : integer) : boolean;
    var B, A : integer (* on or before and after day of month *)
    var Day : integer (* day of month *)
    begin
    B := (N-1)*7 + 1; A := (N-1)*7 + 6;
    D := getDayOfMonth(date);
    if (dow <> getDayOfWeek(date) 
        then return(false)
        else return( (B <= Day) and (A >= Day) );
    end; (* function *)

Hope там не является ошибкой в этом lol!
[редактирование: суббота была бы 7-й, и верхняя граница выше (N-1)*7 + 7.]
Ваше решение похоже на него, соответствовал бы 2 различным неделям? Похож на него, всегда возвращал бы нуль в течение многих воскресений? Должен был сделать псевдокод в C#.. короткое замыкание & & похож на мой если.. эй не был должен в воскресенье первое соответствие для N = 1 в течение многих месяцев, которые запускаются в воскресенье?

 d/ 7 == n

, Который привел бы к (either 0 or 1)/7 == 1, который не может быть правильным! Ваш || выгоды (n-1) также, у Robert есть это. Пойдите с ответом Robert Wagner! Это - только 2 строки, короткий хорошо! Наличие (Day-1) mod 7
[редактирование: (Day-1) div 7] устраняет мои ненужные переменные и 2 строки установки.

Для записи это должно быть проверено на граничные случаи и т.д как какой, если бы 31-го августа было воскресенье или в субботу.
[редактирование: Должен был проверить конец недельного случая также.Прошу прощения!]

1
ответ дан 30 November 2019 в 13:28
поделиться

Ответ от этот веб-сайт . Копируйте/вставляйте здесь в случае, если тот сайт когда-либо теряется.

public static DateTime FindTheNthSpecificWeekday(int year, int month,int nth, System.DayOfWeek day_of_the_week)
{
    // validate month value
    if(month < 1 || month > 12)
    {
        throw new ArgumentOutOfRangeException("Invalid month value.");
    }

    // validate the nth value
    if(nth < 0 || nth > 5)
    {
        throw new ArgumentOutOfRangeException("Invalid nth value.");
    }

    // start from the first day of the month
    DateTime dt = new DateTime(year, month, 1);

    // loop until we find our first match day of the week
    while(dt.DayOfWeek != day_of_the_week)
    {
        dt = dt.AddDays(1);
    }

    if(dt.Month != month)
    {
        // we skip to the next month, we throw an exception
        throw new ArgumentOutOfRangeException(string.Format("The given month has less than {0} {1}s", nth, day_of_the_week));
    }

    // Complete the gap to the nth week
    dt = dt.AddDays((nth - 1) * 7);

    return dt;
}
8
ответ дан 30 November 2019 в 13:28
поделиться

Вы можете найти функцию, которая возвращает дату для n-го появления конкретного дня недели в любом месяце.

See http://chiragrdarji.wordpress.com/2010/08/23/find-second-saturday-and-fourth-saturday-of-month/

1
ответ дан 30 November 2019 в 13:28
поделиться
Другие вопросы по тегам:

Похожие вопросы: