Невозможно назначить Int из функции расширения даты

Мне нужно узнать, сколько дней осталось от двух дат, поэтому я использовал этот код, который нашел в Интернете.

extension Date {

    func years(_ sinceDate: Date) -> Int? {
        return Calendar.current.dateComponents([.year], from: sinceDate, to: self).year
    }

    func months(_ sinceDate: Date) -> Int? {
        return Calendar.current.dateComponents([.month], from: sinceDate, to: self).month
    }

    func days(_ sinceDate: Date) -> Int? {
        return Calendar.current.dateComponents([.day], from: sinceDate, to: self).day
    }

    func hours(_ sinceDate: Date) -> Int? {
        return Calendar.current.dateComponents([.hour], from: sinceDate, to: self).hour
    }

    func minutes(_ sinceDate: Date) -> Int? {
        return Calendar.current.dateComponents([.minute], from: sinceDate, to: self).minute
    }

    func seconds(_ sinceDate: Date) -> Int? {
        return Calendar.current.dateComponents([.second], from: sinceDate, to: self).second
    }  
}

который является расширением класса Date.

Я столкнулся с проблемой при использовании этих функций, у меня есть эта функция

func countDays() {
        if let daysLeft = Date.days(targetDate) {
            self.daysLeft = daysLeft
        }
    }

но Xcode говорит мне, что

Инициализатор для условной привязки должен иметь необязательный тип, а не '(Date) -> Int?'

Итак, затем я попробовал эту функцию

func countDays() {
        let daysLeft = Date.days(targetDate)
        self.daysLeft = daysLeft
    }

Тем не менее Xcode говорит мне, что

Невозможно присвоить значение типа '(Date) -> Int?' ввести «Int»

Я пытался создать проект несколько раз, потому что думал, что это может быть ошибка, но проблема остается.

Может ли кто-нибудь указать, в чем может быть проблема здесь? Заранее спасибо!

Обновлено: я уже пытался принудительно развернуть возвращаемые значения, подобные этому

func years(_ sinceDate: Date) -> Int {
        return Calendar.current.dateComponents([.year], from: sinceDate, to: self).year!
    }

Тем не менее Xcode говорит мне то же самое Невозможно присвоить значение типа «(Дата) -> Int» для типа «Int»

Не связано с вашим вопросом, но почему бы вам просто не развернуть результат? Каждая дата имеет компонент года. Это никогда не подведет.

Leo Dabus 10.04.2019 21:28
func years(_ sinceDate: Date) -> Int {return Calendar.current.dateComponents([.year], from: sinceDate, to: self).year!}
Leo Dabus 10.04.2019 21:28

Проблема все еще остается, я пробовал все эти виды редактирования, но Xcode все еще дает мне Невозможно присвоить значение типа «(Дата) -> Int» для типа «Int»

Mattia Righetti 10.04.2019 21:29

изменение свойства return потребует удаления ключевого слова if. пожалуйста, обновите свой вопрос с вашим фактическим кодом. Кстати, вы должны добавить лучшее описательное имя параметра. что-то вроде func years(since date: Date) -> Int {

Leo Dabus 10.04.2019 21:29

Проблема здесь в том, что Xcode видит это возвращаемое значение как (Date) -> Int независимо от того, как я пишу эти функции. Я собираюсь отредактировать OP, чтобы показать, что

Mattia Righetti 10.04.2019 21:32
let years = Date().years(since: targetDate)
Leo Dabus 10.04.2019 21:33

Это Date() помогло, почему я не могу просто написать Date.method, как я иногда делаю?

Mattia Righetti 10.04.2019 21:36

Это не статический метод. Вам нужен экземпляр даты

Leo Dabus 10.04.2019 21:37

Даже если я объявлю его статическим, это не сработает. Как бы вы отредактировали одну из моих функций в статической функции? Потому что простое написание static перед ним заставит Xcode снова жаловаться, как я написал в комментарии ниже.

Mattia Righetti 10.04.2019 21:38

попробуй extension Date { static func days(since date: Date) -> Int { return Calendar.current.dateComponents([.day], from: date, to: Date()).day! } } Date.days(since: targetDate)

Leo Dabus 10.04.2019 21:41

Давайте продолжить обсуждение в чате.

Mattia Righetti 10.04.2019 21:42

Обратите внимание, что в этом случае я не рекомендую объявлять ваш метод статическим. Я бы оставил его как метод экземпляра. Я бы на самом деле использовал вычисляемое свойство extension Date { var daysSinceNow: Int { return Calendar.current.dateComponents([.day], from: Date(), to: self).day! } } Calendar.current.date(byAdding: DateComponents(day: -2), to: Date())!.daysSinceNow // -2

Leo Dabus 10.04.2019 21:50
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
12
65
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Вы вызываете функцию для типа Date. Однако функция не static. Вам нужно создать экземпляр даты и вызвать для него функцию:

let now = Date()
if let daysLeft = now.days(targetDate) {
   self.daysLeft = daysLeft
}

Раньше я пытался объявить функции расширения статическими, но это дало мне эту ошибку: Тип выражения неоднозначен без дополнительного контекста в файле расширения. Есть ли более чистый способ написать эту функцию, чтобы мне просто нужно было написать Date.days(...)?

Mattia Righetti 10.04.2019 21:26

@MattiaRighetti Вы вычисляете разницу между двумя датами. Либо вы должны передать оба параметра, либо self является одним из них. Вы можете использовать функцию static, только если вы передаете обе в качестве параметров.

Sulthan 10.04.2019 21:34

Правильно, вызов Date() устраняет проблему, но как мне объявить функцию, чтобы она могла вызывать Date.days(tagetDate) без () после Date? Написание static перед func заставляет Xcode жаловаться

Mattia Righetti 10.04.2019 21:42

@MattiaRighetti Повторяю, если вы хотите вызвать Date.days(...), вам нужно два параметра, например. static func days(since: Date, target: Date).

Sulthan 10.04.2019 21:48

Почему бы не использовать стандартный функционал класса Calendar

let days = Calendar.current.dateComponents([.day], from: date1, to: date2)

пример

let date1 = Date(timeIntervalSinceNow: -800000)
print(date1)
let date2 = Date()
print(date2)

let days = Calendar.current.dateComponents([.day], from: date1, to: date2)
if let count = days.day {
    print(count)
}

Урожайность

2019-04-01 13:24:14 +0000
2019-04-10 19:37:34 +0000
9

Я просто хотел иметь более чистый и менее избыточный код, поэтому я написал это расширение.

Mattia Righetti 10.04.2019 21:39

Другие вопросы по теме