The proper way to enforce this would be with a database constraint.
alter table contractors add constraint contractor_date_uk unique
(has_contract, start_date, end_date);
This is the standard way, it is scalable, works in a multi-user environment and cannot be circumvented by cheeky developers.
Of course it is important to ensure that the time element is removed from the dates. This can be done in a trigger, or enforced through an index (which can be used by the constraint:
create unique index contractor_date_uidx
on contractors(has_contract, trunc(start_date), trunc(end_date));
Note that I am including the contractor person in the check - your question isn't clear on that point. If you really only want one contractor in force at a time then simply remove HAS_CONTRACT from the uniqueness specification.
The other thing is, this doesn't allow for overlaps. Your posted data has overlapping date ranges, so I presume that is okay. If you want to avoid overlapping date ranges, please edit your question to say so; but be warned, the logic gets gnarly.