Hi,
As far as I can see, the module is based on the PHP DateInterval format and for example a string "P1Y2M3D" is saved.
If you do an entity query, it is impossible to order or do a condition other than equal with that format.
If you write something like:
$query->condition('my_duration_field', 'P1Y', '<');
you expect that you have all the entities that have a duration less than a year. Unfortunately, it is a string comparison so the duration 'P11Y' will be selected by the query but it shouldn't. I haven't found a way to do a simple condition on the duration field. If you have one I'm interested, otherwise maybe we should store the duration as a timestamp and not a DateInterval.
It implies big changes, but it would solve the problem.
I'm interested to listen your solutions about this condition problem, maybe I've missed something.
Comments
Comment #2
astonvictor commentedYou can try smth like
->condition('field_duration', 'P1990Y%', 'LIKE')for particular year.
Comment #3
phjouThank you for your answer, but P1990Y means a duration of 1990 years. So it will not work.
For example, you have saved a content with an 11 years duration, you will save 'P11Y' in the database.
So if you compare by string comparison, you will have P11Y < P1Y but a duration of 1 year is less than 11 years.
And it is a simple case with the same unit, if you combine years and months for example, it will not work even more:
By string comparison,
P1Y < P5M but a duration of one year is more than 5 months
And you can push the issue far more
P15M < P1Y but 15 months is more than one year
No way, you can handle such a mess with entityQuery, but if the duration was saved into a common unit like a timestamp, the simple condition < and > will work like a charm.
Comment #4
jaypanInteresting issue, but storing the duration as a timestamp does not work as the duration will be lost in the conversion. for example 1 year could also be 365 days, or 12 months, and there would be no way to know what it would be when converting back from the timestamp.
I'm currently working on version 2 of the module, that will work more deeply with the typed data API, and use an actual PHP DateInterval element for the field, rather than just an interval string. I'll do some testing to see if this will work out of the box to do what you want. If not, I may have to look to see if there is a method to work with the EntityQuery API.
Edit: This is not going to be easy, but I have a few ideas about how to maybe get around it. I'll post updates as I find more.
Comment #5
phjou@jaypan Indeed, I think too that this problem implies big changes in the module. If you're working on a V2 based on PHP DateInterval, it could maybe work. Drupal has also his DateInterval field, maybe it could help.
Comment #6
jaypanI've come up with a solution for this, and it is part of the 8.x-2.x branch.
In this branch, you can do mathematical operations on duration strings by adding the tag 'duration_string'. For example, if the value in the DB is P2Y (two years) you can do a condition on the query like this:
With the above, the item in the database will be retrieved as it is P2Y, equal to two years, and the query is searching for a value equal to P1Y365D (1 year 365 days = 2 years).
I still need to document a lot of version two of the module, as well as write an upgrade path, but at least a solution is eventually coming.