在 Swift 5 中,如何按一定间隔递增日期属性,然后使用新的未来日期运行该函数?

问题描述 投票:0回答:1

我正在尝试根据当前日期选择未来的日期。我想使用某种时间间隔,即:日、月、年等。

我写了代码和递归函数。我得到了正确的重复日期数量,但它们都是相同的: Date.now 请参阅下面的结果视图: iPhone预览截图

有人可以告诉我有关日历的信息以及如何在 Apple 产品中正确提前日期和时间吗?

import SwiftUI
import SwiftData

var payFrequencies = [ "once", "daily", "weekly", "biweekly", "monthly", "quarterly", "semiannually", "annually"]

struct PayPeriodCalculation: View {
    
    enum Recurrence {
        case daily, weekly, biweekly, monthly, quarterly, semiannually, annually
    }
    @Environment(\.dismiss) private var dismiss
    @Environment(\.modelContext) private var context
    
    @State private var budgetPayDate: Date = .now
    @State private var budgetPayPurpose: String = ""
    @State private var budgetPayCounterpart: String = ""
    @State private var budgetPayDirection: String = ""
    @State private var budgetPayAmount: Double = 0.00
    @State private var budgetPayMethod: String = "cash"
    @State private var budgetPayFrequency: String =  "once"
    @State private var budgetPayControl: String = "at will"
    @State private var budgetPayPurposeCategory: String = "miscellaneous"
    @State private var budgetIsBudgetTransaction: Bool = true
    
    var budgetTransaction: Transaction
    
    func saveBudgetTransaction(budgetTransaction: Transaction, context: ModelContext) {
        let trxToSave = Transaction(payDate: budgetPayDate, payPurpose: budgetPayPurpose, payCounterpart: budgetPayCounterpart, payDirection: budgetPayDirection, payAmount: budgetPayAmount, payMethod: budgetPayMethod, payFrequency: budgetPayFrequency, payControl: budgetPayControl, payPurposeCategory: budgetPayPurposeCategory, isBudgetTransaction: budgetIsBudgetTransaction)
        
        context.insert(trxToSave)
    }

func oneDay() -> TimeInterval {
        let oneDay: TimeInterval = 24*60*60
        return oneDay
    }
    
    func oneWeek() -> TimeInterval {
        let oneWeek: TimeInterval = 7*24*60*60
        return oneWeek
    }
    
    func twoWeeks() -> TimeInterval{
        let twoWeeks: TimeInterval = 14*24*60*60
        return twoWeeks
    }
    
    func oneMonth() -> TimeInterval {
        let oneMonth: TimeInterval = 30*24*60*60
        return oneMonth
    }
    
    func oneQuarter() -> TimeInterval {
        let oneQuarter: TimeInterval = 3*30*24*60*60
        return oneQuarter
    }
    
    func halfYear() -> TimeInterval {
        let halfYear: TimeInterval = 6*30*24*60*60
        return halfYear
    }

func thisTrxSave() {
let budgetTransaction = Transaction(payDate: budgetPayDate, payPurpose: budgetPayPurpose, payCounterpart: budgetPayCounterpart, payDirection: budgetPayDirection, payAmount: budgetPayAmount, payMethod: budgetPayMethod, payFrequency: budgetPayFrequency, payControl: budgetPayControl, payPurposeCategory: budgetPayPurposeCategory, isBudgetTransaction: budgetIsBudgetTransaction)
            saveBudgetTransaction(budgetTransaction: budgetTransaction, context: context)
        
    }

func calculateNumberOfBudgetTransactions() -> [Date] {
        var budgetPayDates: [Date] = []
        
        switch budgetPayFrequency {
        case "daily" :
            thisTrxSave()
            budgetPayDates.append(budgetPayDate)
            for _ in 0...363 {
                budgetPayDate = budgetPayDate + oneDay()
                thisTrxSave()
                budgetPayDates.append(budgetPayDate)
            }
        case "weekly" :
            thisTrxSave()
            budgetPayDates.append(budgetPayDate)
            for _ in 0...50 {
                budgetPayDate = budgetPayDate + oneWeek()
                thisTrxSave()
                budgetPayDates.append(budgetPayDate)
            }
        case "biweekly" :
            thisTrxSave()
            budgetPayDates.append(budgetPayDate)
            for _ in 0...24 {
                budgetPayDate = budgetPayDate + twoWeeks()
                thisTrxSave()
                budgetPayDates.append(budgetPayDate)
            }
            
        case "quarterly" :
            thisTrxSave()
            budgetPayDates.append(budgetTransaction.payDate)
            for _ in 0...2 {
                budgetPayDate = budgetPayDate + oneQuarter()
                thisTrxSave()
                budgetPayDates.append(budgetTransaction.payDate)
            }
                
        case "semiannually" :
            thisTrxSave()
            budgetPayDates.append(budgetTransaction.payDate)
                budgetPayDate = budgetPayDate + halfYear()
                thisTrxSave()
                budgetPayDates.append(budgetTransaction.payDate)
            
        case "annually" :
            thisTrxSave()
            budgetPayDates.append(budgetTransaction.payDate)
        
        default :
            // monthly
            thisTrxSave()
            budgetPayDates.append(budgetTransaction.payDate)
            for _ in 0...10 {
                budgetPayDate = budgetPayDate + oneMonth()
                thisTrxSave()
                budgetPayDates.append(budgetTransaction.payDate)
            }
        }
        return budgetPayDates
    }
    
 
    var getDateParts = Date.getDateParts(.now)
    
    var body: some View {
        Form {
            Section {
                Section {
                    Picker("Recur", selection: $budgetPayFrequency){
                        ForEach(payFrequencies, id: \.self) {
                            Text($0)
                        }
                    }.frame(maxWidth: .infinity)
                }
            }
        }
        
        List {
            VStack{
                let budPayDates = calculateNumberOfBudgetTransactions()
                if budgetPayFrequency != "once" {
                    
                    Text("\(budPayDates.count)")
                    
                    ForEach(budPayDates, id: \.self) {payDate in
                        
                        Text("\(payDate)")
                        
                    }
                } else {
                    Text("nothing")
                }
            }
        }
        }
    }
    
struct PayPeriodCalculationContainer: View {
    
    @Query(sort: \Transaction.payPurpose) private var transactions: [Transaction]
    
    // MARK: *BUDGET*
    private var budgetTransactions: [Transaction] {
        transactions.filter{ $0.isBudgetTransaction == true }
    }
    
    var body: some View {
        PayPeriodCalculation(budgetTransaction: budgetTransactions[0])
    }
}

#Preview {
    NavigationStack {
        PayPeriodCalculationContainer()
            .modelContainer(previewContainer)
    }
}

swift date datepicker recurrence swiftdata
1个回答
0
投票

直接处理日期非常困难,因为世界各地的日期保存方式不同。在 Apple 框架内推进日期和时间时,您需要使用日历。
例子: Calendar.autoupdatingCurrent.date(通过添加:.day,值:1,到:.now,wrappingComponents:true)

查看此处的文档日历

© www.soinside.com 2019 - 2024. All rights reserved.