简体   繁体   English

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

[英]How to determine if now(utc) is within the range of the given days of the week and times of the day in ISO 8601 format

I run into this question of how to determine if DateTime.UtcNow (eg 2018-01-01T20:00:00Z) falls within the given range of days and times that are in another timezone. 我遇到了如何确定DateTime.UtcNow (例如2018-01-01T20:00:00Z)是否属于另一个时区的给定天数和时间的问题。 There are no specific dates given, just the days of the week, and the time of the day. 没有给出具体的日期,只有一周的日期和一天的时间。 The given time is in ISO 8601 standard format. 给定时间采用ISO 8601标准格式。

To simplify this question, it can be how to check if a UTC time is within business hours in China. 为简化此问题,可以检查UTC时间是否在中国的营业时间内。

For example, the given day and time range is given by someone form China in time zone +08:00, it can be: FromDayOfWeek = "Friday", FromTimeOfDay = "17:00:00+8:00", ToDayOfWeek = "Monday", ToTimeOfWeek = "08:00:00+8:00". 例如,给定的日期和时间范围由中国人在时区+08:00给出,可以是: FromDayOfWeek = "Friday", FromTimeOfDay = "17:00:00+8:00", ToDayOfWeek = "Monday", ToTimeOfWeek = "08:00:00+8:00". I need to determine if "now" in China is sometime between the given range (Friday 17:00:00+8:00 - Monday 08:00:00+8:00). 我需要确定中国的“现在”是否介于给定范围之间(周五17:00:00 + 8:00-周一08:00:00 + 8:00)。

I'm stuck at how to convert the DateTime and get the day of the week in that local time, since 2018-01-01T20:00:00Z is Monday in UK, but at the same time, since China is +08:00, it is already Tuesday in China. 我坚持如何转换DateTime并在当地时间获得一周中的某一天,因为2018-01-01T20:00:00Z是周一在英国,但与此同时,因为中国是+08:00 ,它已经在中国周二了。

My approach: 我的方法:

// 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
...

Can anyone suggest some better solutions? 谁能提出更好的解决方案? I am not sure if mine works, and there are holes in how to deal with Day Light Saving time, since the zone will change, and how to check the time range. 我不确定我的工作是否正常,如何处理日光节约时间,因为区域将改变,以及如何检查时间范围。 I am new to C#, any suggestions of libraries I can use is great! 我是C#的新手,我可以使用的任何库建议都很棒!

Instead of converting both start and end times from UTC, just convert the other time into UTC 而不是从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
    }

Per the comments on @Moffen's answer , you only want to check if Now is within a specific DayOfWeek range: 根据对@ Moffen的回答的评论,您只想检查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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM