Arhn - архитектура программирования

Получить общее количество месяцев между двумя датами в Swift

как получить общий месяц между двумя датами? вот нормальный способ получить дату

1) Дата начала: 2020-2-22 10:25:00

2) дата окончания: 2020-3-3 12:34:00

let diffInDate:Int = Calendar.current.dateComponents([.month], from: startDate, to: endDate).month!

если мы проверим в соответствии с указанной выше датой, он вернет 0 из-за отсутствия всего 30 дней.

теперь я хочу получить результат с разницей в месяц, если мы проверим указанную выше дату, она должна вернуть 1, потому что месяц меняется. так есть ли способ проверить разницу дат, включая этот месяц?

03.03.2020

  • не могли бы вы просто вычесть месячные значения двух указанных дат - если только я не понял ваше требование неправильно 03.03.2020
  • @Kelsnare Я согласен, но вам также нужно проверить компонент года 03.03.2020
  • @Kelsnare спасибо за комментарий, на самом деле я хочу перечислить мотыльков между двумя датами 03.03.2020
  • @MitulBhadeshiya Я опубликовал ответ, который отвечает (альтернативному) требованию в вашем комментарии. 03.03.2020

Ответы:


1

Как вы правильно определили, dateComponents(_:from:to:) не считает дробные месяцы.

Однако существует еще одна перегруженная версия, которая вместо этого вычисляет разницу между DateComponents из Dateс. Мы можем удалить все, что нам не нужно (день, час, минута и т. д.) из начала и конца Dates, передать их в эту перегрузку, и она должна сделать расчет за нас. Это аналогично округлению чисел с плавающей запятой перед их вычитанием, так что вы можете получить разницу между их целыми частями.

let startDateComponents = Calendar.current.dateComponents([.year, .month], from: startDate)
let endDateComponents = Calendar.current.dateComponents([.year, .month], from: endDate)
let diffInDate = Calendar.current.dateComponents([.month], from: startDateComponents, to: endDateComponents).month!

Обратите внимание, что мы также получаем компонент year даты начала и окончания, потому что год также необходим для расчета. Но когда мы вычисляем разницу, нам нужно только month.

03.03.2020
  • Отличное решение! Однако, насколько я понимаю вопрос, нужно подсчитывать количество месяцев от одной даты до другой. Используя ваш код с 30.08.2020 по 20.08.2021, будет рассчитано число 12 месяцев. Просто включите .day при получении dateComponents из startDate и endDate, чтобы вместо этого получить результат 11 месяцев. 31.08.2020
  • @AndreiHerford Я думаю, мы поняли вопрос по-разному. OP говорит, что если мы проверим указанную выше дату, она должна вернуть 1, потому что месяц меняется, поэтому, что касается OP, дни не следует учитывать. Пока месяц меняется, он считается месяцем. Месяц нужно изменить 12 раз, чтобы перейти с 2020-08-30 на 2021-08-20, поэтому 12 месяцев правильно в контексте этого вопроса. Это также видно из примера, приведенного в вопросе. С 22.02 по 03.03 - это один месяц, хотя это даже не 30 дней. Если считать дни, то будет 0 месяцев. 31.08.2020

  • 2

    Получите компонент month из startDate и endDate, а затем вычислите разницу между ними, т.е.

    let startMonth = Calendar.current.component(.month, from: startDate)
    let endMonth = Calendar.current.component(.month, from: endDate)
    let difference = abs(endMonth - startMonth) //1
    
    03.03.2020
  • а если год изменится? 03.03.2020
  • Согласно этому ответу, разница между 2019-12-31 и 2020-01-01 составляет 11 месяцев! 03.03.2020

  • 3

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

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

    import UIKit
    
    func makeDate(year: Int, month: Int, day: Int) -> Date {
        let calendar = Calendar(identifier: .gregorian)
        let components = DateComponents(year: year, month: month, day: day) //, hour: hr, minute: min, second: sec)
        return calendar.date(from: components)!
    }
    
    let date1 = makeDate(year: 2016, month: 10, day: 23) // 23 OCT 2016
    let date2 = makeDate(year: 2020, month: 7, day: 10) // 10 JULY 2020
    
    func printMonths(date1: Date, date2: Date) {
    
        guard date1 < date2 else {return}
    
        let month1 = Calendar.current.component(.month, from: date1)
        let month2 = Calendar.current.component(.month, from: date2)
        let year1 = Calendar.current.component(.year, from: date1)
        let year2 = Calendar.current.component(.year, from: date2)
    
        if year1 == year2 {
            for month in month1...month2 {
                print(DateFormatter().monthSymbols[month - 1])
            }
        } else {
            for year in year1...year2 {
                print(year)
                switch year {
                case year1:
                    for month in month1...12 {
                        print("   \(DateFormatter().monthSymbols[month - 1])")
                    }
                case year2:
                    for month in 1...month2 {
                        print("   \(DateFormatter().monthSymbols[month - 1])")
                    }
                default:
                    for month in 1...12 {
                        print("   \(DateFormatter().monthSymbols[month - 1])")
                    }
                }
                print()
            }
        }
    }
    
    printMonths(date1: date1, date2: date2)
    

    Эта функция будет печатать названия месяцев в порядке от date1 до date2, печатая годы для месяцев, если две даты имеют разные годы.

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

    Вывод из примеров дат:

    2016
       October
       November
       December
    
    2017
       January
       February
       March
       April
       May
       June
       July
       August
       September
       October
       November
       December
    
    2018
       January
       February
       March
       April
       May
       June
       July
       August
       September
       October
       November
       December
    
    2019
       January
       February
       March
       April
       May
       June
       July
       August
       September
       October
       November
       December
    
    2020
       January
       February
       March
       April
       May
       June
       July
    
    03.03.2020
    Новые материалы

    Коллекции публикаций по глубокому обучению
    Последние пару месяцев я создавал коллекции последних академических публикаций по различным подполям глубокого обучения в моем блоге https://amundtveit.com - эта публикация дает обзор 25..

    Представляем: Pepita
    Фреймворк JavaScript с открытым исходным кодом Я знаю, что недостатка в фреймворках JavaScript нет. Но я просто не мог остановиться. Я хотел написать что-то сам, со своими собственными..

    Советы по коду Laravel #2
    1-) Найти // You can specify the columns you need // in when you use the find method on a model User::find(‘id’, [‘email’,’name’]); // You can increment or decrement // a field in..

    Работа с временными рядами спутниковых изображений, часть 3 (аналитика данных)
    Анализ временных рядов спутниковых изображений для данных наблюдений за большой Землей (arXiv) Автор: Рольф Симоэс , Жильберто Камара , Жильберто Кейрос , Фелипе Соуза , Педро Р. Андраде ,..

    3 способа решить квадратное уравнение (3-й мой любимый) -
    1. Методом факторизации — 2. Используя квадратичную формулу — 3. Заполнив квадрат — Давайте поймем это, решив это простое уравнение: Мы пытаемся сделать LHS,..

    Создание VR-миров с A-Frame
    Виртуальная реальность (и дополненная реальность) стали главными модными терминами в образовательных технологиях. С недорогими VR-гарнитурами, такими как Google Cardboard , и использованием..

    Демистификация рекурсии
    КОДЕКС Демистификация рекурсии Упрощенная концепция ошеломляющей О чем весь этот шум? Рекурсия, кажется, единственная тема, от которой у каждого начинающего студента-информатика..