NodaTime转换(第2部分).如何?

mel*_*cia 16 asp.net datetime asp.net-mvc-3 nodatime

在我的第一篇文章后:

在ASP.Net MVC 3 Razor网站上使用NodaTime进行DateTime转换.如何?

我正在努力寻找一种简单的方法来使用NodaTime在本地和UTC(两种方式)之间转换日期/时间.

目前的情况是:

  • 我在数据库中将日期/时间保存为UTC.
  • 当它显示给用户时,我应该考虑当地时区并相应地进行转换.
  • 当用户提供日期/时间作为过滤器时,我需要在发送到SQL查询之前将其转换回UTC.

到目前为止我所拥有的:

从UTC转换为本地的扩展(这部分工作正常):

    public static DateTime UTCtoLocal(this DateTime dateTime)
    {
        IDateTimeZoneProvider timeZoneProvider = DateTimeZoneProviders.Tzdb;

        var utcTimeZone = timeZoneProvider["UTC"];
        var dateTimeFromDb = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond);

        var zonedDbDateTime = utcTimeZone.AtLeniently(LocalDateTime.FromDateTime(dateTimeFromDb));

        var usersTimezoneId = "Europe/London"; //just an example
        var usersTimezone = timeZoneProvider[usersTimezoneId];

        var usersZonedDateTime = zonedDbDateTime.WithZone(usersTimezone);

        return usersZonedDateTime.ToDateTimeUnspecified();
    }
Run Code Online (Sandbox Code Playgroud)

从本地转换回UTC的扩展(这部分是问题):

    public static DateTime LocaltoUTC(this DateTime dateTime)
    {
        IDateTimeZoneProvider timeZoneProvider = DateTimeZoneProviders.Tzdb;
        var usersTimezoneId = "Europe/London";
        var usersTimezone = timeZoneProvider[usersTimezoneId];

        var dateTimeFromDb = new DateTime(dateTime.Year, dateTime.Month, dateTime.Day, dateTime.Hour, dateTime.Minute, dateTime.Second, dateTime.Millisecond);
        var zonedDbDateTime = usersTimezone.AtLeniently(LocalDateTime.FromDateTime(dateTimeFromDb));

        var utcTimezoneId = "UTC";
        var utcTimezone = timeZoneProvider[utcTimezoneId];

        var utcZonedDateTime = zonedDbDateTime.WithZone(utcTimezone);

        return utcZonedDateTime.ToDateTimeUtc();
    }
Run Code Online (Sandbox Code Playgroud)

我在这做错了什么?

Jon*_*eet 28

说实话,你的UTCToLocal看起来比它需要做更多的工作.

它应该只是:

// Note: the DateTime here must have a "Kind" of Utc.
public static DateTime UTCtoLocal(this DateTime dateTime)
{
    Instant instant = Instant.FromDateTimeUtc(dateTime);
    IDateTimeZoneProvider timeZoneProvider = DateTimeZoneProviders.Tzdb;
    var usersTimezoneId = "Europe/London"; //just an example
    var usersTimezone = timeZoneProvider[usersTimezoneId];
    var usersZonedDateTime = instant.InZone(usersTimezone);
    return usersZonedDateTime.ToDateTimeUnspecified();
}
Run Code Online (Sandbox Code Playgroud)

同样,你的LocalToUTC应该沿着这些方向:

// The DateTime here should have a "Kind" of Unspecified
public static DateTime LocaltoUTC(this DateTime dateTime)
{
    LocalDateTime localDateTime = LocalDateTime.FromDateTime(dateTime);

    IDateTimeZoneProvider timeZoneProvider = DateTimeZoneProviders.Tzdb;
    var usersTimezoneId = "Europe/London";
    var usersTimezone = timeZoneProvider[usersTimezoneId];

    var zonedDbDateTime = usersTimezone.AtLeniently(localDateTime);
    return zonedDbDateTime.ToDateTimeUtc();
}
Run Code Online (Sandbox Code Playgroud)

您不需要将其转换为不同的时区:ZonedDateTime知道瞬间是什么,并且ToDateTimeUtc会做正确的事情.请注意,这里没有真正的dateTimeFromDb,因为如果您从未指定的转换DateTime,那可能是来自用户......

  • @pajics:不,因为它总是使用系统时区 - OP想要使用用户的时区. (2认同)