3

Have such a simple Java class:

    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);
    }
}

Which results in 2017-11-23T15:38 Can someone explain me, why a date is subtracted while year and months - doesn't?

Eugene
  • 93
  • 4

5 Answers5

4

Because each three method

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

returns an instance of Period class

Each time you call another method value in Period period gets overriden.

If say ofYears(1) return instance of Period class named a then ofMonths(2) also return a new instance and override he initial one. So, the last one remains and stored to the period variable.

That's why only the ofDays(3) is showing effect.

If you want to do the same you should try calling below method

`public static Period of(int years,
                        int months,
                        int days) 
Rahul Kumar
  • 362
  • 1
  • 7
2

It is simple.

Each of the methods, ofYears, ofMonths and ofDays return a new instance of period. So effectively your period is equal to Period.ofDays(3)

This is not a builder pattern, where you keep modifying the same instance.

In order to achieve what you need, this code will do the work:

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

prints out

2016-09-23T15:38
Abhinaba Chakraborty
  • 3,488
  • 2
  • 16
  • 37
1

Because it works like Period.ofDays(3) overridden every time since they are static method.

Use Period of(int years,int months,int days)

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

Or you can use withDays, withMonths, withYears like for chaining

Eklavya
  • 17,618
  • 4
  • 28
  • 57
1

Give a Man a Fish, and You Feed Him for a Day. Teach a Man To Fish, and You Feed Him for a Lifetime.

(It certainly goes for a woman too.)

I am trying to teach you to fish. I am explaining how to catch such an error without having to ask on Stack Overflow first.

Set up your IDE to warn you when you use an object (an instance) for calling a static method. That is whenever you do something like

    yourObject.someStaticMethod();

In my Eclipse your code gives this warning:

The static method ofDays(int) from the type Period should be accessed in a static way

This tells us that ofDays() is a static method, and therefore the result of the call is the same as calling Period.ofDays(3). Eclipse even offers to fix the problem for me:

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: How to debug small programs with many tips similar to the one I am giving here (and not because yours was a poor question, it’s a good one, I upvoted it).

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

Remember that all classes in the java.time package are immutable (see Java Docs). Instances of Period cannot be changed after creation, you will have to create a new instance and reassign it.

This is the reason why only the last Period.ofDays(3) has an effect on the result (as previous answers suggest). And it is also the reason why withDays returns a copy of the respective Period.

Sergio
  • 36
  • 4