У моей компании есть вспомогательный персонал, который доступен с 7 утра до 7 вечера CST, и мы стараемся отразить это на нашем веб-сайте, показывая либо кнопку, чтобы начать чат, либо сообщение о том, что они недоступны. Персонал службы поддержки находится в центральном времени, но серверы, на которых размещен наш сайт, могут находиться в любом часовом поясе. (Я работаю удаленно и когда я запускаю проект локально на своей машине, например, в восточное время)
Прямо сейчас есть ошибка, в которой говорится, что вы находитесь за пределами временного диапазона в 6 часов вечера КНТ, что слишком рано. Это, по-видимому, связано с тем, что мой временной диапазон в CST на самом деле составляет 2 дня в UTC (1 час до 1 часа следующего дня), и я время basingmy от даты 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));
Любые идеи о том, как сделать эту работу должной?
Вы делаете гораздо больше, чем вам нужно. Лично я бы использовал свой проект Noda Time, но все это можно сделать довольно легко с помощью BCL, используя TimeZoneInfo.ConvertTime
:
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
}