LocalDateTime класс в Java и Period - PullRequest
3 голосов
/ 12 июля 2020

Есть такой простой Java класс:

    public static void main(String[] args) {
      LocalDateTime dateTime = LocalDateTime.of(2017, 11, 26, 15, 38);
      Period period = Period.ofYears(1).ofMonths(2).ofDays(3);
      dateTime = dateTime.minus(period);
      System.out.println(dateTime);
    }
}

Результат: 2017-11-23T15:38 Может кто-нибудь объяснить мне, почему дата вычитается, а год и месяцы - нет?

Ответы [ 5 ]

4 голосов
/ 12 июля 2020

Поскольку каждый из трех методов

(ofYears (1) & ofMonths(2) & ofDays (3))

возвращает экземпляр класса Period

Каждый раз, когда вы вызываете другой метод, значение в Period period переопределяется.

Если, скажем, ofYears (1) возвращает экземпляр класса Period с именем a, то ofMonths(2) также возвращает новый экземпляр и отменяет исходный. Итак, последний остается и сохраняется в переменной period.

Вот почему только ofDays(3) показывает эффект.

Если вы хотите сделать то же самое, попробуйте позвонить ниже метод

`public static Period of(int years,
                        int months,
                        int days) 
2 голосов
/ 12 июля 2020

Это просто.

Каждый из методов ofYears, ofMonths и ofDays возвращает новый экземпляр периода. Таким образом, ваш период равен Period.ofDays (3)

Это не шаблон построения, где вы продолжаете изменять один и тот же экземпляр.

Для достижения что вам нужно, этот код выполнит работу:

    LocalDateTime dateTime = LocalDateTime.of(2017, 11, 26, 15, 38);
    Period period = Period.of(1, 2, 3);
    dateTime = dateTime.minus(period);
    System.out.println(dateTime);

распечатывает

2016-09-23T15:38
1 голос
/ 12 июля 2020

Дайте человеку волокно sh, и вы накормите его на день. Научите мужчину Fi sh, и вы накормите его на всю жизнь.

(Конечно, это касается и женщин.)

Я пытаюсь научить вас Fi sh. Я объясняю, как отловить такую ​​ошибку, не спрашивая сначала о переполнении стека.

Настройте свою среду IDE, чтобы она предупреждала вас, когда вы используете объект (экземпляр) для вызова метода stati c. То есть всякий раз, когда вы делаете что-то вроде

    yourObject.someStaticMethod();

В моем Eclipse ваш код выдает это предупреждение:

Метод stati c ofDays (int) из типа Period должен быть доступ к нему осуществляется путем c

Это говорит нам, что ofDays() является методом c stati, и поэтому результат вызова такой же, как и при вызове Period.ofDays(3). Eclipse даже предлагает решить эту проблему для меня:

enter image description here

After I click “Change access to static using Period (declaring type)”, that code line becomes:

    Period.ofYears(1).ofMonths(2);
    Period period = Period.ofDays(3);

Now I think you can see why you got the result you got.

So:

  1. Make sure your IDE is configured to issue such warnings. It doesn’t have to be Eclipse, other IDEs can do the same.
  2. Read those warnings when you get them and make sure you understand them. If you've skipped a warning once, if you get an unexpected result, go back and read the warning again. If you still need to ask on Stack Overflow, you're welcome of course, and consider including the text of that warning you didn't understand.

Others have nicely explained how to fix your code to give you your desired result. If Period.of(1, 2, 3) is a bit confusing because you can't tell what's years, months weeks and days, use Period.ofYears(1).plusMonths(2).plusDays(3), and everything is clear. It also resembles what you tried in the question.

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

1 голос
/ 12 июля 2020

Потому что он работает как Period.ofDays(3), переопределяемый каждый раз, поскольку они являются методом c stati.

Используйте Период (int лет, int месяцев, int дней)

dateTime = dateTime.minus(Period.of(1, 2, 3));

Или вы можете использовать withDays, withMonths, withYears как для цепочки

0 голосов
/ 12 июля 2020

Помните, что все классы в пакете java.time неизменяемы (см. Java Документы) . Экземпляры Period не могут быть изменены после создания, вам нужно будет создать новый экземпляр и переназначить его.

Это причина, по которой только последний Period.ofDays(3) влияет на результат (как предыдущие ответы предлагать). И это также причина, по которой withDays возвращает копию соответствующего Period.

...