두 날짜 간의 월차
C#의 두 날짜 간의 월차 계산 방법은 무엇입니까?
VB와 한 것이 ?DateDiff()
C# 서 c 。나는 몇 년이나 떨어져 있는 두 날짜의 달 차이를 찾아야 한다..TimeSpan
들면 다음과 같습니다.
TimeSpan ts = date1 - date2;
일 단위로 데이터를 얻을 수 있습니다.이 숫자를 30으로 나누고 싶지 않습니다. 왜냐하면 매달 30일은 아니고 두 오퍼랜드 값이 서로 상당히 다르기 때문에 30으로 나누면 잘못된 값이 나올 수 있기 때문입니다.
좋은 의견이라도 있나?
해당 월의 요일이 무관하다고 가정할 경우(즉, 2011.1.1과 2010.12.31의 차이는 1), date1 > date2는 양의 값을, date2 > date1은 음의 값을 나타냅니다.
((date1.Year - date2.Year) * 12) + date1.Month - date2.Month
또는 두 날짜 사이에 대략적인 '평균 개월' 수를 원하는 경우, 매우 큰 날짜 차이를 제외한 모든 날짜에 대해 다음을 사용할 수 있습니다.
date1.Subtract(date2).Days / (365.25 / 12)
후자의 솔루션을 사용하는 경우는, 유닛 테스트에서는, 사용의 애플리케이션이 동작하도록 설계되어 있는 가장 광범위한 날짜를 기술해, 그에 따라 계산 결과를 검증할 필요가 있습니다.
업데이트(Gary 덕분에)
'평균 월' 방법을 사용하는 경우, '연간 평균 일수'에 사용할 수 있는 조금 더 정확한 숫자는 365.2425입니다.
을 위한 .DateTimeSpan
TimeSpan
단, 시간 컴포넌트 외에 모든 날짜 컴포넌트가 포함되어 있습니다.
사용방법:
void Main()
{
DateTime compareTo = DateTime.Parse("8/13/2010 8:33:21 AM");
DateTime now = DateTime.Parse("2/9/2012 10:10:11 AM");
var dateSpan = DateTimeSpan.CompareDates(compareTo, now);
Console.WriteLine("Years: " + dateSpan.Years);
Console.WriteLine("Months: " + dateSpan.Months);
Console.WriteLine("Days: " + dateSpan.Days);
Console.WriteLine("Hours: " + dateSpan.Hours);
Console.WriteLine("Minutes: " + dateSpan.Minutes);
Console.WriteLine("Seconds: " + dateSpan.Seconds);
Console.WriteLine("Milliseconds: " + dateSpan.Milliseconds);
}
출력:
1년차: 1 일
월: 5 월
: 일 : 27 일
1:00: 1
:00: 36
° : 50
0 리리: 0
DateTimeSpan
ㄴ, ㄴ, ㄴ, ㄴ, ㄴ, ㄹ 수 있다.CompareDates
어디든지 상관없습니다.또한 어느 날짜가 다른 날짜보다 먼저 오는지는 중요하지 않습니다.
public struct DateTimeSpan
{
public int Years { get; }
public int Months { get; }
public int Days { get; }
public int Hours { get; }
public int Minutes { get; }
public int Seconds { get; }
public int Milliseconds { get; }
public DateTimeSpan(int years, int months, int days, int hours, int minutes, int seconds, int milliseconds)
{
Years = years;
Months = months;
Days = days;
Hours = hours;
Minutes = minutes;
Seconds = seconds;
Milliseconds = milliseconds;
}
enum Phase { Years, Months, Days, Done }
public static DateTimeSpan CompareDates(DateTime date1, DateTime date2)
{
if (date2 < date1)
{
var sub = date1;
date1 = date2;
date2 = sub;
}
DateTime current = date1;
int years = 0;
int months = 0;
int days = 0;
Phase phase = Phase.Years;
DateTimeSpan span = new DateTimeSpan();
int officialDay = current.Day;
while (phase != Phase.Done)
{
switch (phase)
{
case Phase.Years:
if (current.AddYears(years + 1) > date2)
{
phase = Phase.Months;
current = current.AddYears(years);
}
else
{
years++;
}
break;
case Phase.Months:
if (current.AddMonths(months + 1) > date2)
{
phase = Phase.Days;
current = current.AddMonths(months);
if (current.Day < officialDay && officialDay <= DateTime.DaysInMonth(current.Year, current.Month))
current = current.AddDays(officialDay - current.Day);
}
else
{
months++;
}
break;
case Phase.Days:
if (current.AddDays(days + 1) > date2)
{
current = current.AddDays(days);
var timespan = date2 - current;
span = new DateTimeSpan(years, months, days, timespan.Hours, timespan.Minutes, timespan.Seconds, timespan.Milliseconds);
phase = Phase.Done;
}
else
{
days++;
}
break;
}
}
return span;
}
}
할 수 있다
if ( date1.AddMonths(x) > date2 )
정확한 월수를 원하는 경우 항상 플러스(2000-01-15, 2000-02-14 returns 0)로 합니다.완전한 달은 다음 달 같은 날에 도달하는 것을 고려합니다(나이 계산 등).
public static int GetMonthsBetween(DateTime from, DateTime to)
{
if (from > to) return GetMonthsBetween(to, from);
var monthDiff = Math.Abs((to.Year * 12 + (to.Month - 1)) - (from.Year * 12 + (from.Month - 1)));
if (from.AddMonths(monthDiff) > to || to.Day < from.Day)
{
return monthDiff - 1;
}
else
{
return monthDiff;
}
}
편집 이유: 다음과 같은 경우 이전 코드가 올바르지 않습니다.
new { From = new DateTime(1900, 8, 31), To = new DateTime(1901, 8, 30), Result = 11 },
Test cases I used to test the function:
var tests = new[]
{
new { From = new DateTime(1900, 1, 1), To = new DateTime(1900, 1, 1), Result = 0 },
new { From = new DateTime(1900, 1, 1), To = new DateTime(1900, 1, 2), Result = 0 },
new { From = new DateTime(1900, 1, 2), To = new DateTime(1900, 1, 1), Result = 0 },
new { From = new DateTime(1900, 1, 1), To = new DateTime(1900, 2, 1), Result = 1 },
new { From = new DateTime(1900, 2, 1), To = new DateTime(1900, 1, 1), Result = 1 },
new { From = new DateTime(1900, 1, 31), To = new DateTime(1900, 2, 1), Result = 0 },
new { From = new DateTime(1900, 8, 31), To = new DateTime(1900, 9, 30), Result = 0 },
new { From = new DateTime(1900, 8, 31), To = new DateTime(1900, 10, 1), Result = 1 },
new { From = new DateTime(1900, 1, 1), To = new DateTime(1901, 1, 1), Result = 12 },
new { From = new DateTime(1900, 1, 1), To = new DateTime(1911, 1, 1), Result = 132 },
new { From = new DateTime(1900, 8, 31), To = new DateTime(1901, 8, 30), Result = 11 },
};
이 방법의 사용법을 VB에서 확인했습니다.MSDN 경유로 NET을 사용하고 있으며, 사용 빈도가 높은 것 같습니다.C#에는 이러한 기본 제공 메서드가 없습니다.C#에서는 VB를 호출할 수 있습니다.
Microsoft.VisualBasic.dll
자료로Microsoft.VisualBasic.DateAndTime.DateDiff
의 코드로
노다 시간 사용:
LocalDate start = new LocalDate(2013, 1, 5);
LocalDate end = new LocalDate(2014, 6, 1);
Period period = Period.Between(start, end, PeriodUnits.Months);
Console.WriteLine(period.Months); // 16
날짜에 관계없이 월별 차이(시작 및 종료 포함)를 얻으려면:
DateTime start = new DateTime(2013, 1, 1);
DateTime end = new DateTime(2014, 2, 1);
var diffMonths = (end.Month + end.Year * 12) - (start.Month + start.Year * 12);
예를 들어 월/년만 입력되는 고용 날짜에 맞춰 간단한 작업이 필요했기 때문에, 근무 연도와 월을 구분하고 싶었습니다.이것은 내가 사용하는 것입니다.여기는 유용성만을 목적으로 합니다.
public static YearsMonths YearMonthDiff(DateTime startDate, DateTime endDate) {
int monthDiff = ((endDate.Year * 12) + endDate.Month) - ((startDate.Year * 12) + startDate.Month) + 1;
int years = (int)Math.Floor((decimal) (monthDiff / 12));
int months = monthDiff % 12;
return new YearsMonths {
TotalMonths = monthDiff,
Years = years,
Months = months
};
}
기간 라이브러리의 DateDiff 클래스는 에 사용할 수 있습니다.네트워크:
// ----------------------------------------------------------------------
public void DateDiffSample()
{
DateTime date1 = new DateTime( 2009, 11, 8, 7, 13, 59 );
DateTime date2 = new DateTime( 2011, 3, 20, 19, 55, 28 );
DateDiff dateDiff = new DateDiff( date1, date2 );
// differences
Console.WriteLine( "DateDiff.Months: {0}", dateDiff.Months );
// > DateDiff.Months: 16
// elapsed
Console.WriteLine( "DateDiff.ElapsedMonths: {0}", dateDiff.ElapsedMonths );
// > DateDiff.ElapsedMonths: 4
// description
Console.WriteLine( "DateDiff.GetDescription(6): {0}", dateDiff.GetDescription( 6 ) );
// > DateDiff.GetDescription(6): 1 Year 4 Months 12 Days 12 Hours 41 Mins 29 Secs
} // DateDiffSample
다음은 제가 정확하다고 판단한 달의 차이를 얻기 위한 저의 기여입니다.
namespace System
{
public static class DateTimeExtensions
{
public static Int32 DiffMonths( this DateTime start, DateTime end )
{
Int32 months = 0;
DateTime tmp = start;
while ( tmp < end )
{
months++;
tmp = tmp.AddMonths( 1 );
}
return months;
}
}
}
사용방법:
Int32 months = DateTime.Now.DiffMonths( DateTime.Now.AddYears( 5 ) );
DiffYears라는 다른 메서드를 생성하여 위와 동일한 로직과 While 루프에서 AddMonths 대신 AddYears를 적용할 수 있습니다.
Noda Time https://nodatime.org/ 를 이용하실 수 있습니다.
LocalDate start = new LocalDate(2010, 1, 5);
LocalDate end = new LocalDate(2012, 6, 1);
Period period = Period.Between(start, end, PeriodUnits.Months);
Console.WriteLine(period.Months);
이건 내가 필요로 하는 것에 효과가 있었어.내 경우 날은 항상 마지막 날이기 때문에 상관없었다.
public static int MonthDiff(DateTime d1, DateTime d2){
int retVal = 0;
if (d1.Month<d2.Month)
{
retVal = (d1.Month + 12) - d2.Month;
retVal += ((d1.Year - 1) - d2.Year)*12;
}
else
{
retVal = d1.Month - d2.Month;
retVal += (d1.Year - d2.Year)*12;
}
//// Calculate the number of years represented and multiply by 12
//// Substract the month number from the total
//// Substract the difference of the second month and 12 from the total
//retVal = (d1.Year - d2.Year) * 12;
//retVal = retVal - d1.Month;
//retVal = retVal - (12 - d2.Month);
return retVal;
}
같은 해, 전년, 다른 해 세 가지 경우가 있습니다.
그 달의 요일이 중요하지 않다면...
public int GetTotalNumberOfMonths(DateTime start, DateTime end)
{
// work with dates in the right order
if (start > end)
{
var swapper = start;
start = end;
end = swapper;
}
switch (end.Year - start.Year)
{
case 0: // Same year
return end.Month - start.Month;
case 1: // last year
return (12 - start.Month) + end.Month;
default:
return 12 * (3 - (end.Year - start.Year)) + (12 - start.Month) + end.Month;
}
}
가장 정확한 방법은 분수에 따른 월차이를 반환하는 것입니다.
private double ReturnDiffereceBetweenTwoDatesInMonths(DateTime startDateTime, DateTime endDateTime)
{
double result = 0;
double days = 0;
DateTime currentDateTime = startDateTime;
while (endDateTime > currentDateTime.AddMonths(1))
{
result ++;
currentDateTime = currentDateTime.AddMonths(1);
}
if (endDateTime > currentDateTime)
{
days = endDateTime.Subtract(currentDateTime).TotalDays;
}
return result + days/endDateTime.GetMonthDays;
}
두 날짜의 총 월차에 대한 저의 이해는 필수 부분과 소수 부분이 있습니다(날짜가 중요합니다).
적분 부분은 전체 달의 차이입니다.
부분적인 부분은 시작 월과 종료 월의 하루 중 (보름날에 대한) 비율의 차이입니다.
public static class DateTimeExtensions
{
public static double TotalMonthsDifference(this DateTime from, DateTime to)
{
//Compute full months difference between dates
var fullMonthsDiff = (to.Year - from.Year)*12 + to.Month - from.Month;
//Compute difference between the % of day to full days of each month
var fractionMonthsDiff = ((double)(to.Day-1) / (DateTime.DaysInMonth(to.Year, to.Month)-1)) -
((double)(from.Day-1)/ (DateTime.DaysInMonth(from.Year, from.Month)-1));
return fullMonthsDiff + fractionMonthsDiff;
}
}
이 확장을 사용하면 다음과 같은 결과를 얻을 수 있습니다.
2/29/2000 TotalMonthsDifference 2/28/2001 => 12
2/28/2000 TotalMonthsDifference 2/28/2001 => 12.035714285714286
01/01/2000 TotalMonthsDifference 01/16/2000 => 0.5
01/31/2000 TotalMonthsDifference 01/01/2000 => -1.0
01/31/2000 TotalMonthsDifference 02/29/2000 => 1.0
01/31/2000 TotalMonthsDifference 02/28/2000 => 0.9642857142857143
01/31/2001 TotalMonthsDifference 02/28/2001 => 1.0
여기 적어도 나에게 효과가 있는 간단한 해결책이 있다.루프에서 DateTime의 AddMonth 기능을 사용하기 때문에 가장 빠르지 않을 수 있습니다.
public static int GetMonthsDiff(DateTime start, DateTime end)
{
if (start > end)
return GetMonthsDiff(end, start);
int months = 0;
do
{
start = start.AddMonths(1);
if (start > end)
return months;
months++;
}
while (true);
}
이 간단한 정적 함수는 두 날짜 사이의 월 수를 계산합니다.
- 1.1 ~ 31.1 = 1.0
- 1.4 ~ 15.4 = 0.5
- 16.4 ~ 30.4 = 0.5
- 1.3 ~ 1.4 = 1 + 1/30
함수는 첫 번째 날짜가 두 번째 날짜보다 작다고 가정합니다.음의 시간 간격에 대처하려면 처음에 기호와 변수 스왑을 도입하여 함수를 쉽게 수정할 수 있습니다.
public static double GetDeltaMonths(DateTime t0, DateTime t1)
{
DateTime t = t0;
double months = 0;
while(t<=t1)
{
int daysInMonth = DateTime.DaysInMonth(t.Year, t.Month);
DateTime endOfMonth = new DateTime(t.Year, t.Month, daysInMonth);
int cutDay = endOfMonth <= t1 ? daysInMonth : t1.Day;
months += (cutDay - t.Day + 1) / (double) daysInMonth;
t = new DateTime(t.Year, t.Month, 1).AddMonths(1);
}
return Math.Round(months,2);
}
한 줄의 해법
먼저 두 날짜가 모두 현재 연도인지 확인하고, 전체 연도의 월을 얻지 못하면 시작 연도와 종료 연도에서 월을 추가합니다.
DateTime dateFrom = new DateTime(2019, 2, 1);
DateTime dateTo = new DateTime(2021, 5, 25);
첫 달과 함께
var monthCount = dateFrom.Year != dateTo.Year ? ((dateTo.Year - dateFrom.Year - 1) * 12) + (13 - dateFrom.Month + dateTo.Month) : dateTo.Month - dateFrom.Month + 1;
결과 = 28
첫 달 미포함
monthCount = dateFrom.Year != dateTo.Year ? ((dateTo.Year - dateFrom.Year - 1) * 12) + (12 - dateFrom.Month + dateTo.Month) : dateTo.Month - dateFrom.Month;
결과 = 27
Public Class ClassDateOperation
Private prop_DifferenceInDay As Integer
Private prop_DifferenceInMonth As Integer
Private prop_DifferenceInYear As Integer
Public Function DayMonthYearFromTwoDate(ByVal DateStart As Date, ByVal DateEnd As Date) As ClassDateOperation
Dim differenceInDay As Integer
Dim differenceInMonth As Integer
Dim differenceInYear As Integer
Dim myDate As Date
DateEnd = DateEnd.AddDays(1)
differenceInYear = DateEnd.Year - DateStart.Year
If DateStart.Month <= DateEnd.Month Then
differenceInMonth = DateEnd.Month - DateStart.Month
Else
differenceInYear -= 1
differenceInMonth = (12 - DateStart.Month) + DateEnd.Month
End If
If DateStart.Day <= DateEnd.Day Then
differenceInDay = DateEnd.Day - DateStart.Day
Else
myDate = CDate("01/" & DateStart.AddMonths(1).Month & "/" & DateStart.Year).AddDays(-1)
If differenceInMonth <> 0 Then
differenceInMonth -= 1
Else
differenceInMonth = 11
differenceInYear -= 1
End If
differenceInDay = myDate.Day - DateStart.Day + DateEnd.Day
End If
prop_DifferenceInDay = differenceInDay
prop_DifferenceInMonth = differenceInMonth
prop_DifferenceInYear = differenceInYear
Return Me
End Function
Public ReadOnly Property DifferenceInDay() As Integer
Get
Return prop_DifferenceInDay
End Get
End Property
Public ReadOnly Property DifferenceInMonth As Integer
Get
Return prop_DifferenceInMonth
End Get
End Property
Public ReadOnly Property DifferenceInYear As Integer
Get
Return prop_DifferenceInYear
End Get
End Property
End Class
이건 내 도서관에서 가져온 건데, 두 날짜 사이의 월차를 돌려줄 거야.
public static int MonthDiff(DateTime d1, DateTime d2)
{
int retVal = 0;
// Calculate the number of years represented and multiply by 12
// Substract the month number from the total
// Substract the difference of the second month and 12 from the total
retVal = (d1.Year - d2.Year) * 12;
retVal = retVal - d1.Month;
retVal = retVal - (12 - d2.Month);
return retVal;
}
이와 같은 기능을 가질 수 있습니다.
예를 들어 2012/12/27부터 2012/12/29까지가 3일이 됩니다.마찬가지로 2012/12/15부터 2013/01/15까지는 2013/01/14까지는 한 달이고 15일부터 두 번째 달이 시작됩니다.
2012/12/15부터 2013/01/15까지 두 날짜를 계산에 포함하지 않으려면 두 번째 조건의 "="를 제거할 수 있습니다.
public int GetMonths(DateTime startDate, DateTime endDate)
{
if (startDate > endDate)
{
throw new Exception("Start Date is greater than the End Date");
}
int months = ((endDate.Year * 12) + endDate.Month) - ((startDate.Year * 12) + startDate.Month);
if (endDate.Day >= startDate.Day)
{
months++;
}
return months;
}
다음 내선번호를 사용할 수 있습니다.코드
public static class Ext
{
#region Public Methods
public static int GetAge(this DateTime @this)
{
var today = DateTime.Today;
return ((((today.Year - @this.Year) * 100) + (today.Month - @this.Month)) * 100 + today.Day - @this.Day) / 10000;
}
public static int DiffMonths(this DateTime @from, DateTime @to)
{
return (((((@to.Year - @from.Year) * 12) + (@to.Month - @from.Month)) * 100 + @to.Day - @from.Day) / 100);
}
public static int DiffYears(this DateTime @from, DateTime @to)
{
return ((((@to.Year - @from.Year) * 100) + (@to.Month - @from.Month)) * 100 + @to.Day - @from.Day) / 10000;
}
#endregion Public Methods
}
구현!
int Age;
int years;
int Months;
//Replace your own date
var d1 = new DateTime(2000, 10, 22);
var d2 = new DateTime(2003, 10, 20);
//Age
Age = d1.GetAge();
Age = d2.GetAge();
//positive
years = d1.DiffYears(d2);
Months = d1.DiffMonths(d2);
//negative
years = d2.DiffYears(d1);
Months = d2.DiffMonths(d1);
//Or
Months = Ext.DiffMonths(d1, d2);
years = Ext.DiffYears(d1, d2);
VB를 사용한 보다 간결한 솔루션을 다음에 제시하겠습니다.연도, 월, 일에만 해당하는 Net DateDiff.C#에서도 DateDiff 라이브러리를 로드할 수 있습니다.
date1은 <= date2이어야 합니다.
VB.NET
Dim date1 = Now.AddDays(-2000)
Dim date2 = Now
Dim diffYears = DateDiff(DateInterval.Year, date1, date2) - If(date1.DayOfYear > date2.DayOfYear, 1, 0)
Dim diffMonths = DateDiff(DateInterval.Month, date1, date2) - diffYears * 12 - If(date1.Day > date2.Day, 1, 0)
Dim diffDays = If(date2.Day >= date1.Day, date2.Day - date1.Day, date2.Day + (Date.DaysInMonth(date1.Year, date1.Month) - date1.Day))
C#
DateTime date1 = Now.AddDays(-2000);
DateTime date2 = Now;
int diffYears = DateDiff(DateInterval.Year, date1, date2) - date1.DayOfYear > date2.DayOfYear ? 1 : 0;
int diffMonths = DateDiff(DateInterval.Month, date1, date2) - diffYears * 12 - date1.Day > date2.Day ? 1 : 0;
int diffDays = date2.Day >= date1.Day ? date2.Day - date1.Day : date2.Day + (System.DateTime.DaysInMonth(date1.Year, date1.Month) - date1.Day);
이것은 커크 월의 대답에 대한 응답이다.아직 평점이 부족해서 댓글에 답할 수 없어요.
저는 커크의 솔루션이 마음에 들어서 뻔뻔하게 그것을 뜯어내 코드에 사용하려고 했습니다만, 그것을 훑어보니 너무 복잡하다는 것을 깨달았습니다.불필요한 스위칭과 루프, 퍼블릭컨스트럭터 사용의 의미가 없습니다.
여기 다시 씁니다.
public class DateTimeSpan {
private DateTime _date1;
private DateTime _date2;
private int _years;
private int _months;
private int _days;
private int _hours;
private int _minutes;
private int _seconds;
private int _milliseconds;
public int Years { get { return _years; } }
public int Months { get { return _months; } }
public int Days { get { return _days; } }
public int Hours { get { return _hours; } }
public int Minutes { get { return _minutes; } }
public int Seconds { get { return _seconds; } }
public int Milliseconds { get { return _milliseconds; } }
public DateTimeSpan(DateTime date1, DateTime date2) {
_date1 = (date1 > date2) ? date1 : date2;
_date2 = (date2 < date1) ? date2 : date1;
_years = _date1.Year - _date2.Year;
_months = (_years * 12) + _date1.Month - _date2.Month;
TimeSpan t = (_date2 - _date1);
_days = t.Days;
_hours = t.Hours;
_minutes = t.Minutes;
_seconds = t.Seconds;
_milliseconds = t.Milliseconds;
}
public static DateTimeSpan CompareDates(DateTime date1, DateTime date2) {
return new DateTimeSpan(date1, date2);
}
}
사용방법 1은 거의 동일합니다.
void Main()
{
DateTime compareTo = DateTime.Parse("8/13/2010 8:33:21 AM");
DateTime now = DateTime.Parse("2/9/2012 10:10:11 AM");
var dateSpan = new DateTimeSpan(compareTo, now);
Console.WriteLine("Years: " + dateSpan.Years);
Console.WriteLine("Months: " + dateSpan.Months);
Console.WriteLine("Days: " + dateSpan.Days);
Console.WriteLine("Hours: " + dateSpan.Hours);
Console.WriteLine("Minutes: " + dateSpan.Minutes);
Console.WriteLine("Seconds: " + dateSpan.Seconds);
Console.WriteLine("Milliseconds: " + dateSpan.Milliseconds);
}
사용방법 2, 유사:
void Main()
{
DateTime compareTo = DateTime.Parse("8/13/2010 8:33:21 AM");
DateTime now = DateTime.Parse("2/9/2012 10:10:11 AM");
Console.WriteLine("Years: " + DateTimeSpan.CompareDates(compareTo, now).Years);
Console.WriteLine("Months: " + DateTimeSpan.CompareDates(compareTo, now).Months);
Console.WriteLine("Days: " + DateTimeSpan.CompareDates(compareTo, now).Days);
Console.WriteLine("Hours: " + DateTimeSpan.CompareDates(compareTo, now).Hours);
Console.WriteLine("Minutes: " + DateTimeSpan.CompareDates(compareTo, now).Minutes);
Console.WriteLine("Seconds: " + DateTimeSpan.CompareDates(compareTo, now).Seconds);
Console.WriteLine("Milliseconds: " + DateTimeSpan.CompareDates(compareTo, now).Milliseconds);
}
저 같은 경우에는 시작일로부터 다음 달 오늘 전날까지 또는 시작부터 월말까지 월 전체를 계산해야 합니다.
입니다.★ 2018 ★ 1 ★ 1 ★ 1 ★ 31 ★
: 1일부터 2일까지는 Ex2 : 2018년 5월 1일 2018년 4월 2일
이를 바탕으로 한 저의 솔루션은 다음과 같습니다.
public static DateTime GetMonthEnd(DateTime StartDate, int MonthsCount = 1)
{
return StartDate.AddMonths(MonthsCount).AddDays(-1);
}
public static Tuple<int, int> CalcPeriod(DateTime StartDate, DateTime EndDate)
{
int MonthsCount = 0;
Tuple<int, int> Period;
while (true)
{
if (GetMonthEnd(StartDate) > EndDate)
break;
else
{
MonthsCount += 1;
StartDate = StartDate.AddMonths(1);
}
}
int RemainingDays = (EndDate - StartDate).Days + 1;
Period = new Tuple<int, int>(MonthsCount, RemainingDays);
return Period;
}
사용방법:
Tuple<int, int> Period = CalcPeriod(FromDate, ToDate);
주의: 제 경우 전체 달 이후의 남은 일수를 계산해야 하므로, 귀하의 경우가 아니라면 일수 결과를 무시하거나 메서드 반환을 태플에서 정수로 변경할 수 있습니다.
public static int PayableMonthsInDuration(DateTime StartDate, DateTime EndDate)
{
int sy = StartDate.Year; int sm = StartDate.Month; int count = 0;
do
{
count++;if ((sy == EndDate.Year) && (sm >= EndDate.Month)) { break; }
sm++;if (sm == 13) { sm = 1; sy++; }
} while ((EndDate.Year >= sy) || (EndDate.Month >= sm));
return (count);
}
이 솔루션은 렌탈/구독 계산용입니다.차이가 차감되는 것이 아니라 이 두 날짜 내의 범위입니다.
다른 방법들은 나에게 맞지 않았기 때문에 나는 이것을 성취하기 위해 함수를 작성했다.
public string getEndDate (DateTime startDate,decimal monthCount)
{
int y = startDate.Year;
int m = startDate.Month;
for (decimal i = monthCount; i > 1; i--)
{
m++;
if (m == 12)
{ y++;
m = 1;
}
}
return string.Format("{0}-{1}-{2}", y.ToString(), m.ToString(), startDate.Day.ToString());
}
당신은 항상 추측만 하고 있기 때문에 이에 대한 명확한 답은 많지 않습니다.
이 솔루션에서는 비교를 위해 날짜를 저장한다고 가정한 달 사이의 두 날짜 사이를 계산합니다(즉, 계산에서 해당 월의 날짜가 고려됨을 의미합니다).
예를 들어, 2012년 1월 30일이면 2012년 2월 29일이 한 달이 아니라 2013년 3월 1일이 됩니다.
꽤 철저하게 테스트되고 있습니다.아마 나중에 사용할 때 정리될 것입니다만, 다음과 같습니다.
private static int TotalMonthDifference(DateTime dtThis, DateTime dtOther)
{
int intReturn = 0;
bool sameMonth = false;
if (dtOther.Date < dtThis.Date) //used for an error catch in program, returns -1
intReturn--;
int dayOfMonth = dtThis.Day; //captures the month of day for when it adds a month and doesn't have that many days
int daysinMonth = 0; //used to caputre how many days are in the month
while (dtOther.Date > dtThis.Date) //while Other date is still under the other
{
dtThis = dtThis.AddMonths(1); //as we loop, we just keep adding a month for testing
daysinMonth = DateTime.DaysInMonth(dtThis.Year, dtThis.Month); //grabs the days in the current tested month
if (dtThis.Day != dayOfMonth) //Example 30 Jan 2013 will go to 28 Feb when a month is added, so when it goes to march it will be 28th and not 30th
{
if (daysinMonth < dayOfMonth) // uses day in month max if can't set back to day of month
dtThis.AddDays(daysinMonth - dtThis.Day);
else
dtThis.AddDays(dayOfMonth - dtThis.Day);
}
if (((dtOther.Year == dtThis.Year) && (dtOther.Month == dtThis.Month))) //If the loop puts it in the same month and year
{
if (dtOther.Day >= dayOfMonth) //check to see if it is the same day or later to add one to month
intReturn++;
sameMonth = true; //sets this to cancel out of the normal counting of month
}
if ((!sameMonth)&&(dtOther.Date > dtThis.Date))//so as long as it didn't reach the same month (or if i started in the same month, one month ahead, add a month)
intReturn++;
}
return intReturn; //return month
}
위에서 수행한 우수한 Date Time Span 작업을 바탕으로 코드를 조금 정규화했습니다.이거는 꽤 잘 동작하고 있는 것 같습니다.
public class DateTimeSpan
{
private DateTimeSpan() { }
private DateTimeSpan(int years, int months, int days, int hours, int minutes, int seconds, int milliseconds)
{
Years = years;
Months = months;
Days = days;
Hours = hours;
Minutes = minutes;
Seconds = seconds;
Milliseconds = milliseconds;
}
public int Years { get; private set; } = 0;
public int Months { get; private set; } = 0;
public int Days { get; private set; } = 0;
public int Hours { get; private set; } = 0;
public int Minutes { get; private set; } = 0;
public int Seconds { get; private set; } = 0;
public int Milliseconds { get; private set; } = 0;
public static DateTimeSpan CompareDates(DateTime StartDate, DateTime EndDate)
{
if (StartDate.Equals(EndDate)) return new DateTimeSpan();
DateTimeSpan R = new DateTimeSpan();
bool Later;
if (Later = StartDate > EndDate)
{
DateTime D = StartDate;
StartDate = EndDate;
EndDate = D;
}
// Calculate Date Stuff
for (DateTime D = StartDate.AddYears(1); D < EndDate; D = D.AddYears(1), R.Years++) ;
if (R.Years > 0) StartDate = StartDate.AddYears(R.Years);
for (DateTime D = StartDate.AddMonths(1); D < EndDate; D = D.AddMonths(1), R.Months++) ;
if (R.Months > 0) StartDate = StartDate.AddMonths(R.Months);
for (DateTime D = StartDate.AddDays(1); D < EndDate; D = D.AddDays(1), R.Days++) ;
if (R.Days > 0) StartDate = StartDate.AddDays(R.Days);
// Calculate Time Stuff
TimeSpan T1 = EndDate - StartDate;
R.Hours = T1.Hours;
R.Minutes = T1.Minutes;
R.Seconds = T1.Seconds;
R.Milliseconds = T1.Milliseconds;
// Return answer. Negate values if the Start Date was later than the End Date
if (Later)
return new DateTimeSpan(-R.Years, -R.Months, -R.Days, -R.Hours, -R.Minutes, -R.Seconds, -R.Milliseconds);
return R;
}
}
모든 날을 세는 미친 방법, 초정밀
도우미 클래스:
public class DaysInMonth
{
public int Days { get; set; }
public int Month { get; set; }
public int Year { get; set; }
public bool Full { get; set; }
}
기능:
public static List<DaysInMonth> MonthsDelta(DateTime start, DateTime end)
{
var dates = Enumerable.Range(0, 1 + end.Subtract(start).Days)
.Select(offset => start.AddDays(offset))
.ToArray();
DateTime? prev = null;
int days = 0;
List < DaysInMonth > list = new List<DaysInMonth>();
foreach (DateTime date in dates)
{
if (prev != null)
{
if(date.Month!=prev.GetValueOrDefault().Month)
{
DaysInMonth daysInMonth = new DaysInMonth();
daysInMonth.Days = days;
daysInMonth.Month = prev.GetValueOrDefault().Month;
daysInMonth.Year = prev.GetValueOrDefault().Year;
daysInMonth.Full = DateTime.DaysInMonth(daysInMonth.Year, daysInMonth.Month) == daysInMonth.Days;
list.Add(daysInMonth);
days = 0;
}
}
days++;
prev = date;
}
//------------------ add last
if (days > 0)
{
DaysInMonth daysInMonth = new DaysInMonth();
daysInMonth.Days = days;
daysInMonth.Month = prev.GetValueOrDefault().Month;
daysInMonth.Year = prev.GetValueOrDefault().Year;
daysInMonth.Full = DateTime.DaysInMonth(daysInMonth.Year, daysInMonth.Month) == daysInMonth.Days;
list.Add(daysInMonth);
}
return list;
}
언급URL : https://stackoverflow.com/questions/4638993/difference-in-months-between-two-dates
'IT' 카테고리의 다른 글
가장자리가 아닌 div 안쪽에 테두리 배치 (0) | 2023.04.08 |
---|---|
Powershell에서 부모 디렉토리를 가져오려면 어떻게 해야 합니까? (0) | 2023.04.08 |
HTML에서 "역할" 속성의 목적은 무엇입니까? (0) | 2023.04.08 |
Woocommerce:제목에서 "아카이브"를 삭제하는 방법 (0) | 2023.04.03 |
동적으로 변경된 HTML을 뒤로 단추에 저장 (0) | 2023.04.03 |