【问题标题】:How to get the date of a given day in a specific week?如何获取特定星期中给定日期的日期?
【发布时间】:2018-07-07 10:41:35
【问题描述】:

我想获取给定一周中特定日期的日期。星期由输入的日期决定。

例如,如果我想要这些日期的星期五:

  1. 06/27/2018
  2. 07/04/2018
  3. 07/07/2018

我期望结果:

  1. 06/29/2018
  2. 07/06/2018
  3. 07/06/2018

在这里,周被定义为星期一到星期日。

【问题讨论】:

  • 如何定义“一周”?周日到周六?周一到周日?
  • @DavidG 周根据用户传递的日期定义。我给出了3个有问题的例子。如有任何疑问,请告诉我。
  • 你误会了。如果我给你 7 月 8 日,那一天的星期五是 6 日还是 13 日?因为有些文化认为星期日是一周的开始,而另一些文化则认为它是结束。
  • @DavidG 应该考虑从周一到周日的一周。所以,应该是7月6日。如果有任何其他疑问,请告诉我。如果需要更多详细信息,我将详细解释。谢谢

标签: c# .net datetime


【解决方案1】:

您可以根据DayOfWeek 进行一些巧妙的数学运算:

public DateTime GetDay(DateTime source, DayOfWeek dayOfWeek, 
    DayOfWeek weekStartsOn = DayOfWeek.Monday)
{
    var offset = (int)source.DayOfWeek - (int)weekStartsOn;;
    if(offset < 0)
    {
        offset = offset + 7;
    }
    return source.AddDays(-offset + (int)dayOfWeek - (int)weekStartsOn);
}

并像这样使用它:

var someDate = ...; //Get a date from somewhere

var friday = GetDay(someDate, DayOfWeek.Friday);
var monday = GetDay(someDate, DayOfWeek.Monday);

如果您的一周从星期日开始,只需使用可选的第三个参数,例如:

var friday = GetDay(someDate, DayOfWeek.Friday, DayOfWeek.Sunday);

【讨论】:

  • DayOfWeek 枚举类型“环绕”在 Saturday (= 6) 和 Sunday (= 0) 之间。这可能不是提问者想要的(参见你自己的 cmets 给他)。如果我这样做GetDay(new DateTime(2018, 7, 8), DayOfWeek.Friday),那么它会是正确的星期五吗?
  • 我刚刚在单独的答案中发布了一种修复。
【解决方案2】:

对 DavidG 答案当前版本的修改:

static DateTime GetDay(DateTime source, DayOfWeek dayOfWeek)
{
  const int offsetSinceMondayIsFirstDayOfWeek = 7 - (int)DayOfWeek.Monday;
  return source.AddDays(((int)dayOfWeek + offsetSinceMondayIsFirstDayOfWeek) % 7
    - ((int)source.DayOfWeek + offsetSinceMondayIsFirstDayOfWeek) % 7);
}

这考虑到提问者认为星期一是一周的第一天。如果您希望星期六作为一周的第一天,只需将上面的 Monday 替换为 Saturday

在您将星期日视为一周的第一天的特殊情况下,它简化为 DavidG 的原始方法:

static DateTime GetDay(DateTime source, DayOfWeek dayOfWeek)
{
  return source.AddDays((int)dayOfWeek - (int)source.DayOfWeek);
}

因为 BCL 的 DayOfWeek 枚举类型已经“环绕”在 Saturday (= 6) 和 Sunday (= 0) 之间。


http://chartsbin.com/view/41671 上有一张世界地图,显然显示了在不同地区,一周中的哪一天被视为一周的第一天。

【讨论】:

    【解决方案3】:
        public void TestMethod1 ( )
        {
    
            DateTime date = DateTime.Now;
            DateTime friday = date.AddDays( (int)DayOfWeek.Friday - (int)date.DayOfWeek );
            Console.WriteLine( friday.ToString( ) );
    
        }
    

    【讨论】:

    • 这并没有考虑到提问者认为星期一是一周的第一天(见 cmets 提问)。因此,如果现在date 是 2018 年 7 月 8 日(星期日),您将添加正五天,但在这种情况下,提问者想要负两天,即提问者想要 2018 年 7 月 6 日(星期五)。
    【解决方案4】:
       using System;
          using System.Globalization;
    
       public class Example
       {
          public static void Main()
          {
             DateTime dateValue = new DateTime(2008, 6, 11);
             Console.WriteLine(dateValue.ToString("ddd", 
                               new CultureInfo("fr-FR")));    
          }
       }
    

    【讨论】:

    • 这对你有什么好处?!
    • 如果您有更好的解决方案可以提供帮助,那就贴出来吧朋友
    • 我会在 OP 回答我提出的问题时。
    • 我建议更仔细地阅读问题。实际上,星期五将无法解决。这只是一个例子。
    • 这没有回答任何问题,无论如何,为什么 OP 想要用法语打印一个硬编码的日期?请阅读How to Answer
    猜你喜欢
    • 2018-06-12
    • 2011-03-02
    • 2017-07-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-08
    • 1970-01-01
    相关资源
    最近更新 更多