2016-09-20 5 views
2

Я хочу создать пользовательскую (несуществующую) TimeZone, которая следует точно таким же правилам, как Европа/Лондон, однако единственная разница в том, что смещение должно быть -5 часов с UTC..NET NodaTime Как создать пользовательский TimeZone?

Для целей тестирования это то, что я пытался. Как указать дневные блики? Или эта реализация полностью неверна?

public class MyTimeZone : DateTimeZone 
    { 
     public MyTimeZone() 
      : base("MyTimeZone", true, Offset.FromHours(-5), Offset.FromHours(-5)) 
     { 

     } 

     protected override bool EqualsImpl(DateTimeZone zone) 
     { 
      if (zone.Id == "MyTimeZone") 
       return true; 

      return false; 
     } 

     public override int GetHashCode() 
     { 
      return 0001; 
     } 

     public override NodaTime.TimeZones.ZoneInterval GetZoneInterval(Instant instant) 
     { 
      return new ZoneInterval("MyTimeZone", new Instant(DateTime.MinValue.Ticks), new Instant(DateTime.MaxValue.Ticks), Offset.FromHours(-5), Offset.FromHours(-5)); 
     } 
    } 
+0

Я раньше не использовал NodaTime, но могу вам сказать, что ваша функция GetHashCode полностью ошибочна. Он должен вернуть значение, которое является относительно уникальным, чтобы идентифицировать разные значения. Я бы рекомендовал вернуть хэш-код идентификатора зоны. Я предполагаю, что базовый класс уже должен делать что-то подобное. –

+0

Спасибо за ваш ответ. Я обязательно исправлю это. –

+0

Я не думаю, что у NodaTime есть API, чтобы сделать это легко, но я уверен, что Джон придет, чтобы ответить на это достаточно скоро. :) Любопытно, что для этого используется бизнес/применение? Мне всегда любопытно, когда люди говорят, что им нужны часовые пояса. Фактически, реальное использование в реальном мире действительно не нуждается в этом, насколько я знаю. –

ответ

2

Это, безусловно, не очень распространенный сценарий, но он определенно поддерживается. (В отличие от создания вашего собственного календаря, например.)

Укажите переход на летнее время с помощью GetZoneInterval - этот метод является ключом к классу. Важные вещи, чтобы получить право являются:

  • Прикованный вызов конструктора с мин/макс смещения (ваш максимум будет UTC-4, а не UTC-5)
  • GetZoneInterval
  • равенство/хэш-код, который вам всегда может сделать равенство идентичности на данный момент.

Так, например, вы могли бы:

public class LondonOffsetZone : DateTimeZone 
{ 
    private readonly DateTimeZone london; 

    // This assumes London has a minimum of +0 and a maximum of +1. 
    // To do it better, you'd resolve Europe/London and find *its* 
    // min/max, and add -5 hours to each. 
    public LondonOffsetZone() 
     : base("LondonOffset", false, Offset.FromHours(-5), Offset.FromHours(-4)) 
    { 
     london = DateTimeZoneProviders.Tzdb["Europe/London"]; 
    } 

    public override int GetHashCode() => RuntimeHelpers.GetHashCode(this); 

    // Base Equals method will have handled reference equality already. 
    protected override bool EqualsImpl(DateTimeZone other) => false; 

    public override ZoneInterval GetZoneInterval(Instant instant) 
    { 
     // Return the same zone interval, but offset by 5 hours. 
     var londonInterval = london.GetZoneInterval(instant); 
     return new ZoneInterval(
      londonInterval.Name, 
      londonInterval.Start, 
      londonInterval.End, 
      londonInterval.WallOffset + Offset.FromHours(-5), 
      londonInterval.Savings); 
    } 
} 

Это потерпит неудачу - по крайней мере, в Нода Time 2.0 - в начале и в конце времени, когда Start и End свойства не будет работать , но это должно быть абсолютно нормально в любой момент, с которым вы, вероятно, столкнетесь.

+0

Конечно, инкапсуляция существующей зоны tzdb, вероятно, самая легкая здесь. Но интересно, насколько сложным было бы, если бы у вас действительно был полный набор пользовательских дат перехода DST или других изменений смещения для реализации с нуля? –

+1

@MattJohnson: Если у вас уже есть набор моментов перехода, то это будет выглядеть очень похоже на https://github.com/nodatime/nodatime/blob/master/src/NodaTime/TimeZones/PrecalculatedDateTimeZone.cs#L78 –

+1

Можно ли это исправить, чтобы он работал в конце времени? Я бы хотел использовать это во время обеда в ресторане в конце вселенной. – Amy

 Смежные вопросы

  • Нет связанных вопросов^_^