Quartz.NET "?" vs "*"
A cron expression that would be perfectly valid in Hangfire or plain Unix cron throws Support for specifying both a day-of-week AND a day-of-month parameter is not implemented in Quartz.NET, for an expression that doesn't look like it's specifying both of anything. The rule is narrower and stricter than it first appears.
// the actual rule
0 0 12 * * ?Valid. Day-of-month is *, day-of-week is ? — fires every day at noon.0 0 6 ? * MONValid. Day-of-month is ?, day-of-week is MON — fires every Monday at 6 AM.0 0 12 * * *Invalid. Neither field is ? — throws the "not implemented" error, even though both fields are just wildcards.0 0 6 15 * MONInvalid, for a different reason: this looks like it's asking for "the 15th, and also every Monday," which cron's AND/OR semantics don't actually resolve the way most people expect even in dialects that allow it. Quartz.NET refuses to guess and requires you to pick one field to leave unconstrained.*, the way they were in the original. That translation is invalid; one of the two has to become ?.// why the restriction exists at all
Standard cron resolves day-of-month and day-of-week with OR logic when both are constrained to specific values — "the 15th, OR any Friday" — which is rarely what anyone actually wants and is a well-documented source of schedules that fire far more often than intended. Quartz.NET sidesteps the ambiguity entirely by making it a parse error instead of a silent surprise: you're forced to explicitly say which of the two fields you're not using, via ?, rather than have the parser guess at AND-vs-OR semantics on your behalf.
// build it without guessing
The Cron Builder & Explainer generates valid Quartz.NET expressions field-by-field, so the ? placement is handled automatically instead of being something to remember while translating between dialects.
Quartz.NET expressions have both a day-of-month field and a day-of-week field, and the rule is exact: exactly one of the two must be
?. It doesn't matter what the other field contains —*, a specific value, a list, a range,L,#— as long as one field is?, the expression is valid. The error only fires when neither field is?.