如何确定now(utc)是否在ISO 8601格式的一周中的给定天数和一天中的时间范围内

时间:2018-05-19 02:08:06

标签: c# datetime timezone timespan timezone-offset

我遇到了如何确定DateTime.UtcNow(例如2018-01-01T20:00:00Z)是否属于另一个时区的给定天数和时间的问题。没有给出具体的日期,只有一周的日期和一天的时间。给定时间采用ISO 8601标准格式。

为了简化这个问题,可以检查UTC时间是否在中国的营业时间内。

例如,给定的日期和时间范围由中国人在时区+08:00给出,它可以是:FromDayOfWeek = "Friday", FromTimeOfDay = "17:00:00+8:00", ToDayOfWeek = "Monday", ToTimeOfWeek = "08:00:00+8:00".我需要确定是否"现在"在中国的某个时间段(周五17:00:00 + 8:00-周一08:00:00 + 8:00)。

我坚持如何转换DateTime并在当地时间获得一周中的某一天,因为2018-01-01T20:00:00Z是周一在英国,但与此同时,自中国以来是+08:00,已经是中国周二了。

我的方法:

// parse the time to get the zone first (+08:00)
TimeSpan ts = TimeSpan.Parse("-08:00");

// Create a custom time zone since the time zone id is not given, and cannot be searched by SearchTimeZoneById
TimeZoneInfo tzi = TimeZoneInfo.CreateCustomTimeZone(zoneId, ts, displayName, standardName);
DateTime localDateTime = TimeZoneInfo.ConvertTime(Date.UtcNow, tzi);

String localDay = localDateTime.DayOfWeek;

// Determine if localDay is between FromDayOfWeek and ToDayOfWeek
// cast the days to integers from 1 (Monday) to 7 (Sunday)  
// create an array of days in integar days = [5, 6, 7, 1]
// if days.contains(localDays), check the times
...

有人能建议一些更好的解决方案吗?我不确定我的工作是否正常,如何处理日光节约时间,因为区域将改变,以及如何检查时间范围。我是C#的新手,我可以使用的任何库建议都很棒!

2 个答案:

答案 0 :(得分:1)

不是从UTC转换开始和结束时间,只需将其他时间转换为UTC

    TimeZoneInfo chinaTimeZone = TimeZoneInfo.CreateCustomTimeZone(zoneID, TimeSpan.Parse("-08:00"), displayName, standardName);

    DateTime FromTime = new DateTime(2018, 0, 19, 13, 0, 0); // year, month, day, hour, minute, second : Friday 1pm
    DateTime ToTime = new DateTime(2018, 0, 21, 1, 0, 0); // year, month, day, hour, minute, second : Monday 1am

    DateTime nowinUTC = DateTime.UtcNow;
    DateTime nowInChina = TimeZoneInfo.ConvertTimeFromUtc(nowinUTC, chinaTimeZone);

    if(FromTime< nowInChina && ToTime> nowInChina)
    {
        // Time is within the from and two times
    }

答案 1 :(得分:1)

根据@ Moffen answer的评论,您只想检查Now是否在特定的DayOfWeek范围内:

public void CheckAll(List<SomeClass> spans)
{
    var chinaTZ = TimeZoneInfo.CreateCustomTimeZone(zoneID, TimeSpan.Parse("-08:00"), displayName, standardName);

    var nowInChina = TimeZoneInfo.ConvertTimeFromUtc(DateTime.UtcNow, chinaTZ);

    foreach ( var span in spans )
    {
        if (InRange(nowInChina, span.startDay, span.endDay))
            // Do something on success 
            // Check for valid times here
            ;
        else
            // Do something on Failure
            ;
    }
}
public bool InRange(DateTime dateToCheck, DayOfWeek startDay, DayOfWeek endDay)
{
    // Initialise as one day prior because first action in loop is to increment current
    var current = (int)startDay - 1;

    do
    {
        // Move to next day, wrap back to Sunday if went past Saturday
        current = (current + 1) % 7;

        if (dateToCheck.DayOfWeek == (DayOfWeek)current)
            return true;

    } while (current != (int)endDay);

    return false;
}