Molte risposte qui indicano la memorizzazione come UTC. Ma stai molto attento con questo. Ad esempio, se pianifichi un appuntamento alle 12:00 ma l'appuntamento avviene dopo il passaggio all'ora legale, cosa accadrà? UTC non conserva alcuna informazione sull'attivazione di dst al momento della memorizzazione dell'appuntamento. Molti grandi e famosi sistemi hanno commesso questo errore, in cui un utente invia un'email alle 9:00 in estate, e poi in inverno l'orario inviato mostra le 8:00, perché il calcolo indietro da UTC dipende da quando si guarda il datetime, non attivo al momento della registrazione del datetime.
Molto meglio è supporre che l'utente voglia avere i tempi che sceglie sempre. Nessuna conversione UTC, nessuna conversione dell'ora, nessuna informazione sul fuso orario, niente. Prendere un appuntamento dalle 08:00 alle 12:00 il 21 marzo 2016 è proprio questo. Non utilizzare né l'ora locale né l'ora UTC, ma l'ora non specificata (in json questo non ha né z né +, in sostanza, in .NET questo ha DateTime.Kind = DateTimeKind.Unspecified).
Naturalmente, se il tuo caso d'uso è che sei una società che tiene riunioni con qualcuno di fusi orari diversi e vuoi vedere queste informazioni, ad esempio, in un calendario aziendale, ma consenti agli utenti di vedere che ora è nel loro fuso orario, diventa più complicato. Il tempo deve essere corretto per persone diverse in fusi orari diversi (fornitore e cliente).
In questi casi, potresti persino voler registrare quando l'appuntamento è stato salvato nel database, in quale fuso orario e se incluso dst o meno. In questo modo, puoi sempre calcolare l'ora locale su qualsiasi altra cosa, a quello che sarebbe ora o a quello che doveva essere storicamente. Poiché i fusi orari non sono statici, il che rende le cose ancora più complicate.
Fortunatamente, qui entrano in gioco biblioteche come http://nodatime.org/ che sono altamente raccomandate. Lavorano con le date in modo molto più coerente. Anche allora consiglierei di racchiudere tutte le variabili e la logica del tuo datetime nei tuoi wrapper, usando le interfacce in modo che possano essere derise e quindi puoi comunque cambiare logica in seguito.