Pergunta

Qual é a maneira idiomática de obter a hora do sistema como um LocalDateTime na hora de Noda?O método mais direto que eu poderia pensar seria

var dt = DateTime.Now
LocalDateTime systemTime = new LocalDateTime(dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute);

mas dado que Noda Time's todo o propósito é substituir DateTime por algo que tenha uma semântica melhor, presumi que havia um método preferido do que usar DateTime da maneira acima.O melhor que consegui usando as instalações do Noda é

var zone = NodaTime.TimeZones.BclDateTimeZone.ForSystemDefault();
LocalDateTime systemTime = SystemClock.Instance.Now.InZone(zone).LocalDateTime;

mas isso parece bastante detalhado.

Foi útil?

Solução

Seu segundo exemplo é exatamente como você faria isso.Isso é intencionalmente prolixo.Ver Filosofia de design da Noda Time.

Pense nisso em três partes:

  1. Obtenha o momento atual:

    // Instant now = SystemClock.Instance.Now;               // NodaTime 1.x
    Instant now = SystemClock.Instance.GetCurrentInstant();  // NodaTime 2.x
    
  2. Obtenha o fuso horário do sistema.(Esta é a sintaxe preferida)

    DateTimeZone tz = DateTimeZoneProviders.Bcl.GetSystemDefault();
    
  3. Aplique o fuso horário ao instante:

    ZonedDateTime zdt = now.InZone(tz);
    

Sua última etapa para obter um LocalDateTime é trivial, mas reconheça que, ao fazer isso, você estará eliminando qualquer informação de fuso horário."Local" no NodaTime faz não significa "local para o computador onde o código está sendo executado".(Em outras palavras, não é como DateTimeKind.Local)

Coisas adicionais para pensar:

  • Você pode preferir abstrair o relógio usando o IClock interface:

    IClock clock = SystemClock.Instance;
    // Instant now = clock.Now;               // NodaTime 1.x
    Instant now = clock.GetCurrentInstant();  // NodaTime 2.x
    

    Então você pode passar o relógio como um parâmetro de método ou injetá-lo com sua estrutura DI/IoC favorita.(Autofac, Ninject, StructureMap, tanto faz...).A vantagem é que você pode usar um NodaTime.Testing.FakeClock durante seus testes de unidade.Ver Teste de Unidade com Noda Time para mais detalhes.

  • Você também pode preferir passar no DateTimeZone para que você possa executar seu código em qualquer lugar sem estar vinculado ao fuso horário do sistema.Isso é importante para aplicativos de servidor, mas nem tanto para aplicativos de desktop/móveis.

  • Se você tiver outro trabalho que use fusos horários da IANA ou se estiver usando a versão .NET Standard do Noda Time, altere a etapa 2 para usar o Tzdb fornecedor:

    DateTimeZone tz = DateTimeZoneProviders.Tzdb.GetSystemDefault();
    

    As zonas TZDB são muito mais precisas que as zonas BCL.O Noda Time mapeará o fuso horário do Windows (BCL) do seu sistema para um fuso horário IANA (TZDB) nesta chamada inicial.

Se você tem curiosidade em saber por que DateTime.Now é tão compacto enquanto o Noda Time é tão detalhado, tente descompilar DateTime.Now ou olhando as fontes de referência do MS.Você verá que ele está executando essencialmente as mesmas etapas nos bastidores.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top