【问题标题】:How do you add weekly, monthly, and yearly intervals to a date in a loop?如何将每周、每月和每年的间隔添加到循环中的日期?
【发布时间】:2020-07-08 23:08:51
【问题描述】:

我正在使用 for 循环将项目附加到数组以添加到 Realm。

var transactionArray:[Transaction] = []

for _ in 1...numberOfTransactionsToAdd {

            let addedTransaction = Transaction()
            
            addedTransaction.transactionAmount = amount
            addedTransaction.transactionName = name
            addedTransaction.transactionDescription = desc
            addedTransaction.transactionDate = datePicked
            addedTransaction.transactionCategory = category

            transactionArray.append(addedTransaction)
        }

let transactionList = List<Transaction>()
        
        
        for transaction in transactionArray {
            
            transactionList.append(transaction)
            
        }
        
        try! realm.write {
            realm.add(transactionList)
        }

此代码运行良好,但它保存了同一日期的所有交易。

我需要通过将每周和每月的时间间隔添加到日期来使他们重复交易。

我尝试创建一个嵌套的 for 循环来添加日期组件:

for _ in 0...1 {
                datePicked = Calendar.current.date(byAdding: timeComponent, to: datePicked)!
            }

我已经尝试增加几个星期的时间,但这几个月都行不通:

for _ in 0...7 {
                datePicked = datePicked + 24*60*60
            }

如何以每周和每月的间隔附加这些 addedTransaction 对象?

【问题讨论】:

  • 你怎么知道用什么来增加日期?
  • 这个问题很模糊,因为我们不知道数量、名称、日期选择等是如何填充的。话虽如此,这段代码将创建一堆重复的 Transaction() 对象,它们的所有属性都是相同的。这可能不是你想要的,但也许是?你能澄清一下吗?此外,我们不知道您想对 datePicked 属性做什么。什么是每周和每月间隔?单个属性如何成为 and 例如单个属性同时拥有每周和每月的间隔?
  • @Joakim,这是我的第一个应用程序,我一直在努力解决如何实现此功能。我希望用户能够保存交易并按照他们的选择重复交易。如果他们每 2 周或第 1 和 15 周获得报酬,他们应该能够做到这一点,而无需手动执行 100 次。类似于 [TBRepeatPicker] 的东西:cocoapods.org/pods/TBRepeatPicker
  • @Jay 每笔交易都应该有一个唯一的日期。示例:用户在 6 月 12 日、7 月 12 日、8 月 12 日的帐户中有手机费用……并且重复 10 年左右。除日期外,有关交易的其他所有内容(类别、金额、名称)均相同。我喜欢 Cocoapods 上的 TBRepeatPicker,但我无法安装 Swift 4 版本。几个月前我才开始编码,我一直在尝试弄清楚如何添加此功能。
  • 我不确定具体的困难在哪里。当用户选择 6 月 12 日,每月重复一年,创建 12 笔交易,相关日期为 6/6/12 7/6/12 等。这行得通吗?

标签: swift date for-loop realm


【解决方案1】:

有一个现有的答案,但它依赖于第三方模块,这不是一件坏事,但如果将来不更新,它将使答案无效。此外,使用的对象没有明确定义。

TL;DR - 不需要列表或数组。在创建和填充事务时编写事务。

详情:

所以这里有一个更完整的 Swift 答案,从 TransactionClass Realm 对象开始,该对象具有交易日期的便利 init 以及通常在对象上使用的主键。

class TransactionClass: Object {
    @objc dynamic var transaction_id = UUID().uuidString
    @objc dynamic var date_picked = Date()
    convenience init(theDate: Date) {
        self.init()
        self.date_picked = theDate
    }
    override static func primaryKey() -> String? {
        return "transaction_id"
    }
}

然后是一个根据pickDate创建多个重复交易的函数

let datePicked = Date() //using today as an example, insert your date here
let numMonths = 12 //recurring for 12 months
var dateComponent = DateComponents()

for index in 0..<numMonths {
    dateComponent.month = index
    if let futureDate = Calendar.current.date(byAdding: dateComponent, to: datePicked) {
        let t = TransactionClass(theDate: futureDate)
        try! realm.write {
            realm.add(t)
        }
    }
}

以及打印时的输出

2020-07-12 13:30:32 +0000
2020-08-12 13:30:32 +0000
2020-09-12 13:30:32 +0000
2020-10-12 13:30:32 +0000
2020-11-12 14:30:32 +0000
2020-12-12 14:30:32 +0000
2021-01-12 14:30:32 +0000
2021-02-12 14:30:32 +0000
2021-03-12 14:30:32 +0000
2021-04-12 13:30:32 +0000
2021-05-12 13:30:32 +0000
2021-06-12 13:30:32 +0000

【讨论】:

    【解决方案2】:

    如果我正确理解了你的问题,你可以试试这个:

    for _ in 1...numberOfTransactionsToAdd {
        let addedTransaction = Transaction()
    
        addedTransaction.transactionAmount = amount
        addedTransaction.transactionName = name
        addedTransaction.transactionDescription = desc
        addedTransaction.transactionCategory = category
        
        // specify your date components (add month, day, whatever you need)
        var dateComponent = DateComponents() 
        dateComponent.day = 1
        dateComponent.month = 2
        // add the date components to `datePicked`
        let newDate = Calendar.current.date(byAdding: dateComponent, to: datePicked)!
        // set `transactionDate` to your new date
        addedTransaction.transactionDate = newDate
    
        transactionArray.append(addedTransaction)
    }
    

    【讨论】:

    • 这非常接近。但它只是将所有事务设置为 newDate。也许我需要实现另一个 for 循环?我正在研究解决方案...
    • @BriScoLeg 你没有提到如何你想这样做。为了帮助您,我们需要更多信息。如果您只想将每个日期增加 1 天(或某个恒定间隔),您可以将 index 参数添加到 for 循环中。
    【解决方案3】:

    这是我解决这个难题的方法:

    我使用 SwiftDate https://cocoapods.org/pods/SwiftDate 来更轻松地处理日期。

    我在循环结束时添加了一个月到 datePicked,在 transactionArray.append 之后。这样,第一个交易日期就是选择的日期。

    代码如下:

    func saveMultipleTransactions() {
            
            var transactionArray:[Transaction] = []
            
            let numberOfTransactionsToAdd = 12
            
            for _ in 1...numberOfTransactionsToAdd {
                
                let addedTransaction = Transaction()
                            
                addedTransaction.transactionAmount = amount
                addedTransaction.transactionName = name
                addedTransaction.transactionDescription = desc
                addedTransaction.transactionDate = datePicked
                addedTransaction.transactionCategory = category
                
                transactionArray.append(addedTransaction)
                
                datePicked = datePicked + 1.months
                
            }
            
            let transactionList = List<Transaction>()
            
            
            for transaction in transactionArray {
                
                transactionList.append(transaction)
                
            }
            
            try! realm.write {
                realm.add(transactionList)
            }
        }
    

    我计划扩展功能以使其更加通用,但这对我有用(目前)。

    【讨论】:

    • 我们不知道 var datePicked 是什么类型的。对您有用很好,但如果没有更多信息,对其他人将无济于事。您可以更新以使其更完整吗?包括你的 Realm 对象会很棒。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-10-08
    • 2017-11-14
    • 2011-08-28
    • 1970-01-01
    相关资源
    最近更新 更多