답변:
확장 방법을 사용하십시오. 그들은 모든 것에 대한 답입니다. ;)
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;
}
}
다음과 같이 사용할 수 있습니다.
DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Monday);
DateTime dt = DateTime.Now.StartOfWeek(DayOfWeek.Sunday);
dt
UTC이며, 이미 주 등의 시작 2012-09-02 16:00:00Z
입니다 Mon, 03 Sep 2012 00:00:00
현지 시간으로. 따라서 dt
현지 시간 으로 변환 하거나 조금 더 똑똑한 작업을 수행해야합니다. 입력이 UTC 인 경우 결과를 UTC로 리턴해야합니다.
DateTime.Parse("2012-09-02 16:00:00Z")
은 현지 시간에 해당하는 시간을 반환 하며이 메서드는 현지 시간과 동일한 시간을 올바르게 반환합니다. DateTime.Parse("2012-09-02 16:00:00Z").ToUniversalTime()
UTC 시간을 명시 적으로 전달하는 데 사용 하는 경우이 메서드는 16 시간 전에 6 일을 UTC 시간으로 올바르게 반환합니다. 예상대로 정확하게 작동합니다.
dt
. 내가 사용int diff = dt.Date.DayOfWeek - startOfWeek;
내가 생각해 낼 수있는 가장 빠른 방법은 다음과 같습니다.
var sunday = DateTime.Today.AddDays(-(int)DateTime.Today.DayOfWeek);
다른 요일을 시작 날짜로 설정하려면 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);
좀 더 장황하고 문화에 대한 인식 :
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;
CultureInfo.CurrentCulture
그와 같은 실에서 그것을 뽑아내는 대신에 현재 문화권을 얻을 수 있습니다 . 액세스하는 이상한 방법 인 것 같습니다.
Now
속성을 두 번 호출하는 것은 위험합니다 . 현재 시간이 두 통화 사이에 24:00 (또는 자정 12:00)을 지나면 날짜가 변경됩니다.
유창한 DateTime 사용 :
var monday = DateTime.Now.Previous(DayOfWeek.Monday);
var sunday = DateTime.Now.Previous(DayOfWeek.Sunday);
public static DateTime Previous(this DateTime start, DayOfWeek day) { do { start = start.PreviousDay(); } while (start.DayOfWeek != day); return start; }
추악하지만 적어도 올바른 날짜를 돌려줍니다.
시스템에 의해 설정된 시작 시간 :
public static DateTime FirstDateInWeek(this DateTime dt)
{
while (dt.DayOfWeek != System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat.FirstDayOfWeek)
dt = dt.AddDays(-1);
return dt;
}
없이:
public static DateTime FirstDateInWeek(this DateTime dt, DayOfWeek weekStartDay)
{
while (dt.DayOfWeek != weekStartDay)
dt = dt.AddDays(-1);
return dt;
}
문화 안전 답변과 확장 방법 답변을 결합합시다.
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));
}
}
dt
대신에 사용 하도록, 음의 오프셋을 보장하기 위해 DateTime.Today
수학을 래핑하고 , 현재 문화권을 인수 로 전달 (offset + 7) % 7
하는 단일 매개 변수 메소드 과부하 를 사용하고 (사양에 따라) 가능한 "마지막 화요일"이 이미 화요일 인 경우 오늘을 반환하지 않도록 7 일 오프셋으로 0을 오프셋합니다. FirstDayOfWeek
startOfWeek
이것은 약간의 해킹 일 수 있지만 .DayOfWeek 속성을 int로 캐스팅 할 수 있습니다 (열거이며 기본 데이터 유형이 기본 값으로 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);
이전 일요일의 코드는이 조정을하지 않아도되므로 더 간단합니다.
DateTime now = DateTime.Now;
int dayOfWeek = (int)now.DayOfWeek;
DateTime startOfWeek = now.AddDays(-(int)now.DayOfWeek);
월요일
DateTime startAtMonday = DateTime.Now.AddDays(DayOfWeek.Monday - DateTime.Now.DayOfWeek);
일요일
DateTime startAtSunday = DateTime.Now.AddDays(DayOfWeek.Sunday- DateTime.Now.DayOfWeek);
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();
}
}
}
세계화와 함께 모든 것을 통합하고 전화의 일부로 요일을 지정할 수 있습니다.
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;
}
이 코드를 사용하면 주어진주의 첫 번째 날짜와 마지막 날짜를 모두 얻을 수 있습니다. 여기서는 일요일이 첫날이고 토요일이 마지막 날이지만 문화에 따라 두 날짜를 모두 설정할 수 있습니다
DateTime firstDate = GetFirstDateOfWeek(DateTime.Parse("05/09/2012").Date,DayOfWeek.Sunday);
DateTime lastDate = GetLastDateOfWeek(DateTime.Parse("05/09/2012").Date, DayOfWeek.Saturday);
public static DateTime GetFirstDateOfWeek(DateTime dayInWeek, DayOfWeek firstDay)
{
DateTime firstDayInWeek = dayInWeek.Date;
while (firstDayInWeek.DayOfWeek != firstDay)
firstDayInWeek = firstDayInWeek.AddDays(-1);
return firstDayInWeek;
}
public static DateTime GetLastDateOfWeek(DateTime dayInWeek, DayOfWeek firstDay)
{
DateTime lastDayInWeek = dayInWeek.Date;
while (lastDayInWeek.DayOfWeek != firstDay)
lastDayInWeek = lastDayInWeek.AddDays(1);
return lastDayInWeek;
}
월요일에 시작하여 일주일 동안 문제를 해결하지 못하여 일요일에 일요일이 다가 왔습니다. 그래서 약간 수정 하고이 코드로 작업했습니다.
int delta = DayOfWeek.Monday - DateTime.Now.DayOfWeek;
DateTime monday = DateTime.Now.AddDays(delta == 1 ? -6 : delta);
return monday;
dt.AddDays(DayOfWeek.Monday - dt.DayOfWeek);
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;
}
}
2 단계 :이 수업을 사용하여 요일의 시작과 끝을 모두 얻습니다.
DateTime dt =TIMEE.StartOfWeek(DateTime.Now ,DayOfWeek.Monday);
DateTime dt1 = TIMEE.EndOfWeek(DateTime.Now, DayOfWeek.Sunday);
(6 - (dt.DayOfWeek - startOfWeek)) % 7
내가 작성한 단위 테스트에 대해 주말이 필요 했습니다.
다음 방법은 원하는 DateTime을 반환해야합니다. 일요일이 요일의 첫날이되면 true로, 월요일의 경우 false로 전달합니다.
private DateTime getStartOfWeek(bool useSunday)
{
DateTime now = DateTime.Now;
int dayOfWeek = (int)now.DayOfWeek;
if(!useSunday)
dayOfWeek--;
if(dayOfWeek < 0)
{// day of week is Sunday and we want to use Monday as the start of the week
// Sunday is now the seventh day of the week
dayOfWeek = 6;
}
return now.AddDays(-1 * (double)dayOfWeek);
}
예제 주셔서 감사합니다. 나는 항상 "CurrentCulture"요일을 항상 사용해야했고 배열의 경우 정확한 Daynumber를 알아야했습니다. 첫 번째 확장은 다음과 같습니다.
public static class DateTimeExtensions
{
//http://stackoverflow.com/questions/38039/how-can-i-get-the-datetime-for-the-start-of-the-week
//http://stackoverflow.com/questions/1788508/calculate-date-with-monday-as-dayofweek1
public static DateTime StartOfWeek(this DateTime dt)
{
//difference in days
int diff = (int)dt.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek; //sunday=always0, monday=always1, etc.
//As a result we need to have day 0,1,2,3,4,5,6
if (diff < 0)
{
diff += 7;
}
return dt.AddDays(-1 * diff).Date;
}
public static int DayNoOfWeek(this DateTime dt)
{
//difference in days
int diff = (int)dt.DayOfWeek - (int)CultureInfo.CurrentCulture.DateTimeFormat.FirstDayOfWeek; //sunday=always0, monday=always1, etc.
//As a result we need to have day 0,1,2,3,4,5,6
if (diff < 0)
{
diff += 7;
}
return diff + 1; //Make it 1..7
}
}
아직 아무도 정확하게 대답하지 않은 것 같습니다. 누군가가 필요로하는 경우 여기에 솔루션을 붙여 넣을 것입니다. 다음 코드는 요일이 월요일인지 일요일인지에 관계없이 작동합니다.
public static class DateTimeExtension
{
public static DateTime GetFirstDayOfThisWeek(this DateTime d)
{
CultureInfo ci = System.Threading.Thread.CurrentThread.CurrentCulture;
var first = (int)ci.DateTimeFormat.FirstDayOfWeek;
var current = (int)d.DayOfWeek;
var result = first <= current ?
d.AddDays(-1 * (current - first)) :
d.AddDays(first - current - 7);
return result;
}
}
class Program
{
static void Main()
{
System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("en-US");
Console.WriteLine("Current culture set to en-US");
RunTests();
Console.WriteLine();
System.Threading.Thread.CurrentThread.CurrentCulture = CultureInfo.GetCultureInfo("da-DK");
Console.WriteLine("Current culture set to da-DK");
RunTests();
Console.ReadLine();
}
static void RunTests()
{
Console.WriteLine("Today {1}: {0}", DateTime.Today.Date.GetFirstDayOfThisWeek(), DateTime.Today.Date.ToString("yyyy-MM-dd"));
Console.WriteLine("Saturday 2013-03-02: {0}", new DateTime(2013, 3, 2).GetFirstDayOfThisWeek());
Console.WriteLine("Sunday 2013-03-03: {0}", new DateTime(2013, 3, 3).GetFirstDayOfThisWeek());
Console.WriteLine("Monday 2013-03-04: {0}", new DateTime(2013, 3, 4).GetFirstDayOfThisWeek());
}
}
C #의 Modulo는 -1mod7 (6이어야 함, c #은 -1을 반환)에 대해 잘못 작동하므로 "oneliner"솔루션은 다음과 같습니다.
private static DateTime GetFirstDayOfWeek(DateTime date)
{
return date.AddDays(-(((int)date.DayOfWeek - 1) - (int)Math.Floor((double)((int)date.DayOfWeek - 1) / 7) * 7));
}
훌륭한 우산 라이브러리를 사용할 수 있습니다 .
using nVentive.Umbrella.Extensions.Calendar;
DateTime beginning = DateTime.Now.BeginningOfWeek();
그러나, 그들은 않는 주 (속성을 참조 첫날 월요일 저장 것으로 보인다 nVentive.Umbrella.Extensions.Calendar.DefaultDateTimeCalendarExtensions.WeekBeginsOn
이전 지역화 된 솔루션은 조금 더 그래서,). 불행한 사람.
편집 : 질문을 자세히 보면 우산이 실제로 작동하는 것처럼 보입니다.
// Or DateTime.Now.PreviousDay(DayOfWeek.Monday)
DateTime monday = DateTime.Now.PreviousMonday();
DateTime sunday = DateTime.Now.PreviousSunday();
월요일에 이전 월요일을 요청하면 7 일이 지난다는 사실에 주목할 가치가 있습니다. 그러나 BeginningOfWeek
버그 를 사용 하는 것처럼 보이는 경우에도 마찬가지 입니다.
그러면 주 시작과 주 종료 날짜가 모두 반환됩니다.
private string[] GetWeekRange(DateTime dateToCheck)
{
string[] result = new string[2];
TimeSpan duration = new TimeSpan(0, 0, 0, 0); //One day
DateTime dateRangeBegin = dateToCheck;
DateTime dateRangeEnd = DateTime.Today.Add(duration);
dateRangeBegin = dateToCheck.AddDays(-(int)dateToCheck.DayOfWeek);
dateRangeEnd = dateToCheck.AddDays(6 - (int)dateToCheck.DayOfWeek);
result[0] = dateRangeBegin.Date.ToString();
result[1] = dateRangeEnd.Date.ToString();
return result;
}
내 블로그 ZamirsBlog 에 시작 / 종료, 월, 분기 및 연도 계산을위한 전체 코드를 게시 했습니다.
namespace DateTimeExample
{
using System;
public static class DateTimeExtension
{
public static DateTime GetMonday(this DateTime time)
{
if (time.DayOfWeek != DayOfWeek.Monday)
return GetMonday(time.AddDays(-1)); //Recursive call
return time;
}
}
internal class Program
{
private static void Main()
{
Console.WriteLine(DateTime.Now.GetMonday());
Console.ReadLine();
}
}
}
다음은 몇 가지 답변의 조합입니다. 문화를 전달할 수있는 확장 방법을 사용합니다. 문화가 전달되지 않으면 현재 문화권이 사용됩니다. 이를 통해 최대한의 유연성과 재사용이 가능합니다.
/// <summary>
/// Gets the date of the first day of the week for the date.
/// </summary>
/// <param name="date">The date to be used</param>
/// <param name="cultureInfo">If none is provided, the current culture is used</param>
/// <returns>The date of the beggining of the week based on the culture specifed</returns>
public static DateTime StartOfWeek(this DateTime date, CultureInfo cultureInfo=null) =>
date.AddDays(-1 * (7 + (date.DayOfWeek - (cultureInfo??CultureInfo.CurrentCulture).DateTimeFormat.FirstDayOfWeek)) % 7).Date;
사용법 예 :
public static void TestFirstDayOfWeekExtension() {
DateTime date = DateTime.Now;
foreach(System.Globalization.CultureInfo culture in CultureInfo.GetCultures(CultureTypes.UserCustomCulture | CultureTypes.SpecificCultures)) {
Console.WriteLine($"{culture.EnglishName}: {date.ToShortDateString()} First Day of week: {date.StartOfWeek(culture).ToShortDateString()}");
}
}
토요일이나 일요일 또는 요일을 원하지만 현재 주를 초과하지 않는 경우 (토요일)이 코드로 덮여 있습니다.
public static DateTime GetDateInCurrentWeek(this DateTime date, DayOfWeek day)
{
var temp = date;
var limit = (int)date.DayOfWeek;
var returnDate = DateTime.MinValue;
if (date.DayOfWeek == day) return date;
for (int i = limit; i < 6; i++)
{
temp = temp.AddDays(1);
if (day == temp.DayOfWeek)
{
returnDate = temp;
break;
}
}
if (returnDate == DateTime.MinValue)
{
for (int i = limit; i > -1; i++)
{
date = date.AddDays(-1);
if (day == date.DayOfWeek)
{
returnDate = date;
break;
}
}
}
return returnDate;
}
Compile This 'Answer에서 다음 요일을 사용하여 요일을 구하십시오.
public static DateTime GetDayOfWeek(this DateTime dt, DayOfWeek day)
{
int diff = (7 + (dt.DayOfWeek - DayOfWeek.Monday)) % 7;
var monday = dt.AddDays(-1 * diff).Date;
switch (day)
{
case DayOfWeek.Tuesday:
return monday.AddDays(1).Date;
case DayOfWeek.Wednesday:
return monday.AddDays(2).Date;
case DayOfWeek.Thursday:
return monday.AddDays(3).Date;
case DayOfWeek.Friday:
return monday.AddDays(4).Date;
case DayOfWeek.Saturday:
return monday.AddDays(5).Date;
case DayOfWeek.Sunday:
return monday.AddDays(6).Date;
}
return monday;
}
재귀를 사용하는 함수를 작성하십시오. DateTime 객체는 입력이며 함수는 주 시작을 나타내는 새로운 DateTime 객체를 반환합니다.
DateTime WeekBeginning(DateTime input)
{
do
{
if (input.DayOfWeek.ToString() == "Monday")
return input;
else
return WeekBeginning(input.AddDays(-1));
} while (input.DayOfWeek.ToString() == "Monday");
}
이 방법으로 계산하면 새 요일의 시작을 나타내는 요일 (월요일을 선택한 예)을 선택할 수 있습니다.
월요일 인 날짜에 대해이 계산을 수행 하면 이전 월요일이 아닌 현재 월요일 이 제공됩니다 .
//Replace with whatever input date you want
DateTime inputDate = DateTime.Now;
//For this example, weeks start on Monday
int startOfWeek = (int)DayOfWeek.Monday;
//Calculate the number of days it has been since the start of the week
int daysSinceStartOfWeek = ((int)inputDate.DayOfWeek + 7 - startOfWeek) % 7;
DateTime previousStartOfWeek = inputDate.AddDays(-daysSinceStartOfWeek);
int diff = dayOfWeek - dt.DayOfWeek; return dt.AddDays(diff).Date;