[フレーム]

πŸ•’ Handling Time Zones in .NET 6: Quartz.NET vs Hangfire for Scheduled Jobs

🧾 Scenario: Daily Invoice Email at 9 AM Local Time

Requirements:

  • Users are in India, UK, and US

  • Email should be sent at 9 AM local time

  • Server runs in UTC

  • App is built in .NET 6 Web API

πŸ”§ Quartz.NET vs Hangfire (Quick Comparison)

FeatureHangfireQuartz.NET
Time Zone Support❌ Manualβœ… Native
Ideal ForDelayed jobsScheduled jobs
Dashboardβœ… Yes❌ No
Retry/Error Handlingβœ… Yes⚠️ Manual
Distributed Setupβœ… Yesβœ… Yes

πŸ› οΈ Option 1: Quartz.NET for Time-Sensitive Jobs

βœ… Best for scheduled tasks at specific times in specific time zones

πŸ“¦ Job Class

public class InvoiceJob : IJob
{
 public Task Execute(IJobExecutionContext context)
 {
 Console.WriteLine($"Invoice job running at {DateTime.UtcNow}");
 // Custom logic: fetch users in IST and send emails
 return Task.CompletedTask;
 }
}

πŸ—“οΈ Register Job in Program.cs (or a Hosted Service)

IScheduler scheduler = await StdSchedulerFactory.GetDefaultScheduler();
await scheduler.Start();
IJobDetail job = JobBuilder.Create<InvoiceJob>()
 .WithIdentity("invoiceJob", "billing")
 .Build();
ITrigger trigger = TriggerBuilder.Create()
 .WithIdentity("dailyTrigger", "billing")
 .WithCronSchedule("0 0 9 ? * *", x => x
 .InTimeZone(TimeZoneInfo.FindSystemTimeZoneById("India Standard Time")))
 .Build();
await scheduler.ScheduleJob(job, trigger);

βœ… This job runs daily at 9 AM IST, no matter where your server is hosted.

πŸ› οΈ Option 2: Hangfire for Delayed or Event-Based Jobs

βœ… Best for fire-and-forget or delayed jobs

πŸ“¦ Delayed Job Example

BackgroundJob.Schedule(() => SendEmail(userId), TimeSpan.FromMinutes(10));

πŸ“¦ Recurring Job Example

RecurringJob.AddOrUpdate(
 "daily-invoice",
 () => SendDailyInvoices(),
 Cron.Daily
);

⚠️ Time Zone Limitation: Hangfire schedules in server time.

To support multiple time zones:

  • Store user time zones in the database

  • Convert local time to UTC when scheduling

  • Handle logic in the job execution if needed

πŸ—οΈ Run Jobs on a Separate Server

Both Quartz.NET and Hangfire can run in a dedicated .NET 6 Worker Service:

+-------------------+ +-------------------------+
| Web API | --> | .NET 6 Worker (Jobs) |
+-------------------+ +-------------------------+
 Database Job Scheduling Engine

βœ… This setup improves scalability, separation of concerns, and distributed job processing.

🎯 Which Should You Use?

Use CaseBest Choice
Time-specific jobs in user time zonesβœ… Quartz.NET
Delayed jobs or event-driven triggersβœ… Hangfire
Need dashboard, retries, failure trackingβœ… Hangfire
Hybrid needs (scheduled + triggered)βœ… Use both

βœ… Best Practices

  • Store all timestamps in UTC

  • Convert to local time in the UI

  • Avoid relying on server's local time

  • Use Quartz.NET for precision, Hangfire for flexibility

People also reading
Membership not found

AltStyle γ«γ‚ˆγ£γ¦ε€‰ζ›γ•γ‚ŒγŸγƒšγƒΌγ‚Έ (->γ‚ͺγƒͺγ‚ΈγƒŠγƒ«) /