Angular 4: Date pipe, UTC Time to local time: How to tell Angular the current time zone?

Setting Json Deserializer options to UTC does the trick.

The default DateTime Kind for Json deserializer is RoundTripKind. When the server side datetime object's Kind is set to Unspecified, RoundTripKind doesn't add the Z at the end of the deserialized string. I guess this is the right behaviour but if we assume all date objects are actually in UTC time than we can say to Json Deserializer to consider it.

And now date pipe actually gets that the time is in UTC and shows it in local time, by default apparently

services.AddMvc().AddJsonOptions(options =>
            {
                options.SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc;
            });

And strings like "2019-03-15T21:00:00" will become "2019-03-15T21:00:00Z"

See: Newtonsoft Json.Net DateTimeZoneHandling setting


I have done something similar using moment.js, but the Locale it's actually specific to each user configuration for Locale and date pattern:

import { Injectable, Pipe, PipeTransform } from '@angular/core';
import * as moment from 'moment';
import { Observable } from 'rxjs/Rx';
import { UserService } from '../security/user/user.service';

@Pipe({
    name: 'formatDate'
})
@Injectable()
export class DateTimePipe implements PipeTransform {

    constructor(private userService: UserService) {

    }

    /**
     * Asynchronous pipe, transforms a date into a formatted date.
     * The transformation is based on the 'locale' and 'pattern' properties from the current user preferences.
     * Usage: this pipe need to be followed by the'async' pipe, since it returns an Observable.
     */
    transform(value: any, showTime?: boolean): Observable<string> {
        if (value) {
            return this.userService.getPreferences()
                .map(prefs => {
                    const locale = prefs.preferences.get('locale');

                    let pattern;
                    if (showTime) {
                        pattern = prefs.preferences.get('dateTimeFormat') || 'DD/MM/YYYY HH:mm';
                    } else {
                        pattern = prefs.preferences.get('dateFormat') || 'DD/MM/YYYY';
                    }

                    moment.locale(locale);

                    let date = value instanceof Date ? value : new Date(value);
                    return moment(date).format(pattern);
                });
        }
        return Observable.of(value);
    }
}

you can change local with moment as well

moment.locale('en_GB')

See full options here https://momentjs.com/