#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.