Как получить различие между двумя датами в году/Месяце/Неделе/Дне?

Swift 4 ответ:

func scaleDown(image: UIImage, withSize: CGSize) -> UIImage {
    let scale = UIScreen.main.scale
    UIGraphicsBeginImageContextWithOptions(withSize, false, scale)
    image.draw(in: CGRect(x: 0, y: 0, width: withSize.width, height: withSize.height))
    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage!
}
46
задан Nosredna 5 July 2009 в 16:51
поделиться

7 ответов

Это на самом деле довольно сложно . Другое общее количество дней может привести к тому же результату. Например:

  • 19 июня 2008 г. по 19 июня 2010 г. = 2 года, но также 365 * 2 дня

  • 19 июня 2006 г. по 19 июня 2008 г. = 2 года, но также 365 + 366 дней из-за високосных лет

. Вы можете вычесть годы, пока не дойдете до точки, где у вас есть две даты, разделенные меньше чем на год. Затем вычтите месяцы, пока не дойдете до точки, где у вас есть две даты, которые отличаются друг от друга менее чем в месяц.

Дальнейшая путаница: вычесть (или добавить) месяцы сложно, если вы можете начать с даты «30 марта». - что месяцем раньше этого?

Еще одна путаница ( может не иметь значения): даже день - это не всегда 24 часа. Кто-нибудь сберегает дневное время?

Еще одна путаница (почти наверняка не актуальна): даже минута не всегда 60 секунд. Високосные секунды очень сбивают с толку ...

Я не знаю ' У меня есть время, чтобы выработать точный правильный способ сделать это прямо сейчас - этот ответ в основном призван подчеркнуть тот факт, что это не так просто, как может показаться.

РЕДАКТИРОВАТЬ: К сожалению, мне не хватит пора ответить на этот вопрос полностью. Я бы посоветовал вам начать с определения структуры, представляющей Период :

public struct Period
{
    private readonly int days;
    public int Days { get { return days; } }
    private readonly int months;
    public int Months { get { return months; } }
    private readonly int years;
    public int Years { get { return years; } }

    public Period(int years, int months, int days)
    {
        this.years = years;
        this.months = months;
        this.days = days;
    }

    public Period WithDays(int newDays)
    {
        return new Period(years, months, newDays);
    }

    public Period WithMonths(int newMonths)
    {
        return new Period(years, newMonths, days);
    }

    public Period WithYears(int newYears)
    {
        return new Period(newYears, months, days);
    }

    public static DateTime operator +(DateTime date, Period period)
    {
        // TODO: Implement this!
    }

    public static Period Difference(DateTime first, DateTime second)
    {
        // TODO: Implement this!
    }
}

Я предлагаю вам сначала реализовать оператор +, который должен информировать метод Difference - вы должны убедиться, что first + (Period.Difference (first, second)) == second для всех первых / вторых значений.

Начните с написания целого ряда модульные тесты - сначала «легкие» случаи, затем переходят к сложным с високосными годами. Я знаю, что нормальный подход - писать по одному тесту за раз, но я Я лично проведу мозговой штурм по их группе, прежде чем начинать какую-либо работу по внедрению.

Дайте себе день, чтобы правильно реализовать это. Это непростой вопрос.

Обратите внимание, что я опустил здесь недели - это значение, по крайней мере, простое, потому что это всегда 7 дней. Итак, учитывая (положительный) период, у вас будет:

int years = period.Years;
int months = period.Months;
int weeks = period.Days / 7;
int daysWithinWeek = period.Days % 7;

(Я предлагаю вам даже не думать о отрицательных периодах - убедитесь, что все положительно, все время.)

34
ответ дан 26 November 2019 в 20:17
поделиться

Используйте метод Subtract объекта DateTime , который возвращает TimeSpan ...

DateTime dt1 = new DateTime(2009, 3, 14);
DateTime dt2 = new DateTime(2008, 3, 15);

TimeSpan ts = dt1.Subtract(dt2);

Double days = ts.TotalDays;
Double hours = ts.TotalHours;
Double years = ts.TotalDays / 365;
0
ответ дан 26 November 2019 в 20:17
поделиться

Если вы вычтите два экземпляра DateTime, вернет экземпляр TimeSpan , который будет представлять разницу между двумя датами.

]
2
ответ дан 26 November 2019 в 20:17
поделиться

Вычтите два экземпляра DateTime , чтобы получить TimeSpan , у которого есть свойство Days . (Например, в PowerShell):

PS > ([datetime]::today - [datetime]"2009-04-07")


Days              : 89
Hours             : 0
Minutes           : 0
Seconds           : 0
Milliseconds      : 0
Ticks             : 76896000000000
TotalDays         : 89
TotalHours        : 2136
TotalMinutes      : 128160
TotalSeconds      : 7689600
TotalMilliseconds : 7689600000

Преобразование дней в годы или недели относительно просто (дни в году могут быть 365, 365,25, ... в зависимости от контекста). Месяцы намного сложнее, потому что без базовой даты вы не знаете, какая длина месяца применяется.

Предполагая, что вы хотите начать с базовой даты, вы можете постепенно вычитать при подсчете первых лет (проверка на високосные годы), затем месяца длины (индексация от startDate.Month), затем недели (оставшиеся дни делятся на 7) и затем дни (остаток).

Необходимо рассмотреть множество крайних случаев, например, 2005-03-01 - это один год с 2004 по 2004 год. 03-01,

4
ответ дан 26 November 2019 в 20:17
поделиться

Високосные годы и неравные месяцы на самом деле делают эту проблему нетривиальной. Я уверен, что кто-то может придумать более эффективный способ, но вот один вариант - сначала приблизиться с малой стороны и отрегулировать (непроверено):

public static void GetDifference(DateTime date1, DateTime date2, out int Years, 
    out int Months, out int Weeks, out int Days)
{
    //assumes date2 is the bigger date for simplicity

    //years
    TimeSpan diff = date2 - date1;
    Years = diff.Days / 366;
    DateTime workingDate = date1.AddYears(Years);

    while(workingDate.AddYears(1) <= date2)
    {
        workingDate = workingDate.AddYears(1);
        Years++;
    }

    //months
    diff = date2 - workingDate;
    Months = diff.Days / 31;
    workingDate = workingDate.AddMonths(Months);

    while(workingDate.AddMonths(1) <= date2)
    {
        workingDate = workingDate.AddMonths(1);
        Months++;
    }

    //weeks and days
    diff = date2 - workingDate;
    Weeks = diff.Days / 7; //weeks always have 7 days
    Days = diff.Days % 7;
}
15
ответ дан 26 November 2019 в 20:17
поделиться
DateTime dt1 = new DateTime(2009, 3, 14);
DateTime dt2 = new DateTime(2008, 3, 15);

int diffMonth = Math.Abs((dt2.Year - dt1.Year)*12 + dt1.Month - dt2.Month)
2
ответ дан 26 November 2019 в 20:17
поделиться

А как насчет использования System.Data.Linq пространства имен и его SqlMethods.DateDiffMonth?

Например, скажем:

DateTime starDT = {01-Jul-2009 12:00:00 AM}
DateTime endDT = {01-Nov-2009 12:00:00 AM}

Тогда:

int monthDiff = System.Data.Linq.SqlClient.SqlMethods.DateDiffMonth(startDT, endDT);

==> 4

В классе DateDiff существуют другие SqlMethods статические методы.

.
10
ответ дан 26 November 2019 в 20:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: