The five fields — minute, hour, day of month, month, day of week — are each expanded into the complete set of values they match. A star becomes every value in range, 9-17 becomes the nine hours between them, */15 becomes 0, 15, 30 and 45. Once every field is a plain set, both the description and the next run times fall out of the same data, so the two can never disagree about what the expression means.
The description is generated mechanically rather than assembled from phrase templates. A template-based describer reads beautifully for the dozen expressions its author had in mind and produces a confidently wrong sentence for everything else — which is worse than a plain one, because somebody reads "every Monday", schedules a billing run on it, and finds out in production. Every phrase here is derived from the expanded sets, so it is always literally true even where that makes it less elegant.
Next run times are found by walking the calendar forward a day at a time and testing each day against the sets, rather than by pattern-matching the text. That is why 0 0 29 2 * correctly reports the next 29 February rather than a date next month, and why an expression asking for 31 February reports no runs at all instead of silently never firing. Everything is computed and displayed in UTC — a real cron daemon uses its host’s time zone, which is its own source of surprise.