Hi Guillaume,
Let me see if I can help:
On Thu, Jan 5, 2017 at 2:58 PM, Guillaume Smet <guillaume.smet(a)gmail.com>
wrote:
1. Support for partials
================
The initial proposal of Michael included the support for partials such as
YearMonth or MonthDay (ie types which do not strictly represent a point in
time).
While @Past and @Future make sense for YearMonth, it's a bit more
difficult to define them for MonthDay.
The implementation we committed indeed supports MonthDay by building a
MonthDay from the Clock provided by the ClockProvider and comparing them
using MonthDay.compare(...).
We tried to think of a use case but couldn't think of any.
When you are using a calendar year for fiscal purposes (in Brazil, its
January-December), you could use MonthDay to represent a point in time
separately from the year. If a MonthDay represents a holiday, there might
be other use cases related to the current year.
That being said, it does not cost us anything to have it for consistency.
Consistency for me is a good argument in itself. If we couldn't think of
the use case, maybe it's just because we're temporarily blind. Being
consistent doesn't hurt, especially given the effort is minimum :-)
2. Resolution
==========
In the comments of
https://hibernate.atlassian.net/browse/HV-820, someone
suggested the idea of resolution.
You could have something like:
@Future(resolution = ChronoUnit.MONTHS)
private LocalDate paymentDate;
This would truncate the LocalDates to ChronoUnit.MONTHS before doing the
comparison, ensuring that the date should be at least next month.
While this is a valid use case, it seems a little bit specific to me in the
sense you have a reference for "now" as a comparison (a use case I
mentioned before is validating a temporal object against an arbitrary
reference) and in this case converting it. This also limits the
"truncation" (which is just a specific case of conversion) to ChronoUnit,
when other types of conversion might be needed.
This can be handled by doing:
@Future
private YearMonth paymentYearMonth() {
return YearMonth.from(paymentDate);
}
Which is trivial.
A more interesting use case that remains unsupported, of which the previous
is kind of a specialization is: I have a startDate and an endDate and there
is no simple way to express that endDate must be greater or equal than
startDate. That would apply to any Comparable, by the way :-( If we are to
pursue something more advanced, that's the use case I'd suggest going after.
Note that it's only useful if you use a type more precise than
what you
require for the validation so it might be a very narrow use case not worth
adding additional complexity to the standard constraints.
That's my opinion, too narrow. A broader one is relative comparable
validation.
3. orPresent
=========
The current implementation adds orPresent support as an option of the
preexisting @Past/@Future annotations:
@Past(orPresent = true) / @Future(orPresent = true)
Gunnar suggested this afternoon that it might be more readable to have
@PastOrPresent/@FutureOrPresent, especially if we have more than one
options for @Past/@Future.
Something like @Past(resolution = DAY, orPresent = true) would be less
readable than @PastOrPresent(resolution = DAY).
Personally, I prefer having one annotation with an option rather than 2
different annotations - I think it has a better semantic - but I can see
the rationale behind Gunnar's proposal.
I vote for one annotation.
PS: sorry for my long absence. My work load got too intense these days, I
hope it will cool off soon...
Regards,
Michael