0

我的应用程序服务器与我的大多数应用程序用户当前所在的位置不同。

在存储日期时间值时,我意识到如果我只是这样做

`TimeAdded=DateTime.Now`, 

时间是根据服务器位置时间存储的,无论我在Startup.cs课堂上是否做了以下事情

 var cultureInfo = new CultureInfo("en-NG");
 cultureInfo.NumberFormat.CurrencySymbol = "NGN";

 CultureInfo.DefaultThreadCurrentCulture = cultureInfo;
 CultureInfo.DefaultThreadCurrentUICulture = cultureInfo;

我的用户的位置在 UTC+1,而服务器当前位于 UTC-8 的位置

有没有办法让我的日期时间值按照类中的CurrentCultureInfo设置存储在数据库(SQL Server)中startup.cs

我目前仅将日期时间值存储为 UTC,并在从数据库中检索值后将其转换为等效的 UTC+1 值。

所以,我愿意

TimeAdded=DateTime.UtcNow;

在检索显示给用户的值后,我将其转换为

TimeAdded=TimeAdded.AddHours(1)

我希望有一个更好的方法来解决这个问题。

谢谢

4

1 回答 1

2

有没有办法根据 CurrentCultureInfo 将我的日期时间值存储在数据库(SQL Server)中?

日期时间在 SQL Server 中以二进制格式存储,没有任何文化信息。但是 SQL Server 可以存储带有时间偏移的日期和时间信息。SQL Server 具有datetimeoffset类型。我认为用文化信息存储日期并不能解决在用户本地时区显示日期和时间的问题,因为文化信息可以对应多个时区。例如,在西班牙,我们有两个时区,而美国有几个时区。

在检索显示给用户的值后,我将其转换为

TimeAdded=TimeAdded.AddHours(1)

我希望有一个更好的方法来解决这个问题。

不要那样做,因为夏令时会发生什么?并且您假设您的所有用户都在同一个时区。

我建议您将日期时间存储在 UTC 中,因为它不是模棱两可的,它只有一种解释。然后您必须将该日期时间转换为用户时区的本地日期时间以进行显示。如果您知道用户的时区,您可以执行以下操作:

var usertimeZoneInfo = TimeZoneInfo.FindSystemTimeZoneById(userTimeZoneId);
var userLocalDateTime = TimeZoneInfo.ConvertTimeFromUtc(utcDateTime, usertimeZoneInfo);

可以使用一些 JavaScript 计算出用户的 IANA 时区。这个答案向您展示了如何做到这一点。

并且 IANA 时区可以转换为 windows 时区 id。请看这个答案。它向您展示了如何做到这一点。

另一方面,如果您通过从浏览器调用一些 Web API 来获取数据。你真的不需要做太多。您只需要确保数据按照 UTC 日期进行序列化。是的,您将 UTC 日期存储在数据库中,但是当您从数据库中检索它们时,您会得到DateTimeKind.Unspecified日期,然后这些日期没有正确序列化为 JSON。如果使用 Newtosoft.Json 进行序列化,可以指定SerializerSettings.DateTimeZoneHandling = DateTimeZoneHandling.Utc

如果您使用的是 System.Text.Json,那么您必须JsonConverterDateTime.

在这里,您可以将日期JsonConverter序列化为DateTimeKind.UnspecifiedUTC:

public class JsonDateConverter : JsonConverter<DateTime>
{
    public override DateTime Read(ref Utf8JsonReader reader, Type typeToConvert, JsonSerializerOptions options)
    {
        var d = reader.GetDateTime();
        return d;
    }

    public override void Write(Utf8JsonWriter writer, DateTime value, JsonSerializerOptions options)
    {
        if (value.Kind == DateTimeKind.Unspecified)
        {
            value = new DateTime(value.Ticks, DateTimeKind.Utc);
        }
        writer.WriteStringValue(value);
    }
}

然后,在从 Web API 检索到数据之后,编写一些 Javascript 来解析日期:

obj.theDate = obj.TheDate && new Date(obj.TheDate);

您需要这样做,因为DateTime在序列化为 JSON 时被序列化为字符串。你想theDate成为一个 JavaScript 约会对象。

之后,theDate 为用户时区本地时间日期。要检查它,请编写以下内容:

console.log(obj.theDate);
于 2020-12-28T10:13:24.207 回答