Подтвердить что ты не робот

Instant.Now для NodaTime

Я пытаюсь получить представление об использовании Noda Time от Jon Skeet (и других).

Я пытаюсь сохранить текущее сейчас (мгновенное). Мгновенное действие создается из длинных тиков, но каково текущее количество Ticks?

Это:

Instant now = new Instant(DateTime.Now.ToUniversalTime().Ticks);

И или?

Instant now = Instant.FromDateTimeUtc(DateTime.Now.ToUniversalTime());

Являются ли они эквивалентными, я даже делаю это правильно?

PS, если Джон ответит на это - я хотел бы предложить свойство Instant.Now.

PS2 Я знаю, что заголовок содержит тег, но он не дал бы мне короткое название "Instant.Now".

4b9b3361

Ответ 1

Я немного поработал, и кажется, что способ NodaTime состоит в том, чтобы получить сейчас момент в соответствии с clock.

Если вы хотите получить текущее время с использованием системных часов, просто используйте SystemClock.Instance.Now.

Однако вместо использования SystemClock.Instance непосредственно в вашем коде предпочтительнее, чтобы вы добавляли зависимость IClock в свои классы, ориентированные на время.

Это позволит вам:

  • предоставить класс SystemClock.Instance во время выполнения, поэтому код будет использовать правильное время
  • поставляйте поддельную реализацию IClock во время модульного тестирования, чтобы вы могли настроить время по мере необходимости, чтобы протестировать различные сценарии (например, время прохождения). Там проект NodaTime.Testing, который предлагает такой класс, называется FakeClock.

Я считаю это очень полезным. Я думаю, что что-то вроде new Instant() или Instant.Now возвращает текущее время, упростит использование жестких кодов SystemClock под обложками, поэтому не хватает преимуществ тестирования, которое предлагает NodaTime.

Подробнее о модульном тестировании с помощью NodaTime см. эта ссылка.


Что касается ваших примеров кода: они не эквивалентны.

  • Instant.FromDateTimeUtc(DateTime.Now.ToUniversalTime()) действительно даст вам текущее мгновение в UTC.
  • new Instant(DateTime.Now.ToUniversalTime().Ticks) даст вам неправильную дату в будущем, потому что BCL DateTime.Ticks представляет количество тиков с 1/1/0001, и NodaTime Instant.Ticks представляет количество тиков с 1/1/1970 (см. примечание здесь).

Ответ 2

SystemClock.Now возвращает текущее время как значение Instant:

Instant now = SystemClock.Instance.Now;

Но вы можете прислушаться к замечаниям в документации для IClock интерфейса:

IClock предназначен для использования в любом месте, где требуется доступ к текущему времени. Хотя это не является строго неправильным для прямого вызова SystemClock.Instance.Now, так же, как вы могли бы называть UtcNow, он сильно обескуражен как вопрос стиля для производственный код. Мы рекомендуем предоставить экземпляр IClock для всего, что ему нужно, что позволяет вам писать тесты с использованием таймера-заглушки в сборке NodaTime.Testing(или вашей собственной реализации).

В качестве простого примера предположим, что у вас есть класс Logger, которому требуется текущее время. Вместо прямого доступа к SystemClock используйте экземпляр IClock, который передается через его конструктор:

public class Logger
{
    private readonly IClock clock;

    public Logger(IClock clock)
    {
        this.clock = clock;
    }

    public void Log(string message)
    {
        Instant timestamp = this.clock.Now;
        // Now log the message with the timestamp... 
    }
}

Когда вы создаете экземпляр Logger в своем производственном коде, вы можете дать ему SystemClock.Instance. Но в unit test для класса Logger вы можете дать ему FakeClock.