Same code, different results.
Why
Local time zones and daylight saving.
Fix
DateTimeOffset.UtcNow
π₯ Why DateTime.Now Breaks Distributed Logic (And What to Use Instead)
Same code. Different results.
If youβve ever seen time-based logic randomly fail in production, DateTime.Now might be the silent culprit.
In distributed systems, local time is a trap.
π¨ The Core Problem
DateTime.Now returns the local time of the machine it runs on.
That means:
-
Different servers β different time zones
-
Daylight Saving Time (DST) changes β time jumps forward or backward
-
Same request β different results
In modern architectures (APIs, background workers, microservices), this breaks deterministic logic.
π₯ Real-World Failure Example
Token expiration logic
var expiresAt = DateTime.Now.AddMinutes(30);
Later, on another server:
if (DateTime.Now > token.ExpiresAt)
{
// Token expired
}
β Works sometimes
β Randomly fails in production
Why?
Because each server evaluates βnowβ differently.
π Daylight Saving Time: The Hidden Time Bomb
During DST transitions, clocks can:
-
Jump forward (missing time)
-
Go backward (duplicate time)
This can cause:
-
Scheduled jobs running twice
-
Time comparisons going backward
-
Logs appearing out of order
Time should never move backward in backend logic β but local time does.
β Why DateTime.Now Is Dangerous
-
Depends on server configuration
-
Affected by DST
-
Impossible to reliably test
-
Breaks distributed consistency
β The Golden Rule
Use UTC everywhere on the backend.
Convert to local time only at the UI layer.
π’ The Correct Approach
Use UTC
DateTime.UtcNow
Safe comparison
if (DateTime.UtcNow > expiresAtUtc)
{
// Deterministic and safe
}
β Even Better: DateTimeOffset
DateTimeOffset.UtcNow
Why itβs superior:
-
Stores UTC + offset
-
Time-zone aware
-
Ideal for distributed systems and databases
π§ Professional Tip: Abstract Time
Avoid calling time directly.
public interface IClock
{
DateTime UtcNow { get; }
}
This gives you:
-
Testability
-
Predictability
-
Clean architecture
π§Ύ TL;DR
β DateTime.Now
β Breaks distributed logic
β
DateTime.UtcNow
β Backend standard
β
DateTimeOffset
β Enterprise-grade time handling
If your system runs on more than one machine, local time is a bug β not a feature.
