mutation on the individual fields makes you have to transition through an invalid state
If you want to do this mutation-style for some reason, you should use the builder pattern (or whatever it's called). So in this case you'd instantiate a DateBuilder instance instead of a Date instance, and finally call .date() to get the actual Date instance from the builder instance.
Better yet, in this particular case, don't use the builder pattern, and instead just provide a sensible set of constructors with appropriate defaults for unspecified arguments (e.g., 00:00 for unspecified time).
For a simple date/time class, the builder pattern reeks of pointless overengineering.
Comments
If you want to do this mutation-style for some reason, you should use the builder pattern (or whatever it's called). So in this case you'd instantiate a DateBuilder instance instead of a Date instance, and finally call .date() to get the actual Date instance from the builder instance.
Better yet, in this particular case, don't use the builder pattern, and instead just provide a sensible set of constructors with appropriate defaults for unspecified arguments (e.g., 00:00 for unspecified time).
For a simple date/time class, the builder pattern reeks of pointless overengineering.
Oh certainly, didn't mean to imply it's great for a freaking date.
But I've seen the mutating pattern in other cases causing the weird state bug which could have avoided using a builder.