如何获得本周开始的DateTime?

Gat*_*ler 443 c# datetime

我怎么知道一周的开始(周日和周一)知道C#中的当前时间?

就像是:

DateTime.Now.StartWeek(Monday);
Run Code Online (Sandbox Code Playgroud)

Com*_*his 699

使用扩展方法.你知道,他们是一切的答案!;)

public static class DateTimeExtensions
{
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        int diff = (7 + (dt.DayOfWeek - startOfWeek)) % 7;
        return dt.AddDays(-1 * diff).Date;
    }
}
Run Code Online (Sandbox Code Playgroud)

可以使用如下:

DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Monday);
DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Sunday);
Run Code Online (Sandbox Code Playgroud)

  • 您可以按如下方式简化:`int diff = dayOfWeek - dt.DayOfWeek; return dt.AddDays(diff).Date;` (13认同)
  • 特洛伊,如果给定日期是星期日,而你的星期一是星期一,我不相信你的代码有效.它将返回(星期日+ 1)而不是(星期日 - 6) (11认同)
  • 有时这对我来说会晚一天。一旦我从“dt”中剥离时间部分,它就对我有用。我用了 `int diff = dt.Date.DayOfWeek - startOfWeek;` (5认同)
  • 如果`dt` 是UTC 并且已经是一周的开始,则这不起作用,例如`2012-09-02 16:00:00Z`,即当地时间的`Mon, 03 Sep 2012 00:00:00`。所以它需要将 `dt` 转换为本地时间或者做一些更聪明的事情。如果输入是 UTC,它还需要将结果作为 UTC 返回。 (2认同)

Eri*_*ric 74

我能想出的最快方法是:

var sunday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek);
Run Code Online (Sandbox Code Playgroud)

如果您希望将一周中的任何其他日期作为开始日期,那么您需要做的就是将DayOfWeek值添加到最后

var monday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek + (int)DayOfWeek.Monday);

var tuesday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek + (int)DayOfWeek.Tuesday);
Run Code Online (Sandbox Code Playgroud)

  • 在拉脱维亚周从星期一开始......实际上......我一直想知道星期天一周怎么开始......对我来说似乎很尴尬..;) (6认同)
  • 这个添加的代码不适用于Threezol描述的情况.如果您希望本周的开始时间是星期一,那么在星期日计算会给出即将到来的星期一,而不是之前的星期一. (5认同)
  • 是的..对于星期天,它给出了下一个Modnay ..而不是之前的:P (4认同)
  • 最简单的答案是最好的,这个答案很好,但文化依赖 (2认同)

Jas*_*ete 65

更加冗长和文化意识:

System.Globalization.CultureInfo ci = 
    System.Threading.Thread.CurrentThread.CurrentCulture;
DayOfWeek fdow = ci.DateTimeFormat.FirstDayOfWeek;
DayOfWeek today = DateTime.Now.DayOfWeek;
DateTime sow = DateTime.Now.AddDays(-(today - fdow)).Date;
Run Code Online (Sandbox Code Playgroud)

  • 另一个问题:两次调用"Now"属性是危险的.如果当前时间恰好在两次通话之间的24:00(或午夜12:00)通过,则日期将发生变化. (6认同)
  • 这有一个错误:今天=星期天; fdow =星期一; (今天 - fdow)== -1; DateTime.Now.AddDays( - ( - 1)).Date == DateTime.Now.AddDays(+1).Date; 01-02-2010!= 25-01-2010 !! (3认同)
  • 你也可以使用`CultureInfo.CurrentCulture`来获取当前的文化,而不是像那样把它拉出来.看起来像是一种奇怪的访问方式. (3认同)
  • 如果你在星期天试试这个,那么它基本上是为en-GB做AddDays(0-1).所以它需要@Sarcastic的if声明 (2认同)

Sim*_*mon 36

使用Fluent DateTime:

var monday = DateTime.Now.Previous(DayOfWeek.Monday);
var sunday = DateTime.Now.Previous(DayOfWeek.Sunday);
Run Code Online (Sandbox Code Playgroud)

  • 我不想为此承担依赖.似乎想到了"了解你的依赖并杀死它们".:) (28认同)
  • 是的,就好像我一直在世界各地修复世界上每个开源软件中的每一个错误...... (11认同)
  • @nsimeonov它是开源的.请随意提供更好的实施,而不是扔石头. (9认同)
  • 有没有人注意到"Fluent"如何运作?只需看看代码.它正在使用do ... while循环.不想叫它的名字,但如果我决定这样做会不愉快.`public static DateTime Previous(此DateTime start,DayOfWeek day){do {start = start.PreviousDay(); } while(start.DayOfWeek!= day); 回归开始; } (7认同)
  • 我不得不发表评论,因为我对使用"do ... while"循环的投诉大笑不已!爆笑!我以前从未听过另一个程序员对循环感到不寒而栗.当他/他是否意识到他的代码实际编译成什么时,他会喜欢看到这个小丑的脸. (3认同)
  • @EstebanAraya:http://www.haneycodes.net/npm-left-pad-have-we-forgotten-how-to-program/ (2认同)
  • @nsimeonov 看来 Fluent 以这种方式编码是有充分理由的。通过使用该方法可以避免以星期一为 FDoTW 的文化周围的边缘情况,尽管效率可能较低。特别有一个问题:当当前日期是星期日时,需要减去 6 天才能得到一周的第一天星期一。这里的许多其他解决方案最终都会增加一天。请注意此处针对已提出的其他方法的评论。不过我同意,这样做可以更有效。它并不像乍一看那么微不足道。 (2认同)

小智 18

丑陋但它至少给出了正确的日期

按系统设置的周开始:

    public static DateTime FirstDateInWeek(this DateTime dt)
    {
        while (dt.DayOfWeek != System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek)
            dt = dt.AddDays(-1);
        return dt;
    }
Run Code Online (Sandbox Code Playgroud)

无:

    public static DateTime FirstDateInWeek(this DateTime dt, DayOfWeek weekStartDay)
    {
        while (dt.DayOfWeek != weekStartDay)
            dt = dt.AddDays(-1);
        return dt;
    }
Run Code Online (Sandbox Code Playgroud)

  • 由于其简单性和可读性,这确实值得更多投票。 (2认同)
  • 我必须承认这是最万无一失的方法。只需查看其他答案遇到的所有边缘情况即可。我得到了关于效率的争论,但最糟糕的情况是您从一周的最后一天开始,并且必须调用 AddDays 六次才能回到开始。在最坏的情况下,这比其他解决方案多五倍,但这些解决方案还必须处理其他数值计算来得出偏移量。除了对性能最敏感的应用程序之外,这种差异在所有应用程序中可能都是微不足道的。 (2认同)

Joe*_*orn 14

让我们结合文化安全答案和扩展方法答案:

public static class DateTimeExtensions
{
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
        DayOfWeek fdow = ci.DateTimeFormat.FirstDayOfWeek;
        return DateTime.Today.AddDays(-(DateTime.Today.DayOfWeek- fdow));
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 你的函数中既没有dt也没有startOfWeek,我想第一个应该用来代替DateTime.Today (11认同)
  • 我知道这是一个古老的答案,但在很多层面都是错的; 除了完全忽略方法参数之外,数学将使它在许多情况下选择*future*date.这应该写成使用`dt`代替`DateTime.Today`,将数学包装在`(offset + 7)%7`中以确保负偏移,使用单参数方法*overload*将当前文化的`FirstDayOfWeek`作为`startOfWeek`参数传递,并且可能(取决于规范)将零偏移强制为7天偏移,以便"如果已经是星期二","上周二"今天不会返回. (6认同)
  • 该问题的上下文是希望以与.Today或.Now相同的方式使用Datetime之外的其他属性.我同意这很尴尬,但这就是要求的. (2认同)

ljs*_*ljs 9

这可能是一个黑客,但你可以将.DayOfWeek属性转换为int(它是一个枚举,因为它的基础数据类型没有更改,默认为int)并使用它来确定一周的前一个开始.

看起来DayOfWeek枚举中指定的星期在星期日开始,所以如果我们从这个值中减去1,它将等于星期一在当前日期之前的天数.我们还需要将星期日(0)映射到等于7,因此给定1 - 7 = -6星期日将映射到上一个星期一: -

DateTime now = DateTime.Now;
int dayOfWeek = (int)now.DayOfWeek;
dayOfWeek = dayOfWeek == 0 ? 7 : dayOfWeek;
DateTime startOfWeek = now.AddDays(1 - (int)now.DayOfWeek);
Run Code Online (Sandbox Code Playgroud)

上周日的代码更简单,因为我们无需进行此调整: -

DateTime now = DateTime.Now;
int dayOfWeek = (int)now.DayOfWeek;
DateTime startOfWeek = now.AddDays(-(int)now.DayOfWeek);
Run Code Online (Sandbox Code Playgroud)


Ski*_*izz 8

这会给你前一个星期天(我想):

DateTime t = DateTime.Now;
t -= new TimeSpan ((int) t.DayOfWeek, 0, 0, 0);
Run Code Online (Sandbox Code Playgroud)


小智 8

对于星期一

DateTime startAtMonday = DateTime.Now.AddDays(DayOfWeek.Monday - DateTime.Now.DayOfWeek);
Run Code Online (Sandbox Code Playgroud)

周日

DateTime startAtSunday = DateTime.Now.AddDays(DayOfWeek.Sunday- DateTime.Now.DayOfWeek);
Run Code Online (Sandbox Code Playgroud)

  • 当这一天是星期日时,这不起作用。它给出的是下周一,而不是本周的开始。 (3认同)

Muh*_*bas 7

步骤1:

创建静态类

public static class TIMEE
{
    public static DateTime StartOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        int diff = (7 + (dt.DayOfWeek - startOfWeek)) % 7;
        return dt.AddDays(-1 * diff).Date;
    }

    public static DateTime EndOfWeek(this DateTime dt, DayOfWeek startOfWeek)
    {
        int diff = (7 - (dt.DayOfWeek - startOfWeek)) % 7;
        return dt.AddDays(1 * diff).Date;
    }
}
Run Code Online (Sandbox Code Playgroud)

第 2 步:使用此类获取一周的开始日和结束日

DateTime dt = TIMEE.StartOfWeek(DateTime.Now ,DayOfWeek.Monday);
DateTime dt1 = TIMEE.EndOfWeek(DateTime.Now, DayOfWeek.Sunday);
Run Code Online (Sandbox Code Playgroud)

  • 根据我编写的单元测试,周末需要“(6 - (dt.DayOfWeek - startOfWeek)) % 7”。 (3认同)

Mat*_*zen 5

将所有内容放在一起,通过全球化并允许指定一周的第一天作为我们通话的一部分

public static DateTime StartOfWeek ( this DateTime dt, DayOfWeek? firstDayOfWeek )
{
    DayOfWeek fdow;

    if ( firstDayOfWeek.HasValue  )
    {
        fdow = firstDayOfWeek.Value;
    }
    else
    {
        System.Globalization.CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
        fdow = ci.DateTimeFormat.FirstDayOfWeek;
    }

    int diff = dt.DayOfWeek - fdow;

    if ( diff < 0 )
    {
        diff += 7;
    }

    return dt.AddDays( -1 * diff ).Date;

}
Run Code Online (Sandbox Code Playgroud)


小智 5

using System;
using System.Globalization;

namespace MySpace
{
    public static class DateTimeExtention
    {
        // ToDo: Need to provide culturaly neutral versions.

        public static DateTime GetStartOfWeek(this DateTime dt)
        {
            DateTime ndt = dt.Subtract(TimeSpan.FromDays((int)dt.DayOfWeek));
            return new DateTime(ndt.Year, ndt.Month, ndt.Day, 0, 0, 0, 0);
        }

        public static DateTime GetEndOfWeek(this DateTime dt)
        {
            DateTime ndt = dt.GetStartOfWeek().AddDays(6);
            return new DateTime(ndt.Year, ndt.Month, ndt.Day, 23, 59, 59, 999);
        }

        public static DateTime GetStartOfWeek(this DateTime dt, int year, int week)
        {
            DateTime dayInWeek = new DateTime(year, 1, 1).AddDays((week - 1) * 7);
            return dayInWeek.GetStartOfWeek();
        }

        public static DateTime GetEndOfWeek(this DateTime dt, int year, int week)
        {
            DateTime dayInWeek = new DateTime(year, 1, 1).AddDays((week - 1) * 7);
            return dayInWeek.GetEndOfWeek();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

  • 首先,欢迎来到社区:)这个问题已有几个高质量的答案,其中大部分都是在七年前提出问题时发布的.尽管尝试回答诸如此类之类的简单问题以提高您的编程能力可能是一项值得的练习,但在当前状态下发布此答案并不会增加任何问题.如果你的答案有一些新颖的东西,请用几句话来解释它是如何不同以及为什么它会变得更好. (3认同)