Estaba probando un código y encontré un comportamiento muy extraño. Cuando uso DateTime.MinValue, le agrego minutos y lo convierto a UTC, parece haber una diferencia de 58 minutos entre mi zona horaria local y UTC. Estoy en Europa central (+1 en invierno o +2 en verano). ¿Cómo pueden ser 58 minutos? Esperaría una compensación de 1 hora, no 58 minutos. Estoy usando .net core en Linux.

var x1 = DateTime.MinValue.AddMinutes(61);
var x1ticks = x1.Ticks;
var x1kind = x1.Kind;
var y1 = x1.ToUniversalTime();
var y1tickes = y1.Ticks;
var y1kind = y1.Kind;

var z1 = TimeZoneInfo.ConvertTimeToUtc(x1, TimeZoneInfo.Local);
var z1ticks = z1.Ticks;
var z1kind = z1.Kind;

fragmento de código con valores evaluados : fragmento de código con valores evaluados

4
Franceq 4 mar. 2021 a las 11:53

1 respuesta

La mejor respuesta

58 minutos es aproximadamente el desfase de UTC de la hora media local ( Wikipedia) de Praga, República Checa. Supongo que su zona horaria local es Europe/Prague.

TimeZoneInfo busca los datos de la zona horaria en la base de datos de la zona horaria en su computadora. En una máquina Linux (y en todas las POSIX, creo), la base de datos predeterminada es la tz de IANA. En las computadoras con Windows, estaría consultando la base de datos de la zona horaria de Windows de forma predeterminada.

De todos modos, lo importante es que, según la base de datos de IANA, el desfase UTC de su zona horaria local en DateTime.MinValue más 61 minutos, es más 58 minutos.

// prints 00:58:00
Console.WriteLine(TimeZoneInfo.FindSystemTimeZoneById("Europe/Prague").GetUtcOffset(DateTime.MinValue));

Consulte también esta publicación.

La base de datos de IANA en realidad dice que el desplazamiento es de 57 minutos y 44 segundos, pero .NET Core en realidad lo redondea como un detalle de implementación, porque no admite segundos. Encontré esta línea del código fuente que lo explica:

    private static TimeSpan TZif_CalculateTransitionOffsetFromBase(TimeSpan transitionOffset, TimeSpan timeZoneBaseUtcOffset)
    {
        TimeSpan result = transitionOffset - timeZoneBaseUtcOffset;

        // TZif supports seconds-level granularity with offsets but TimeZoneInfo only supports minutes since it aligns
        // with DateTimeOffset, SQL Server, and the W3C XML Specification
        if (result.Ticks % TimeSpan.TicksPerMinute != 0)
        {
            result = new TimeSpan(result.Hours, result.Minutes, 0);
        }

        return result;
    }
3
Sweeper 4 mar. 2021 a las 10:30