Отображение времени для правильного часового пояса - PullRequest
0 голосов
/ 08 января 2019

У меня есть веб-приложение .NET Core 2.2, работающее внутри приложения docker-compose. Я сохраняю различные метки времени UTC в базе данных, например:

//set asked state on question
Question questionInDb = c.Questions.Single(x => x.Id == id);
questionInDb.Asked = true;
questionInDb.AskTime = DateTime.UtcNow;
c.SaveChanges();

В apppsettings.json у меня есть раздел для настроек моего приложения, содержащий локаль, на которой должно работать приложение. Я установил CultureInfo.CurrentCulture так:

//get locale from settings, defaulting to de-DE
string locale = "de-DE";
locale = Configuration.GetValue<string>("AppSettings:Locale");
var ci = new CultureInfo(locale, false);
//actually setting locale
 CultureInfo.CurrentCulture = ci;

Я настроил свою Entity Framework для установки всех DateTime s на DateTimeKind.Utc, чтобы приложение знало, что DateTime s, которые он получает, все UTC.

Теперь, когда отображается время на виде, это не правильный час. В view.cshtml я использую @q.AskTime.ToString("HH:mm:ss dd.MM.yy"), но он всегда возвращает точное значение из базы данных. Это должно показать еще один час.

Я даже пытался установить часовой пояс контейнера в CET (Centran Euopean Time), используя ln -snf /usr/share/zoneinfo/$TZ /etc/localtime && echo $TZ > /etc/timezone (в моем docker-compose я установил переменную окружения TZ в Europe/Berlin).

У меня нет идей.

1 Ответ

0 голосов
/ 08 января 2019

Культуры (также известные как локали) используются для отображения и форматирования данных и представляют собой концепцию, отличную от часовых поясов. Вы можете найти и создать определенный TimeZoneInfo из имени часового пояса и преобразовать дату и время в формате UTC, используя метод ConvertTimeFromUtc().

Имейте в виду, что разные операционные системы используют разные имена часовых поясов. Например, вы можете использовать Europe/Berlin для Linux и Central Europe Standard Time для Windows.

Пример:

TimeZoneInfo tz;
try
{
    // Linux
    tz = TimeZoneInfo.FindSystemTimeZoneById("Europe/Berlin");
}
catch (TimeZoneNotFoundException)
{
    try
    {
        // Windows
        tz = TimeZoneInfo.FindSystemTimeZoneById("Central Europe Standard Time");
    }
    catch (TimeZoneNotFoundException)
    {
        // Fallback to UTC
        tz = TimeZoneInfo.Utc;
    }
}

var converted = tz.ConvertTimeFromUtc(DateTime.UtcNow);
...