【问题标题】:Check if DateTime in specific range检查 DateTime 是否在特定范围内
【发布时间】:2011-11-22 01:19:21
【问题描述】:

需要检查 DateTime 是否在特定范围内。 我想我需要计算知道今年 DST 时间的 YEAR 第一个和最后一个日期。

如何计算“3 月 2 日的星期日”日期?

From 1/1/2007 12:00:00 AM to 12/31/9999 12:00:00 AM
  Begins at 2:00 AM on Sunday of week 2 of March
  Ends at 2:00 AM on Sunday of week 1 of November

例如,我需要检查 2011 年 11 月 21 日是否介于 3 月第 2 周的星期日和 11 月第 1 周的星期日之间 - 答案应该是 NO

如果我在 2011 年 8 月 8 日通过 - 答案应该是肯定的。

基本上,我需要编写函数来检查我的日期是否属于夏令时。到目前为止,我唯一的想法是编写循环来查找例如第 2 周。

所以,我会从三月的第一天开始循环,直到第二次到达星期天。我会从 11 月 1 日开始循环(将天数增加 1)直到我第一次到达星期日。

换句话说,我需要检查输入数据是否处于夏令时时间段的函数。由上述约束定义的时间段。

附:我不能使用TimeZoneInfo,因为它在 Silverlight 中 P.P.S 我不能使用DateTime.IsDaylightSavingsTime,因为我没有时间与善良的“本地人”相处

【问题讨论】:

  • 不太清楚你的问题是什么。你能改写你的问题吗?比如“这就是我所拥有的”和“这就是我需要的”和“这是我迄今为止尝试过的”
  • 希望我的编辑能提供更多关于我在做什么的信息

标签: c# .net silverlight datetime


【解决方案1】:

尝试使用DateTime.IsDaylightSavingsTime 方法。

如果您的日期时间是 UTC,您可以转换为本地,然后使用 IsDaylightSavingsTime():

var localDateTime = utcDateTime.ToLocalTime();
var isDaylightSavings = localDateTime.IsDaylightSavingsTime();

【讨论】:

  • 这不是我需要的。我所有的 DateTimes UTC。我需要编写函数来执行此操作,因为我没有“本地”类型。我的应用程序同时从多个时区运行时间,没有“本地”时间
  • @katit,使用类似:DateTime convertedDate = DateTime.SpecifyKind( DateTime.Parse(dateStr), DateTimeKind.Utc); DateTime dt = convertedDate.ToLocalTime(); 将 UTC 时间转换为本地时间。
  • @katit,如果你有 UTC 日期时间,你不能在 SL 中转换为本地吗?
  • 我可以转换为本地但我不需要本地,我需要转换为不同的时区。假设用户查看行程并且用户与出发/到达处于不同的时区。我知道这些地点的时区,也知道 UTC 时间。我需要 TimeZoneInfo 之类的工具,但它不在 Silverlight 中
  • 另一个说明。知道当地时间是夏令时对我没有任何作用。另一个位置可能有不同的规则和时间段。所以是的,我需要实际进行计算并转换时间。
【解决方案2】:

我只是做了这个小方法,检查一下告诉我:

    bool IsInDaylightSavingsTime(DateTime date)
    {
        // get second sunday in march
        DateTime _tempDateMar = new DateTime(date.Year, 3, 1);
        int secondSunDayInMar = (8 - (int)_tempDateMar.DayOfWeek) + 7;
        _tempDateMar = new DateTime(date.Year, 3, secondSunDayInMar, 2, 0, 0);

        //get first sunday in november
        DateTime _tempDateNov = new DateTime(date.Year, 11, 1);
        int firstSunDayInNov = (8 - (int)_tempDateNov.DayOfWeek);
        _tempDateNov = new DateTime(date.Year, 11, firstSunDayInNov, 2, 0, 0);

        return (date >= _tempDateMar && date <= _tempDateNov);
    }

【讨论】:

  • 显然您的代码中有错误,但我将其标记为答案,因为这是我正在寻找的思考过程类型
  • 好吧,我是当场写的..但是错误在哪里?
  • 仍在等待明显的错误
  • 实际上,我通过我的测试用例运行它,它很好,只是它不考虑时间部分。但没关系 - 总的来说它正在工作。但无论如何我还是选择了循环。我认为它更容易阅读并且循环不是那么大,所以没关系。
  • 我为总共大约 100 次计算创建了边缘案例测试场景,它在我的笔记本电脑上运行时间为 20 毫秒。这个表现我还可以。不是其他答案中建议的网络服务调用。没关系,我得到了你的代码,但对我来说 - 那里有神奇的数字。不是批评,只是循环让我更容易阅读。循环很小。 1 到 14 次互动,具体取决于日期。在大多数情况下
【解决方案3】:

这对你来说可能已经足够了:http://www.codeproject.com/KB/datetime/TimePeriod.aspx

【讨论】:

    【解决方案4】:

    在多个 TimeZone 上运行是一件棘手的事情。一般来说,这个问题靠一个人的努力是无法解决的(除非你将自己的一生奉献给它)。如果您需要支持 2-3 个时区,则可以使用循环解决方案(AFAIK 这是在 .NET 中计算周的唯一方法)。

    我用这段代码计算了夏令时切换的周数:

    /// <summary>
    /// Utility method for GetDaylightChanges. 
    /// Searches for date defined by TransitionTime structure.
    /// </summary>
    /// <param name="year">Year for which create date.</param>
    /// <param name="transitionTime">TimeZoneInfo.TransitionTime which to use for date calculation.</param>
    /// <returns>Transition time.</returns>
    private static DateTime DateTimeByWeek(int year, TimeZoneInfo.TransitionTime transitionTime)
    {
        const int DaysInWeek = 7;
    
        // get year and month
        DateTime switchDate = new DateTime(year, transitionTime.Month, 1);
    
        // move to switch day of week
        while (switchDate.DayOfWeek != transitionTime.DayOfWeek)
        {
            switchDate = switchDate.AddDays(1);
        }
    
        // move to week
        switchDate = switchDate.AddDays((transitionTime.Week - 1) * DaysInWeek);
    
        // add time
        switchDate = switchDate.AddHours(transitionTime.TimeOfDay.Hour);
    
        // sometimes it gives us next month...
        if (switchDate.Month != transitionTime.Month)
        {
            // ...then use previous (last) week
            return switchDate.AddDays(-DaysInWeek);
        }
    
        return switchDate;
    }
    

    显然你不需要时间,需要用一些自定义参数替换TransitionTime

    【讨论】:

    • 我在上面解释了为什么 .NET 对我没有帮助。我不需要太多支持——现在只有 4 个美国主要时区,以后可能会扩展。我想我会写那些丑陋的循环 :) 谢谢,伊万
    • 哦,第一次没弄明白。那么是的,使用循环。顺便说一句,请参阅更新的答案。
    【解决方案5】:

    您可以编写一个 Web 服务,它采用 utc 日期时间和时区 ID 并返回您需要的信息 - 例如 IsDaylightSavings。由于您可以访问完整的 .net 框架,因此您可以使用它所具有的时区功能,只要安装了系统更新,该功能就应该始终是最新的。

    【讨论】:

    • 是的,我确信我可以找到第 3 方网络服务并为此付费。不,这只是另一种复杂性。
    • 我没有说你需要为一个付费 - 只需编写你自己的并使用从注册表获取时区信息的 .net 框架。为 DST 编写硬编码例程是有缺陷的,因为规则可以并且将会改变——他们只是在 2007 年改变了——并且除非正确地执行它比使用 Web 服务来利用已经编写和测试的代码来处理更复杂夏令时规则。
    • 对不起,那是对第三者的讽刺 :) 我明白你的意思,但它太过分了。此功能必须是本地的。您知道如何在 Silverlight 中处理异步调用吗?现在想象一下,如果您在自定义控件中需要此功能。它只是行不通。至于变化 - 没关系,我总是可以发布更新。它的网络应用程序 - 更新很容易。从这个角度来看,安装服务器操作系统更新或更新我的应用程序没有太大区别
    • 是的,但是如果您考虑应用程序的生命周期(不是应用程序的单次运行,而是应用程序可以使用多长时间),这不是一个好主意(至少在我看来)故意硬编码 dst 规则。此外,如果您必须处理任何其他时区,则经常发生变化,因此这将成为一个更大的问题,或者如果您处理较旧的日期(例如 2007 年之前的某些美国时区),那么您必须根据不同的规则处理日期。如果您不想按日期拨打电话,请获取每个区域的范围 - 所以 1 次异步通话。无论如何,这是我的看法。
    • 是的,我也考虑应用的生命周期。我现在只需要美国时区。如果规则发生变化 - 编写额外的函数不会有什么大不了的。
    猜你喜欢
    • 1970-01-01
    • 2018-11-22
    • 2021-04-01
    • 2012-09-27
    • 2011-07-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-09
    相关资源
    最近更新 更多