簡體   English   中英

使用NodaTime比較兩個不同的時區時跨

[英]Comparing two different timezone timespans using NodaTime

我有一個要求,對此有些困惑。 我開始使用NodaTime,我認為這是最好的方法。

我在兩個不同的時區中都有兩個用戶,User1和User2。 例如,他們可以在當地時區的下午2點至下午5點之間見面。 如果User2與User1的偏移量為+2小時,則重疊時間僅為1小時。 我想要得到的小時數重疊(User1和User2的實際時間將是一個獎勵。)

到目前為止,我得到的是:

var user1TimeZone = DateTimeZoneProviders.Tzdb.GetZoneOrNull(user1timezone);
var user2TimeZone = DateTimeZoneProviders.Tzdb.GetZoneOrNull(user2timeZone);

關於我什至應該開始解決這個問題的任何想法?

謝謝,

首先,請注意它可能每天都在變化:不要將時區視為固定的偏移量。

其次,請注意,指定的本地時間(針對每個開始/結束)可能甚至不會發生,或者可能會發生兩次。 找出您要如何處理含糊不清的時間。

對於任何特定的日子,我只要將其用戶的開始/結束時間轉換為Instant (通過ZonedDateTime )即可,然后您可以找到重疊部分。 這確實假設任何重疊都發生在同一天,但是...實際上並非如此。 我即將開會,其中一位與會者在新西蘭-3月14日在這里,但3月15日在新西蘭。 考慮到這一點比較棘手...

這是相對簡單的情況的代碼:

using NodaTime;
using System;

class Test
{
    static void Main()
    {
        // My availability: 4pm-7pm in London        
        var jon = new Availability(
            DateTimeZoneProviders.Tzdb["Europe/London"],
            new LocalTime(16, 0, 0),
            new LocalTime(19, 0, 0));
        // My friend Richard's availability: 12pm-4pm in New York
        var richard = new Availability(
            DateTimeZoneProviders.Tzdb["America/New_York"],
            new LocalTime(12, 0, 0),
            new LocalTime(16, 0, 0));

        // Let's look through all of March 2017...
        var startDate = new LocalDate(2017, 3, 1);
        var endDate = new LocalDate(2017, 4, 1);
        for (LocalDate date = startDate; date < endDate; date = date.PlusDays(1))
        {
            var overlap = GetAvailableOverlap(date, jon, richard);
            Console.WriteLine($"{date:yyyy-MM-dd}: {overlap:HH:mm}");
        }
    }

    static Duration GetAvailableOverlap(
        LocalDate date,
        Availability avail1,
        Availability avail2)
    {
        // TODO: Check that the rules of InZoneLeniently are what you want.
        // Be careful, as you could end up with an end before a start...
        var start1 = (date + avail1.Start).InZoneLeniently(avail1.Zone);
        var end1 = (date + avail1.End).InZoneLeniently(avail1.Zone);

        var start2 = (date + avail2.Start).InZoneLeniently(avail2.Zone);
        var end2 = (date + avail2.End).InZoneLeniently(avail2.Zone);

        var latestStart = Instant.Max(start1.ToInstant(), start2.ToInstant());
        var earliestEnd = Instant.Min(end1.ToInstant(), end2.ToInstant());

        // Never return a negative duration... return zero of there's no overlap.
        // Noda Time should have Duration.Max really...
        var overlap = earliestEnd - latestStart;
        return overlap < Duration.Zero ? Duration.Zero : overlap;
    }
}

public sealed class Availability
{
    public DateTimeZone Zone { get; }
    public LocalTime Start { get; }
    public LocalTime End { get; }

    public Availability(DateTimeZone zone, LocalTime start, LocalTime end)
    {
        Zone = zone;
        Start = start;
        End = end;
    }
}

如果您在服務器上執行此操作,則必須發送UTC,然后進行比較。 當您有時間在客戶端時,您必須將其轉換為本地。 這意味着,當第一個用戶想要安排會議時,他將自己的時間發送到UTC到服務器,然后,當第二個用戶獲得該時間時,他會將其轉換為他的本地時間。

// First user sends UTC.
DateTime firstUserTime = DateTime.UtcNow;

// Second user gets time in his time zone.
DateTime secondUserTime = firstUserTime.ToLocalTime();

暫無
暫無

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

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