如何处理从06:00开始到30:00结束的一天

时间:2012-01-12 08:33:12

标签: c# .net datetime c#-4.0

我正在处理客户每天30小时的情况。

这一天从早上6点开始,然后在第二天上午6点左右开始,但是当他们第二天凌晨1点到达时,他们将其视为25:00。凌晨2点将是26:00等等......

现在,我想知道,有没有办法在c#'s DateTime class中处理这个问题,或者我是否需要做很长时间才能解决这个问题?

更新

这是澳大利亚的媒体代理商。再次解释,这一天从06:00 am (12 Jan 2012)开始,到午夜时分是24:00。现在,当第二天01:00 am (13 Jan 2012)时,客户端将其视为25:00 hours (12 Jan 2012)

他们一天仍然有24小时。唯一的区别是他们的日子从早上6点开始,而不是像我们这样的00小时。

更新

我需要使用的典型程序的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 个答案:

答案 0 :(得分:20)

这听起来有点像你有一个涵盖多个时区的业务的情况 - 那么,有可能连续一天超过24小时。

然而,这并不意味着你必须调整一天的长度 - 一天是国际惯例,除非Jon Skeet实际上决定使用他已经无法建造的巨型重力枪(一天; - )并用它来改变地球的旋转速度,延长我们称之为一天的光明和黑暗的交替周期,你最好的选择是使用移位或时间段的概念;

班次(在您的情况下,时间段!)有一个工作日,一个长度和一个时区。然后你可以:

  • 汇总广告在工作日显示的所有小时数(总和[长度],其中日期=工作日)
  • 汇总广告在时区显示的所有小时数(sum [length]其中timezone = x group by workday
  • 汇总广告在特定天文日期的所有小时数(计算工作日之间的小时数。启动时间与午夜之间的小时数)

最好不要把它们称为日子,因为它会混淆直截了当的术语。

在你的例子中,你甚至不关心时区。我认为你真正需要的是广告时段即将开始的日期/时间,以及它应该显示的小时数。

编辑:对于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)
    }



}

答案 1 :(得分:7)

始终以一些通用标准格式存储您的数据,并将任何其他要求仅视为显示/输出格式。

在处理源自不同时区(与服务器不同或客户端之间)的日期/时间时,最好使用C# DateTimeOffset structure以及datetimeoffset字段类型的SQL存储它们Server 2008 R2。

这使您不仅可以确定“通用时间”,还可以了解相对于任何给定客户的时间

您尚未说明30小时工作日的实际用途,因此我无法在没有更多信息的情况下提供具体信息,但正如其他人所说,您需要为您的时髦日期输出提供自定义类。< / em>的

答案 2 :(得分:4)

由于延长天数重叠,您可以使用DateTime实现某些操作,但在您介绍这30小时工作时,您还需要回答很多问题并介绍当时的操作和规则的概念

您几乎肯定需要创建自己的类型来处理它。如果不出意外,您需要转换实际天数(DateTime可以处理大多数案例,尽管我不会感到惊讶,如果JS发布关于他的高级库/框架)来往/来自“疯狂天”。

例如:你真的必须指出所有的操作,并回答这些问题:

  • 2012年1月12日的疯狂日期和2012年1月20日的疯狂日期之间有多少天?
  • 正常日期2012年1月12日至正常日期2012年1月20日之间有多少疯狂日?
  • 2012年1月12日至2012年1月13日的疯狂日期之间有多少小时?或2012年1月12日和2012年1月14日?

所有这些都有不同的答案,并不明显。您必须与客户端进行规范/解决,具体取决于您正在设计的用例或最终用途或输出的输出。

答案 3 :(得分:3)

对于像这样的场景,我无法“调整”DateTime类。

班上的所有计算都会有所不同。您可以通过复制/学习DateTime的来源来滚动自己的DateTime。

注意:我确定我需要这个,听起来有点不对

答案 4 :(得分:2)

如果您保留标准日期,但是可以根据客户的惯例显示它们,那也许没问题。

答案 5 :(得分:2)

好的,所以这不是一个三十小时的一天,而是一个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那么你的偏移量必须为零。

答案 6 :(得分:2)

导入数据时,只需在小时大于24时添加1天,然后从小时减去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
}

这基本上就是你需要做的一切。

答案 7 :(得分:1)

从DateTime类型的baseDate变量开始。 到时候,将其设置为当前日期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);

显示文本变量;