Skip to content

Enterprise Systems

A business day is not always a calendar date in the server's time zone

A practical model for timestamps, branch time zones and close-of-day reports in multi-branch business software.

By · Published · 6 min read

A sale created at 00:15 on Tuesday may belong to Monday's trading day. A restaurant can close after midnight; a shop can run a shift across a date boundary; a branch may use a different local time zone from the server. If a report groups transactions by the server's date alone, the result can be technically consistent and operationally wrong.

The fix begins by separating two ideas: the instant an event occurred and the business date to which the organisation assigns it. Store an unambiguous timestamp for the instant. Decide the business date using the branch's time zone and the business's close-of-day rule.

Store the instant; calculate the local view

A timestamp with time zone in PostgreSQL represents an instant and is rendered in a selected time zone. Keep the canonical event time in that form. Avoid storing a local clock reading without its zone: “1:30 AM” may occur twice when clocks move back, and may not occur at all when clocks move forward.

Use an IANA zone name such as Asia/Kolkata or America/New_York, not a fixed offset like UTC-5. Offsets change with daylight-saving rules and governments can change time-zone law. The time-zone database is updated to reflect those decisions.

Define a trading day as a business rule

A business date is often a date field assigned when the transaction is posted. Its calculation may depend on the branch zone, a configured closing time and whether a late-night grace period applies. For example, a restaurant that closes at 02:00 may assign activity before 02:00 to the previous day's close. That is an explicit operational rule, not a universal calendar conversion.

Write the rule down and let managers inspect it. If a branch changes its close time, decide whether the change applies only going forward or whether historical reports should be recalculated. In accounting systems, changing a posted document's business date silently can affect a closed period, so corrections need an auditable process.

Use half-open intervals in reports

For a daily report, query from the start of the business date up to, but not including, the start of the next business date. In SQL terms, that is created_at >= start and created_at < next_start. This avoids rounding a timestamp to 23:59:59.999 and missing records with finer precision.

Calculate both boundaries in the branch's time zone, then compare the resulting instants. A local day can be shorter or longer than 24 hours around a daylight-saving transition. Do not assume that adding 24 hours to an instant always finds the next local midnight.

Make the chosen date visible

A receipt or close report should show the branch, business date and time zone context clearly. Users need to understand whether a report means “events that happened in this UTC interval” or “transactions assigned to this branch's trading day.” Those answer different questions.

What belongs in a timestamp and what belongs in a business date?

Use a timestamp for when an event occurred or was recorded. Use a separate date for the business period the organisation assigns to that event, when the domain needs that concept. Keeping both prevents the report from reconstructing a past business decision from a time-zone rule that may later change.

Should the server's local time zone drive reports?

Usually no. A server can move regions or run in UTC while a branch keeps its local operating hours. Set the branch or organisation zone explicitly and apply it when calculating business boundaries.

References

Author

Raktim Ranjit is a software engineer and the founder of NodeDR Infotech. He builds and maintains the software described here.

Have something in mind?

Let’s build something useful.

Tell me about the idea, product, or workflow you’re working through.

Tap to say hello