Osy#betaRun it on Osyrin: osyrin.com

Reference / Zones

An organization's time zone — the local time of every app that names none

Organization settings → Time zone · app.DefaultTimeZone (left out) → the organization's zone · app.DefaultTimeZone = TimeZoneInfo.Utc → UTC, whatever the organization says

Each organization on Osyrin Cloud has one Time zone setting, on its settings page. An app whose source declares no `app.DefaultTimeZone` uses it as its local time — `DateTime.Now`, `DateTime.Today`, `ToLocalTime()` and `TimeZoneInfo.Local` read in it — from the app's next build. A zone the source declares always wins. The same setting is the midnight the organization's daily budgets reset at, so an owner can change it once every 30 days.

stable2 examples compiled by CIzonestimeorganizations

Summary#

An app that never says which time zone it lives in still has a local time on Osyrin Cloud: its organization's. The organization's Time zone, on its settings page, is the zone DateTime.Now and DateTime.Today read in for every app of the organization whose source declares no app.DefaultTimeZone. An app that declares one keeps its own.

Signature#

Organization settings → Time zone                        the organization's one zone (UTC until someone changes it)
app.DefaultTimeZone        (not written)                 local time is the organization's zone, on Osyrin Cloud
app.DefaultTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Europe/Stockholm");   local time is Stockholm, always
app.DefaultTimeZone = TimeZoneInfo.Utc;                  local time is UTC, always

Description#

Which zone is local time in?#

The first of these that applies:

local time is
the signed-in person set their own zone (a [PreferredTimeZone] member of the principal)their zone
the app's source declares app.DefaultTimeZonethat zone
the app is deployed on Osyrin Cloudthe organization's Time zone
anywhere else — osy launch, osy compile, osy test on your own machineUTC

"Local time" is everything that reads the local clock: DateTime.Now, DateTime.Today, DateTimeOffset.Now, d.ToLocalTime(), d.IsDaylightSavingTime(), DateTime.Parse of text that carries an offset, and TimeZoneInfo.Local itself — on the server, in the browser and inside a query alike (Time zones — TimeZoneInfo, Current time (DateTime.UtcNow, DurableClock.Now)). A stored DateTime is unaffected: it is a UTC instant whichever zone reads it.

The organization's zone does not have to be one the app lists in its zones { } block. The organization chose it, not the app's author, so the app is built with it whatever that block says.

When does a change reach an app?#

On the app's next build. Local time is fixed when an app is built, so the server, the browser and the database all agree on it without asking on each request. An app picks up a new organization zone the next time it is deployed, or the next time Osyrin Cloud rebuilds it for a new platform release. Until then it keeps the zone it was built with. Run osy deploy to move it at once (Deploying your app to an environment).

Keeping an app on its own clock#

Declare the zone in the source and the organization's setting never touches that app. An app that must stay on UTC — a log, a ledger reconciled against a bank's UTC statement — says so explicitly:

app.DefaultTimeZone = TimeZoneInfo.Utc;

entity Transfer {
  [Required, MaxLength(40)] string Reference;
  DateTime BookedAt;
}

/// The day a transfer is booked on — the UTC day, in every organization.
DateOnly BookingDay(Transfer t) => DateOnly.FromDateTime(t.BookedAt);

An app that leaves the line out follows its organization. Here "today" is the organization's today:

entity Shift {
  [Required, MaxLength(80)] string Who;
  DateOnly Day;
}

/// The shifts on today's rota, where "today" starts at midnight in the organization's zone.
List<Shift> TodaysShifts() {
  var today = DateOnly.FromDateTime(DateTime.Today);
  return Shift.Where(s => s.Day == today).OrderBy(s => s.Who).ToList();
}

Changing it#

Open the organization's Settings page in Osyrin Cloud; the Time zone section shows the current zone. Choose Change time zone, pick the new one and Save time zone.

  • Who may change it: an Owner of the organization. Everyone else sees the zone and a disabled button that says so.
  • Once every 30 days. The same setting is the midnight the organization's daily budgets reset at — a billing boundary — so moving it again within 30 days is refused, naming the date it can change from. Saving the zone it already has is not a change and does not start the 30 days.
  • A new organization starts in the time zone Osyrin Cloud sets for the region it was created in, or UTC where there is none. Choosing a zone for the first time is not limited.

The daily budgets on the organization's Budgets page reset at midnight in this zone (What your plan allows, and how much of it is used).

See also#

Time zones — TimeZoneInfo — TimeZoneInfo, app.DefaultTimeZone and a viewer's own zone.

Current time (DateTime.UtcNow, DurableClock.Now) — DateTime.Now, DateTime.Today and the local clock.

What your plan allows, and how much of it is used — the plan and the budgets that reset at the organization's midnight.

Deploying an application to a cloud platform — the zone builds it — what a deploy does, including building the app.

Related

Time zones — TimeZoneInfo

Store and use civil time zones with C#'s `TimeZoneInfo`. A zone holds an IANA id (`"Europe/Stockholm"`), and C#'s…

Current time (DateTime.UtcNow, DurableClock.Now)

Read the current instant. `DateTime.UtcNow` (and the platform-idiomatic `DurableClock.Now`/…) return the current time…

What your plan allows, and how much of it is used

`osyrin org plan` and `osyrin app plan` say which plan applies and, for every meter — requests, CPU, egress, storage…

Deploying an application to a cloud platform — the zone builds it

A cloud deploy hands over the application's bundle — its app blob and the package archives it pins — to the zone the…