簡體   English   中英

野田時間倒計時

[英]Noda Time Countdown

我已經編寫了一個應用程序,以顯示下一次大型行業展會之前的剩余時間。
(在撰寫本文時大約是兩年)

我開始使用標准的DateTime類,但很快遇到了每個月處理不同天數的問題,2016年是Le年,其中包含Le日 ,夏時制等。

幸運的是,我發現了NodaTime (感謝@JonSkeet)

不用說,我習慣使用DateTime的方式並不適用,而且我很難確定如何獲得剩余時間。 (周圍沒有很多例子)

例如,以下代碼不起作用,因為您無法從LocalDateTime中減去瞬間

void example()
{
    DateTime DT = Convert.ToDateTime("09/12/2016 10:00AM");

    LocalDateTime NodaLocalDateTime = new LocalDateTime(
        DT.Year, DT.Month, DT.Day, DT.Hour, DT.Minute, 0);

        Period P = NodaLocalDateTime - SystemClock.Instance.Now;
}

所以問題變成了:

從現在到某個日期,您如何獲得剩余時間?

要確定兩個事件之間的“日歷”時間量,您需要已發現的Period 但是,這處理本地日期和時間。

要確定兩個事件之間的“日歷中立”時間量,可以使用“ Instant和“ Duration -但是您無法顯示剩余的月數。

這兩種方法都有缺點,但是基本上它們是時間工作方式的基礎。 如果您使用本地時間方法,那么您會發現,經過DST轉換后,時間量會向后或向前跳一個小時。 如果您使用即時方法,則只能使用天/月/小時/分鍾等信息,而不是月份。

兩者之間的一種選擇是使用LocalDateTimePeriod ,但是將事件和當前時間都錨定在UTC中。 這樣一來,就不會有間斷,因為UTC實際上是不變的基准線。 這也意味着無論您在櫃台上的哪個位置(或托管代碼,具體取決於您打算做什么),您都將始終顯示相同的“剩余時間”。

如果您想了解有關為什么為什么不能在兩個ZonedDateTime值之間獲得Period更多詳細信息,我可以考慮一些根本有問題的示例。 最重要的是,日歷計算和時區不能很好地配合使用...

僅給出一些實際的代碼,我會得到一些類似的信息:

public sealed class EventCountdown
{
     private readonly LocalDateTime eventTimeUtc;
     private readonly IClock clock;

     // It's probably most convenient to express the event time with the time zone
     // in which it occurs. You could easily change this though.
     public EventCountdown(ZonedDateTime zonedEventTime, IClock clock)
     {
         this.eventTimeUtc = zonedEventTime.WithZone(DateTimeZone.Utc).LocalDateTime;
         this.clock = clock;
     }

     public Period GetPeriodRemaining()
     {
         return Period.Between(clock.Now.InUtc().LocalDateTime, eventTimeUtc);
     }
}

請注意,在Noda Time 2.0中, IClock.Now屬性已更改為GetCurrentInstant方法...但是在這種情況下,您可能會在UTC中使用ZonedClock並對其調用GetCurrentLocalDateTime

我最終使用的解決方案是Period.Between() ,似乎可以解決問題。

using NodaTime;

    DateTime EventDT;
    LocalDateTime LocalizedEventDT;
    Period TimeLeft; 

    public EventCountdown()
    {
        // Start with a date and time
        EventDT = Convert.ToDateTime("09/12/2016 10:00AM");

        // Localize it
        LocalizedEventDT = new LocalDateTime(
            EventDT.Year, EventDT.Month, 
            EventDT.Day, EventDT.Hour, 
            EventDT.Minute, 0);
    }

    // find out how much time is between now and the future date
    public Period GetPeriodRemaining()
    {
        DateTime dt_Now = DateTime.Now;

        return Period.Between(new LocalDateTime(
            dt_Now.Year, dt_Now.Month, dt_Now.Day, dt_Now.Hour, 
            dt_Now.Minute, dt_Now.Second), LocalizedEventDT);
    }

結果


如果有人有解決方案在考慮時區(本地與事件發生地)的同時做到這一點,那就太好了。 (我嘗試以類似的方式使用ZonedDateTime進行此操作,但遇到了磚牆)。

另外,我不清楚這種方法是否考慮了每月的各個天,夏時制,leap年等。 有人知道嗎
如果不是這樣,顯然我會歡迎任何優雅的解決方案。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM