使用以分钟为单位的偏移量将 utc 时间转换为时区时间 C#

Convert utc time to timezone time using an offset in minutes C#

  1. 前端发送 timezoneOffsetInMinutes

var timezoneOffsetInMinutes = new Date().getTimezoneOffset();
console.log(timezoneOffsetInMinutes);

  1. Api 接收偏移量

    public DateTimeOffset GetDateTimeOffsetAtTimezone(int timezoneOffsetInMinutes)
    {
        var utc = DateTime.UtcNow;
        utc.AddMinutes(timezoneOffsetInMinutes); //Apply the offset
        var result = new DateTimeOffset(utc, TimeSpan.FromMinutes(timezoneOffsetInMinutes)); //Set the offset
    
        return result;
    }
    

出于某种原因,我收到此错误消息

"The UTC Offset for Utc DateTime instances must be 0. (Parameter 'offset')"

我不想使用 NodaTime,因为我已经有了 timezoneOffset,我只需要应用它。除非我错了,否则我应该使用 NodaTime。

如果您知道执行此操作的正确方法,那将非常有帮助。

直接回答你的问题:

public DateTimeOffset GetDateTimeOffsetAtTimezone(int timezoneOffsetInMinutes)
{
    // Start out with the current UTC time as a DateTimeOffset
    DateTimeOffset utc = DateTimeOffset.UtcNow;

    // Get the offset as a TimeSpan
    TimeSpan offset = TimeSpan.FromMinutes(timezoneOffsetInMinutes);

    // Apply the offset to the UTC time to calculate the resulting DateTimeOffset
    DateTimeOffset result = utc.ToOffset(offset);

    return result;
}

就是说 - 请确保您仅在中继 当前 时区偏移时才这样做 - 有效的 现在 在客户端上,now 在服务器上(合理的传输延迟是可以接受的)。要了解为什么,请参阅the timezone tag wiki中的“时区!=偏移量”。

如果您还需要使用除现在以外的时间,那么您需要改为从客户端收集时区 ID,而不是偏移量。

var timeZoneId = Intl.DateTimeFormat().resolvedOptions().timeZone;
console.log(timeZoneId);

这将 return 一个 IANA 时区标识符,例如 America/Los_Angeles

在服务器端,您有以下选择:

  • 在非 Windows 系统上(Linux、OSX 等):

    public DateTimeOffset ConvertDateTimeOffsetToTimeZone(DateTimeOffset dto, string ianaTimeZoneId)
    {
        // Get the time zone by its identifier
        TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(ianaTimeZoneId);
    
        // Convert the input value to the time zone
        DateTimeOffset result = TimeZoneInfo.ConvertTime(dto, tz);
    
        return result;
    }
    
  • 在任何 OS(包括 Windows)上使用我的 TimeZoneConverter 库:

    using TimeZoneConverter;
    
    public DateTimeOffset ConvertDateTimeOffsetToTimeZone(DateTimeOffset dto, string ianaTimeZoneId)
    {
        // Get the time zone by its identifier
        TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(ianaTimeZoneId);
    
        // Convert the input value to the time zone
        DateTimeOffset result = TimeZoneInfo.ConvertTime(dto, tz);
    
        return result;
    }
    
  • 在任何 OS(包括 Windows)上使用 Noda Time 库:

    using NodaTime;
    
    public DateTimeOffset ConvertDateTimeOffsetToTimeZone(DateTimeOffset dto, string ianaTimeZoneId)
    {
        // Get the time zone by its identifier
        DateTimeZone tz = DateTimeZoneProviders.Tzdb[ianaTimeZoneId];
    
        // Convert the input value to the time zone
        DateTimeOffset result = OffsetDateTime.FromDateTimeOffset(dto)
            .InZone(tz)
            .ToDateTimeOffset();
    
        return result;
    }
    

    当然,如果您在整个项目中都使用 Noda Time,那么您可能更愿意根据 Noda Time 的类型保留内容,而不是来回转换。