Определить, находится ли время определенного часового пояса в пределах диапазона

1

У моей компании есть вспомогательный персонал, который доступен с 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));

Любые идеи о том, как сделать эту работу должной?

  • 0
    Вы действительно имеете в виду, что они доступны с 6:00 до 18:00 CST или с 6:00 до 18:00 по центральному времени?
  • 0
    @JonSkeet Я имею в виду 7 утра до 7 вечера в центральном стандартном часовом поясе. (Компания находится в штате Флорида Panhandle)
Показать ещё 3 комментария
Теги:
datetime
timezone
datetimeoffset

1 ответ

3
Лучший ответ

Вы делаете гораздо больше, чем вам нужно. Лично я бы использовал свой проект 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
}
  • 0
    Отлично, спасибо большое. Это намного проще и легче понять, чем я имел раньше.
  • 0
    Вот основной код, который я в итоге использовал: dotnetfiddle.net/w27ZMd
Показать ещё 3 комментария

Ещё вопросы

Сообщество Overcoder
Наверх
Меню