C # /. NET TimeSpan
에는 TotalDays
, TotalMinutes
등이 있지만 총 개월 차이에 대한 공식을 알 수는 없습니다. 한 달에 다양한 날과 윤년이 계속 저를 던져 버립니다. TotalMonths를 어떻게받을 수 있습니까 ?
편집 더 명확하지 않은 것에 대해 죄송합니다 : 실제로 이것을 얻을 수는 TimeSpan
없지만 사용 TotalDays
하고 있다고 생각 TotalMinutes
하고 총 달을 얻는 것을 제외하고는 내가 찾고있는 것을 표현하는 좋은 예가 될 것입니다 …
예 : 2009 년 12 월 25 일-2009 년 10 월 6 일 = 총 2 개월 10 월 6 일부터 11 월 5 일까지는 0 개월입니다. 11 월 6 일, 1 개월 2 개월 12 월 6 일
답변
TimeSpan
“월”은 가변 측정 단위이므로을 ( 를) 얻을 수 없습니다 . 직접 계산해야하며 작동 방식을 정확히 파악해야합니다.
예를 들어, 날짜 좋아해야 July 5, 2009
하고 August 4, 2009
한 달 제로 개월 차이를 산출? 당신은 무엇에 대해 다음 중 하나를 양보해야한다고 경우 July 31, 2009
와 August 1, 2009
? 가 그 한 달? 단순히 Month
날짜 값 의 차이입니까 , 아니면 실제 시간 범위와 더 관련이 있습니까? 이러한 모든 규칙을 결정하는 논리는 사소한 것이 아니므로 자신의 규칙을 결정하고 적절한 알고리즘을 구현해야합니다.
날짜 값을 완전히 무시하고 단순히 달의 차이 만 원하는 경우 다음을 사용할 수 있습니다.
public static int MonthDifference(this DateTime lValue, DateTime rValue)
{
return (lValue.Month - rValue.Month) + 12 * (lValue.Year - rValue.Year);
}
이는 상대적인 차이를 반환합니다. 즉, rValue
이보다 크면 lValue
반환 값이 음수입니다. 절대적인 차이를 원하면 다음을 사용할 수 있습니다.
public static int MonthDifference(this DateTime lValue, DateTime rValue)
{
return Math.Abs((lValue.Month - rValue.Month) + 12 * (lValue.Year - rValue.Year));
}
답변
(이것은 오래된 질문이라는 것을 알고 있지만 …)
이다 상대적으로 순수 .NET에서 할 고통. 나는 특히 다음과 같은 것들을 위해 설계된 Noda Time 라이브러리를 추천 합니다.
LocalDate start = new LocalDate(2009, 10, 6);
LocalDate end = new LocalDate(2009, 12, 25);
Period period = Period.Between(start, end);
int months = period.Months;
(다른 옵션도 있습니다. 예를 들어 몇 년 동안 몇 달 동안 만 원하는 경우을 사용합니다 Period period = Period.Between(start, end, PeriodUnits.Months);
)
답변
아마도 월의 분수에 대해 알고 싶지 않을 것입니다. 이 코드는 어떻습니까?
public static class DateTimeExtensions
{
public static int TotalMonths(this DateTime start, DateTime end)
{
return (start.Year * 12 + start.Month) - (end.Year * 12 + end.Month);
}
}
// Console.WriteLine(
// DateTime.Now.TotalMonths(
// DateTime.Now.AddMonths(-1))); // prints "1"
답변
TotalMonths가 의미하는 바를 정의해야합니다.
간단한 정의는 한 달에 30.4 일 (365.25 / 12)입니다.
그 외에도 분수를 포함한 모든 정의는 쓸모없는 것처럼 보이며 더 일반적인 정수 값 (날짜 사이의 월 단위)도 비표준 비즈니스 규칙에 따라 다릅니다.
답변
나는에 아주 간단한 확장 메서드를 작성했습니다 DateTime
과 DateTimeOffset
이 작업을 수행하는. 나는 그것이 TotalMonths
속성 TimeSpan
이 작동 하는 것과 똑같이 작동하기를 원했다 . 그것은 그것을 기반으로하기 때문에 DateTime.AddMonths()
다른 달 길이를 존중하고 인간이 개월 기간으로 이해 한 것을 반환합니다.
(불행히도 TimeSpan에서 확장 방법으로 구현 할 수는 없습니다. 실제 사용 된 날짜에 대한 지식을 유지하지 못하기 때문에 수개월 동안 중요합니다.)
코드와 테스트는 모두 GitHub에서 사용할 수 있습니다 . 코드는 매우 간단합니다.
public static int GetTotalMonthsFrom(this DateTime dt1, DateTime dt2)
{
DateTime earlyDate = (dt1 > dt2) ? dt2.Date : dt1.Date;
DateTime lateDate = (dt1 > dt2) ? dt1.Date : dt2.Date;
// Start with 1 month's difference and keep incrementing
// until we overshoot the late date
int monthsDiff = 1;
while (earlyDate.AddMonths(monthsDiff) <= lateDate)
{
monthsDiff++;
}
return monthsDiff - 1;
}
그리고 모든 단위 테스트 사례를 통과합니다.
// Simple comparison
Assert.AreEqual(1, new DateTime(2014, 1, 1).GetTotalMonthsFrom(new DateTime(2014, 2, 1)));
// Just under 1 month's diff
Assert.AreEqual(0, new DateTime(2014, 1, 1).GetTotalMonthsFrom(new DateTime(2014, 1, 31)));
// Just over 1 month's diff
Assert.AreEqual(1, new DateTime(2014, 1, 1).GetTotalMonthsFrom(new DateTime(2014, 2, 2)));
// 31 Jan to 28 Feb
Assert.AreEqual(1, new DateTime(2014, 1, 31).GetTotalMonthsFrom(new DateTime(2014, 2, 28)));
// Leap year 29 Feb to 29 Mar
Assert.AreEqual(1, new DateTime(2012, 2, 29).GetTotalMonthsFrom(new DateTime(2012, 3, 29)));
// Whole year minus a day
Assert.AreEqual(11, new DateTime(2012, 1, 1).GetTotalMonthsFrom(new DateTime(2012, 12, 31)));
// Whole year
Assert.AreEqual(12, new DateTime(2012, 1, 1).GetTotalMonthsFrom(new DateTime(2013, 1, 1)));
// 29 Feb (leap) to 28 Feb (non-leap)
Assert.AreEqual(12, new DateTime(2012, 2, 29).GetTotalMonthsFrom(new DateTime(2013, 2, 28)));
// 100 years
Assert.AreEqual(1200, new DateTime(2000, 1, 1).GetTotalMonthsFrom(new DateTime(2100, 1, 1)));
// Same date
Assert.AreEqual(0, new DateTime(2014, 8, 5).GetTotalMonthsFrom(new DateTime(2014, 8, 5)));
// Past date
Assert.AreEqual(6, new DateTime(2012, 1, 1).GetTotalMonthsFrom(new DateTime(2011, 6, 10)));
답변
당신은 날짜 시간에 스스로 그것을 해결해야합니다. 스텁 일을 처리하는 방법은 사용하려는 대상에 따라 다릅니다.
한 가지 방법은 월을 계산 한 다음 마지막 날을 수정하는 것입니다. 다음과 같은 것 :
DateTime start = new DateTime(2003, 12, 25);
DateTime end = new DateTime(2009, 10, 6);
int compMonth = (end.Month + end.Year * 12) - (start.Month + start.Year * 12);
double daysInEndMonth = (end - end.AddMonths(1)).Days;
double months = compMonth + (start.Day - end.Day) / daysInEndMonth;
답변
나는 이렇게 할 것입니다 :
static int TotelMonthDifference(this DateTime dtThis, DateTime dtOther)
{
int intReturn = 0;
dtThis = dtThis.Date.AddDays(-(dtThis.Day-1));
dtOther = dtOther.Date.AddDays(-(dtOther.Day-1));
while (dtOther.Date > dtThis.Date)
{
intReturn++;
dtThis = dtThis.AddMonths(1);
}
return intReturn;
}