Основываясь на этом вопросе, у меня есть это (чтобы я мог чувствовать объект позже при вызове функций).
Но он выдает ошибку, и мне не помешала бы помощь, чтобы понять, что не так в этом коде..? Я провел день, читая несколько подробных документов NodaTime, но теперь теряю время. Может быть, упущение чего-то тривиального? Песня: Под давлением - Королева
Ошибка вызвана в GetZoneInterval() в return new ZoneInterval():
System.InvalidOperationException: Zone interval extends to the end of time.
Трассировки стека:
at NodaTime.Utility.Preconditions.CheckState(Boolean expression, String message)
at NodaTime.TimeZones.ZoneInterval.get_End()
at WebApp.PocTasks.Models.HeardIslandDateTimeZone.GetZoneInterval(Instant instant)
at NodaTime.DateTimeZone.GetUtcOffset(Instant instant)
at NodaTime.ZonedDateTime..ctor(Instant instant, DateTimeZone zone, CalendarSystem calendar)
at NodaTime.ZonedDateTime.WithZone(DateTimeZone targetZone)
at WebApp.PocTasks.DateTimeExtension.ConvertToZonedDateTime(ZonedDateTime zonedDateTime, DateTimeZone dateTimeZone)
at WebApp.PocTasks.Controllers.HomeController.GetUserTimezoneRecords(ZonedDateTime sourceStartTime, ZonedDateTime sourceEndTime)
public class HeardIslandDateTimeZone : DateTimeZone
{
private readonly DateTimeZone _brisbane;
/// <summary>
/// The Territory of Heard Island and McDonald Islands is an Australian external territory.
/// <para>French Southern and Antarctic Time (TFT) is 5 hours ahead of Coordinated Universal Time (UTC). This time zone is in use during standard time in: Indian Ocean.</para>
/// </summary>
/// <remarks>
/// <para>Ref: www.timeanddate.com/worldclock/@1547315</para>
/// </remarks>
public HeardIslandDateTimeZone()
: base(
"Australia/HeardIsland",
false,
Offset.FromHours(5),
Offset.FromHours(5))
{
this._brisbane = DateTimeZoneProviders.Tzdb["Australia/Brisbane"];
}
public override int GetHashCode() => RuntimeHelpers.GetHashCode(this);
public override ZoneInterval GetZoneInterval(Instant instant)
{
// Return the same zone interval, but offset by 5 hours.
var brisbaneInterval = _brisbane.GetZoneInterval(instant);
return new ZoneInterval(
brisbaneInterval.Name,
brisbaneInterval.Start,
brisbaneInterval.End,
brisbaneInterval.WallOffset + Offset.FromHours(-5), // taking-off 5 from +10 that is Brisbane.
brisbaneInterval.Savings);
}
}
Моя вызывающая функция POC использует действие HomeControllerIndex и соответствующее представление.
HomeController.cs
[HttpGet]
public IActionResult Index()
{
var meeting = new ViewModelExample();
meeting.StartTime = new DateTime(2023, 2, 18, 9, 30, 0);
meeting.EndTime = new DateTime(2023, 2, 18, 10, 30, 0);
var sydney = DateTimeZoneProviders.Tzdb["Australia/Sydney"];
meeting.HostStartTime = meeting.StartTime.ConvertToZonedDateTime(sydney);
meeting.HostEndTime = meeting.EndTime.ConvertToZonedDateTime(sydney);
var heard = new HeardIslandDateTimeZone();
meeting.AttendeeStartTime = meeting.HostStartTime.ConvertToZonedDateTime(heard);
meeting.AttendeeEndTime = meeting.HostEndTime.ConvertToZonedDateTime(heard);
return View(meeting);
}
И отображение данных в представлении:
<div>
<p>Database Time: @Model.StartTime.ToCustomString() - @Model.EndTime.ToCustomString()</p>
<p>Host Time (Sydney): @Model.HostStartTime.ToCustomString() - @Model.HostEndTime.ToCustomString()</p>
<p>Attendee Time (Heard Island): @Model.AttendeeStartTime.ToCustomString() - @Model.AttendeeEndTime.ToCustomString()</p>
</div>
Примечание. ConvertToZonedDateTime, ToCustomString — это простые классы расширения для преобразования (ч/б DateTime и ZoneDateTime) и рендеринга в строку в таких форматах, как "dd/MM/yyyy HH:mm.ss" и "dd/MM/yyyy HH:mm.ss '('o<g>')'".
Идентичный класс работает хорошо, например:
// Return the same zone interval, but offset by 1 hour.
var sydneyInterval = _sydney.GetZoneInterval(instant);
return new ZoneInterval(
sydneyInterval.Name,
sydneyInterval.Start,
sydneyInterval.End,
sydneyInterval.WallOffset + Offset.FromHours(1), // adding +1 hr to +10:00 that is Sydney.
sydneyInterval.Savings);
Я надеюсь понять, чего мне не хватает, почему позже работает и устранить ошибку?
C#, .NET 7, NodaTime 3.1.9, базовое веб-приложение ASP.NET, VS 2022
Но если вам просто нужна фиксированная зона UTC+5, то проще использовать DateTimeZone.ForOffset.





Ах, похоже, это потому, что вы используете свойство End для интервала, который простирается до конца времени, поэтому оно генерирует (задокументированное) исключение.
Вы можете обнаружить это и не вызывать End там, где это неуместно:
return new ZoneInterval(
sydneyInterval.Name,
sydneyInterval.HasStart ? sydneyInterval.Start : default(Instant?),
sydneyInterval.HasEnd ? sydneyInterval.End : default(Instant?),
brisbaneInterval.WallOffset + Offset.FromHours(-5),
sydneyInterval.Savings);
Однако было бы лучше просто использовать DateTimeZone.ForOffset(Offset.FromHours(5)), если вы хотите фиксированное смещение. В настоящее время ваша зона будет варьироваться между UTC+5 и UTC+6, потому что Австралия/Брисбен варьируется между UTC+10 и UTC+11, по крайней мере, до 1992 года.
Большое спасибо за это! Документы NodaTime потрясающие, но я просто заблудился. Я добавил пример, идентичный тому, с чем я работаю, а также трассировку стека ошибок. Я решил проблему на данный момент, используя тернарный оператор, как указано выше. Спасибо, что указали на предостережение при использовании Брисбена. Мне не удалось быстро потренироваться ZonedDateTime.ForOffset.., но я скоро попробую и, возможно, буду использовать его в соответствии с рекомендациями.
не удалось найти вызов функции для ZonedDateTime.ForOffset(Offset.FromHours(5)). Это было бы идеальным решением. если это не слишком много, не могли бы вы отредактировать этот ответ, включив в него оператор возврата? еще раз спасибо..
@foxfuzz: Дох, это была моя вина, это DateTimeZone.ForOffset, а не ZonedDateTime.ForOffset. (Если вы хотите использовать значения, которые просто имеют фиксированное смещение UTC, не обязательно зная фактический часовой пояс, используйте тип OffsetDateTime.)
благодаря тонну! извините, что нуб.
@foxfuzz: Никогда не нужно извиняться за это. Надеюсь, если у вас возникнут другие вопросы о Noda Time, я смогу помочь вам с ними.
Пожалуйста, не могли бы вы опубликовать полную трассировку стека, а не только тип и сообщение? В идеале минимальный воспроизводимый пример, который также использует эту зону.