When datetime.utcnow() (naive) was passed as after=, astimezone() treated
it as system-local time (Beijing), causing next_run_at to be calculated
incorrectly. Now naive datetimes are explicitly localized to UTC first.
Also replaced deprecated datetime.utcnow() with aware UTC equivalent.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>