Как обрабатывать день, который начинается с 06:00 и заканчивается в 30:00 - PullRequest
23 голосов
/ 12 января 2012

Я работаю со случаем, когда у клиента есть 30-часовой рабочий день.

День начинается в 6 часов утра, а затем продолжается до 6 часов утра следующего дня, но когда они приходят в 1 час ночи следующего дня, они принимают это за 25 часов. 2 часа ночи будут 26:00 и так далее ...

Теперь, я хочу знать, есть ли способ справиться с этим в c#'s DateTime class или мне нужно проделать длинный путь и разделить все это?

UPDATE

Это медиа-агентство в Австралии. Просто чтобы еще раз объяснить, день начинается в 06:00 am (12 Jan 2012), а когда наступает полночь, это будет 24:00. Теперь, когда на следующий день 01:00 am (13 Jan 2012), клиент принимает его как 25:00 hours (12 Jan 2012).

У них все еще есть 24 часа в день. Разница лишь в том, что их день начинается в 6 часов утра, а не в 00 часов, как у нас.

UPDATE:

XML-представление типичной программы, с которой мне нужно работать. Примечание. Удалены CHANNEL_CODE и CHANNEL_NAME.

 <PROGRAMME>
  <PROGRAMME_ID>1</PROGRAMME_ID>
  <PROGRAMME_NAME>Mass For You At Home</PROGRAMME_NAME>
  <CHANNEL_CODE>SomeCode</CHANNEL_CODE>
  <CHANNEL_NAME>SomeChannel</CHANNEL_NAME>
  <TX_DATE>20120101</TX_DATE>
  <START_TIME>06:00</START_TIME>
  <DURATION>1800</DURATION>
  <AGENCY_AVAIL>C</AGENCY_AVAIL>
  <SALES_AVAIL>90</SALES_AVAIL>
  <SSB>N</SSB>
 </PROGRAMME>
</PROGRAMME>


<PROGRAMME>
  <PROGRAMME_ID>2</PROGRAMME_ID>
  <PROGRAMME_NAME>Home Shopping</PROGRAMME_NAME>
  <CHANNEL_CODE>SomeCode</CHANNEL_CODE>
  <CHANNEL_NAME>SomeChannel</CHANNEL_NAME>
  <TX_DATE>20120101</TX_DATE>
  <START_TIME>26:00</START_TIME>
  <DURATION>1800</DURATION>
  <AGENCY_AVAIL>C</AGENCY_AVAIL>
  <SALES_AVAIL>0</SALES_AVAIL>
  <SSB>N</SSB>
 </PROGRAMME>

Итак, есть ли способ настроить класс DateTime, чтобы он начинался в 06:00 и заканчивался в 30:00?

Ответы [ 8 ]

20 голосов
/ 12 января 2012

Это немного похоже на ситуацию, когда у вас есть бизнес, который охватывает несколько часовых поясов - тогда можно иметь непрерывный день, который дольше, чем 24 часа.

Однако это не означает, что вам нужно регулировать продолжительность дня - день является международным соглашением, и, если Джон Скит не решит использовать гигантское гравитационное оружие, которое он, несомненно, построил (через день; -) и использует его для изменения скорости вращения Земли, продлевая чередующийся период света и тьмы, который мы называем днем, лучше всего использовать концепцию сдвига или временного интервала;

Смена (в вашем случае, временной интервал!) Имеет рабочий день, продолжительность и часовой пояс. Вы можете:

  • Сумма всех часов, в течение которых было показано объявление за рабочий день (сумма [длина], где дата = рабочий день)
  • Сумма всех часов, в течение которых было показано объявление для часового пояса (сумма [длина], где часовой пояс = x группа по рабочему дню
  • Суммируйте все часы, в течение которых реклама находилась на определенную астрономическую дату (вычислите количество часов между рабочим днем, временем начала и полуночью и продолжительностью)

Лучше не называть это днями, так как это путает простую терминологию.

В вашем случае вы даже не беспокоитесь о часовом поясе. Я думаю, что все, что вам действительно нужно, это дата / время, когда рекламный таймслот должен начаться, и количество часов, в течение которого оно должно быть показано.

РЕДАКТИРОВАТЬ: В случае вашего XML вы все еще можете использовать вышеупомянутую концепцию. Вы можете либо:

1) Очистите его, когда получите XML, и сохраните его как «правильную» дату-время, поэтому определите время начала UTC и используйте продолжительность

2) Создайте класс, который просто преобразует это в обычное представление даты и времени с длиной. Преимущество этого подхода заключается в том, что вы также можете пойти другим путем, к соглашению об источнике.

Реально, я думаю, что это действительно все, что вам нужно.

Например, в приведенном выше xml вы можете создать класс; что-то вроде этого должно сделать свое дело:

public class AdvertDate{

    public DateTime TransmissionDate { get; set;} //Store as 06:00 on the TX_Date

    public int AdvertStartTime { get; set; } //Store as 0 - 30

    public int Duration { get; set; } //Store as 18 - assuming whole numbers so change if needed        
    public DateTime RealDate {
        get{
            return TransmissionDate.AddHours(AdvertStartTime);
        }
    }


    public AdvertDate(){

    }

    public AdvertDate(DateTime transmissionDate, int advertStartTime, int duration){
        TransmissionDate = transmissionDate;
        AdvertStartTime = advertStartTime;
        Duration = duration;
    }


    public AdvertDate ConvertRealDateTimeToAdvertDate(DateTime realDateTime, int advertDuration){

        if(realDateTime.Hour < 6)
        {
            DateTime  advertDateTime = realDateTime.AddDays(-1).Date.AddHours(6);

            return new AdvertDate(advertDateTime, 24+realDateTime.Hour, advertDuration);
        }
        else{
            return new AdvertDate(realDateTime.Date.AddHours(6), realDateTime.Hour, advertDuration);
        }

    }


    public void LoadFromXml(){
        //Xml Loading here (or in a dedicated class or wherever)
    }



}
7 голосов
/ 12 января 2012

Всегда храните ваши данные в каком-либо универсальном стандартном формате и рассматривайте любые другие требования только как форматирование отображения / вывода.

При работе с датой / временем, которые происходят из разных часовых поясов (разных на сервере или также между клиентами) лучше хранить их, используя C # DateTimeOffset структуру вместе с типом поля datetimeoffset SQL Server 2008 R2.

Это дает вам возможность определитьне только «универсальное время», но и знать, какое время относительно любого данного клиента .

Вы не указали фактическое использование для 30-часовых дней, поэтомуЯ не могу предоставить подробности без дополнительной информации, но, как утверждают другие, вам нужно будет предоставить собственный класс для вывода фанки даты.

4 голосов
/ 12 января 2012

Поскольку расширенные дни перекрываются, некоторые операции можно выполнить с помощью DateTime, но в то время, когда вы вводите этот 30-часовой рабочий день, вам также необходимо ответить на множество вопросов и представить понятия операций и правил тех дней.

Вам почти наверняка понадобится создать свой собственный тип для обработки этого.Если ничего другого, вам нужно преобразовать фактические дни (DateTime может обрабатывать в большинстве случаев, хотя я не удивлюсь, если JS сообщит о его превосходной библиотеке / фреймворке) в / из "crazy-days ".

Например: вам действительно нужно указать все операции и ответить на следующие вопросы:

  • Сколько дней проходит между сумасшедшей датой 12 января 2012 года и сумасшедшей-дата 20 января 2012 года?
  • Сколько сумасшедших дней существует между обычной датой 12 января 2012 года и обычной датой 20 января 2012 года?
  • Сколько часов проходит между сумасшедшими датами 12 января 2012 годаа 13 января 2012?Или 12 января 2012 года и 14 января 2012 года?

Все они могут иметь разные ответы и не очевидны.Вы должны будете уточнить это / работать с клиентом, в зависимости от того, какой вариант использования или конечное использование, или какой выходной процесс (ы) вы разрабатываете.

3 голосов
/ 12 января 2012

Я не вижу способа «настроить» класс DateTime для такого сценария.

Все расчеты в классе будут разными. Вы можете свернуть свой собственный DateTime, копируя / изучая из источников DateTime.

NB: Я бы очень уверен, что мне это нужно, это звучит немного неправильно

2 голосов
/ 12 января 2012

При импорте данных просто добавьте 1 день, когда час больше 24, а затем вычтите 24 из часа.

для обратного преобразования:

public static void DateTimeTo30HourDay(DateTime tx_datetime)
{
    if (tx_datetime.Hour < 6)
    {
        // subtract one day
        tx_datetime = tx_datetime.AddDays(-1);
    }
    int offsetHours = tx_datetime.Hour + 6;

    string tx_date = string.Format("{0}{1}{2}", tx_datetime.Year.ToString().PadLeft(4, '0'), tx_datetime.Month.ToString().PadLeft(2, '0'), tx_datetime.Day.ToString().PadLeft(2, '0'));
    string start_time = string.Format("{0}:{1}", offsetHours.ToString().PadLeft(2, '0'), tx_datetime.Second.ToString().PadLeft(2, '0'));

    // do what you want here
}

Это в основномвсе, что вам нужно сделать.

2 голосов
/ 12 января 2012

Хорошо, значит, это не тридцатичасовой рабочий день, а смещение на 24 часа от вашего местного времени на шесть часов. Похоже, вы должны использовать DateTimeOffset:

DateTime dt = new DateTime(2012, 2, 12, 8, 34, 56); 
var dto = new DateTimeOffset(dt, TimeSpan.FromHours(-6));

Вам потребуется использовать .Net 3.5, чтобы иметь возможность использовать структуру DateTimeOffset. Обратите внимание, что вам нужно иметь DateTime с DateTimeKind.Unspecified, чтобы иметь возможность передавать его в конструктор DateTimeOffset с любым смещением - например, если у вас есть DateTimeKind.Utc, тогда ваше смещение должно быть нулевым.

2 голосов
/ 12 января 2012

Может быть, все будет в порядке, если вы сохраните стандартные даты, но отобразите их с условием вашего клиента.

1 голос
/ 12 января 2012

Начните с типизированной переменной baseDate DateTime. Когда пришло время, установите текущую дату baseDate = DateTime.Date.AddHours(6); При отображении времени используйте TimeSpan как:

TimeSpan ts = specifiedDateTime - Globals.baseDate;
string text = string.Format("{0:yyyy.MM.dd} {1:00}:{2:00}", Globals.baseDate, Math.Floor(ts.TotalHours), ts.Minutes);

Показать текстовую переменную;

...