确定某个时区是否在某个范围内的时间

时间:2015-01-16 21:04:24

标签: c# datetime timezone datetimeoffset

我的公司有支持人员,可在美国中部标准时间早上7点到晚上7点之间使用,我们会尝试通过显示发起聊天的按钮或显示不可用的消息在我们的网站上反映出来。支持人员位于中部时间,但我们站点所在的服务器可以位于任何时区。 (我在远程工作,当我在我的机器上本地运行项目时,例如在东部时间)

现在有一个错误,这表示你在中部标准时间下午6点之外的时间范围之外,这是一个小时太早。这似乎是因为我在CST的时间范围实际上在UTC时间跨越2天(下午1点到次日凌晨1点),并且我基于UTC日期离开时间。我知道这是导致问题的原因,但我不确定解决这个问题的最佳方法。

这是代码,从一个返回布尔值的函数转换为控制台应用程序以注销eh值。

查看以下代码,或在此处使用:https://dotnetfiddle.net/Hzhv8n

//=================================================================================================
//Get hours & days of operation
//These normally come from a config file, but hardcoding them here for demo
int availableChatStartHour = 13; //7am CST in UTC time
int availableChatDuration = 12;  //12 hours from 7am CST is 7pm CST
string[] availableDaysForChat = "monday,tuesday,wednesday,thursday,friday".ToUpper().Split(',');
//=================================================================================================

//The current timezone-agnostic time.
var now = DateTime.UtcNow;

//Convert times to a date object
//-------------------------------------------------
//I THINK THIS IS WHERE MY BUG IS
var startTime = new DateTime(now.Year, now.Month, now.Day, availableChatStartHour, 0, 0, DateTimeKind.Utc);
//-------------------------------------------------
var endTime = startTime.AddHours(availableChatDuration);

//Company HQ is located in the central time zone
//The central time zone can experience daylight saving time.
//We need to determine if DST is currently active or not in CST
var cstZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
var cstTime = TimeZoneInfo.ConvertTimeFromUtc(now, cstZone);
var isDstActive = cstZone.IsDaylightSavingTime(cstTime);

//If DST is active, then we need to subtract an hour from the start and end times.
if (isDstActive)
{
    startTime = startTime.AddHours(-1);
    endTime = endTime.AddHours(-1);
}

//Determine if the day of the week (in CST time) is available for chat
var isDayAvilable = availableDaysForChat.Contains(cstTime.DayOfWeek.ToString().ToUpper());

//Make sure the time of day is within the acceptable range
var isAfterStartTime = now > startTime;
var isBeforeEndTime = now < endTime;

//Now take everything into account and see if the chat is available
//return isDayAvilable && isAfterStartTime && isBeforeEndTime;


Console.WriteLine("NOW:   "+ now);
Console.WriteLine("START: "+ startTime);
Console.WriteLine("END:   "+ endTime);
Console.WriteLine("-------------------------------------");
Console.WriteLine("Day Available:       "+isDayAvilable);
Console.WriteLine("Is After Start Time: "+ isAfterStartTime);
Console.WriteLine("Is Before End Time:  "+ isBeforeEndTime);
Console.WriteLine("-------------------------------------");
Console.WriteLine("FINAL RESULT:        "+ (isDayAvilable && isAfterStartTime && isBeforeEndTime));

关于如何使其正常工作的任何想法?

1 个答案:

答案 0 :(得分:3)

你的比你需要的更多。就个人而言,我会使用我的Noda Time项目,但使用TimeZoneInfo.ConvertTime,可以使用BCL轻松完成所有

var zone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");
var centralTime = TimeZoneInfo.ConvertTime(DateTime.UtcNow, zone);
if (centralTime.Hour >= 7 && centralTime.Hour < 21 &&
    centralTime.DayOfWeek >= DayOfWeek.Monday &&
    centralTime.DayOfWeek <= DayOfWeek.Friday)
{
    // Yes, you have support staff
}
else
{
    // Nope, let the answerphone handle it
}