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

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

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

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

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

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


person Rog    schedule 20.10.2016    source источник


Ответы (2)


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

  • Преобразуйте оба значения 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;
    }
}
person Jon Skeet    schedule 20.10.2016
comment
Спасибо. Я попробую это с вашим решением. Кроме того, я получаю сообщение об ошибке типа Cannot implicitly convert type 'NodaTime.ZonedDateTime' to 'NodaTime.LocalDateTime'. Преобразование LocalDateTime в ZonedDateTime устранило ошибку. Прав ли я в этом? - person Rog; 20.10.2016
comment
Спасибо, @Jon Skeet. - person Rog; 27.10.2016

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

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);
}
person Niyoko    schedule 20.10.2016
comment
Спасибо. Ваше решение отлично работает. Но не могли бы вы объяснить объект DateTimeZone localZone?, Поскольку он устанавливает значение смещения. - person Rog; 20.10.2016
comment
@Karthik Используется для преобразования Instant в LocalDate, потому что Instant не зависит от часового пояса. Измените его в соответствии с вашим часовым поясом. - person Niyoko; 20.10.2016
comment
Или вы можете автоматически получить местный часовой пояс, позвонив DateTimeZoneProviders.Bcl.GetSystemDefault() - person Niyoko; 20.10.2016
comment
Спасибо @Niyoko Yuliawan. - person Rog; 27.10.2016