Как преобразовать интервал в диапазон локальных данных в NodaTime?

#c# #.net #nodatime

#c# #.net #nodatime

Вопрос:

Я сталкиваюсь со сценарием, в котором мне нужно преобразовать Interval значение в перечислимую коллекцию LocalDate в NodaTime. Как я могу это сделать?

Ниже приведен код

 Interval invl = obj.Interval; 
//Here is the Interval value i.e.,{2016-10-20T00:00:00Z/2016-11-03T00:00:00Z}
  

Как я могу сформировать диапазон дат между этими интервалами?

Заранее спасибо.

Ответ №1:

Немного альтернативный подход к тому, который был предложен Niyoko:

  • Преобразовать оба Instant значения в LocalDate
  • Реализовать диапазон между ними

Я предполагаю, что интервал является эксклюзивным — поэтому, если конечная точка представляет ровно полночь в целевом часовом поясе, вы исключаете этот день, в противном случае вы включаете его.

Таким образом, приведенный ниже метод включает в себя каждую дату, которая охватывается интервалом, в данном часовом поясе.

 public IEnumerable<LocalDate> DatesInInterval(Interval interval, DateTimeZone zone)
{
    LocalDate start = interval.Start.InZone(zone).Date;
    ZonedDateTime endZonedDateTime = interval.End.InZone(zone);
    LocalDate end = endLocalDateTime.Date;
    if (endLocalDateTime.TimeOfDay == LocalTime.Midnight)
    {
        end = end.PlusDays(-1);
    }
    for (LocalDate date = start; date <= end; date = date.PlusDays(1))
    {
        yield return date;
    }
}
  

Комментарии:

1. Спасибо. Я попробую это с вашим решением. Кроме того, я получаю ошибку типа Cannot implicitly convert type 'NodaTime.ZonedDateTime' to 'NodaTime.LocalDateTime' . Преобразование LocalDateTime в ZonedDateTime исправило ошибку. Правильно ли я это делаю?

2. Спасибо @Jon Skeet.

Ответ №2:

Используйте этот код:

 var l = Enumerable.Range(0, int.MaxValue)
            .Select(x => Period.FromDays(x))
            .Select(x => LocalDate.Add(interval.Start.InZone(localZone).Date, x))
            .TakeWhile(x => x.CompareTo(interval.End.InZone(localZone).Date) <= 0);
  

Пример:

 var localZone = DateTimeZone.ForOffset(Offset.FromHours(7));

var start = Instant.FromDateTimeOffset(new DateTimeOffset(new DateTime(2016, 10, 1)));
var end = Instant.FromDateTimeOffset(new DateTimeOffset(new DateTime(2016, 10, 25)));

var interval = new Interval(start, end);

var l = Enumerable.Range(0, int.MaxValue)
        .Select(x => Period.FromDays(x))
        .Select(x => LocalDate.Add(interval.Start.InZone(localZone).Date, x))
        .TakeWhile(x => x.CompareTo(interval.End.InZone(localZone).Date) <= 0);

foreach (var localDate in l)
{
    Console.WriteLine(localDate);
}
  

Комментарии:

1. Спасибо. Ваше решение работает нормально. Но не могли бы вы объяснить об объекте DateTimeZone localZone ?, поскольку он задает значение смещения.

2. @Karthik Он используется для преобразования Instant в LocalDate , потому что Instant не зависит от часового пояса. Измените его в соответствии с вашим местным часовым поясом.

3. Или вы можете автоматически получить местный часовой пояс, вызвав DateTimeZoneProviders.Bcl.GetSystemDefault()

4. Спасибо @Niyoko Yuliawan.