user21156717
user21156717

Reputation:

how to set date countdown from given a string type date in swiftui?

How to set the date countdown in swiftui. I want to update decrease time each second. But I don't understand how to solve this problem?

struct TimerExample: View {
    @State var currentTime = Date.now
    @State var inputDate = "2022-12-03 12:20:09"

    var body: some View {
        Text("The time is: \(convertDateFormat(inputDate: inputDate))")
            .padding()
            .onAppear {
                Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) {
                    time in
                    currentTime = Date.now
                }
            }
    }

    func convertDateFormat(inputDate: String) -> String {
        let olDateFormatter = DateFormatter()
        olDateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss" //"yyyy-MM-dd'T'HH:mm:ss"

        let oldDate = olDateFormatter.date(from: inputDate)

        let convertDateFormatter = DateFormatter()
        convertDateFormatter.dateFormat = "yyyy-MM-dd hh:mm:ss"

        return convertDateFormatter.string(from: oldDate!)
    }
}

Upvotes: 1

Views: 1493

Answers (3)

Anup Kumar Mishra
Anup Kumar Mishra

Reputation: 206

This approach may be solution of your problem. please let me know it is working or not. if i understand your question then this is solution.

struct DateTimerView:View{
    
        @State private var endDateText = "25-12-2027"
            @State private var remainingTime = "Enter an end date"
            @State private var timer: Timer?
            
            var body: some View {
                VStack {
                    TextField("Enter an end date", text: $endDateText, onCommit: startTimer)
                        .padding()
                    
                    Text(remainingTime)
                        .padding()
                }
                .onDisappear(perform: stopTimer)
            }
            
            func startTimer() {
                let formatter = DateFormatter()
                formatter.dateFormat = "dd-MM-yyyy"
                
                if let endDate = formatter.date(from: endDateText) {
                    let timer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { timer in
                        let currentDate = Date()
                        
                        let calendar = Calendar.current
                        let difference = calendar.dateComponents([.day, .hour, .minute, .second], from: currentDate, to: endDate)
                        
                        if difference.day! > 0 {
                            remainingTime = "\(difference.day!) d  \(difference.hour!) h \(difference.minute!) m \(difference.second!) s"
                        } else if difference.hour! > 0 {
                            remainingTime = "\(difference.hour!) h  \(difference.minute!) m \(difference.second!) s"
                        } else if difference.minute! > 0 {
                            remainingTime = "\(difference.minute!) m \(difference.second!) s"
                        } else {
                            remainingTime = "\(difference.second!) s"
                        }
                        
                        if currentDate >= endDate {
                            stopTimer()
                        }
                    }
                    
                    self.timer = timer
                } else {
                    remainingTime = "Invalid date format"
                }
            }
            
            func stopTimer() {
                timer?.invalidate()
                timer = nil
            }
    }

Upvotes: -2

Noor Ahmed Natali
Noor Ahmed Natali

Reputation: 523

I Think You might what this to send OTP

here is the solution which will help you with resend OTP

struct OTPSample: View {
    
    let timer = Timer.publish(every: 1, on: .main, in: .common).autoconnect()
    @State private var timeLimit: Int = 30
    
    var body: some View {
        
        ZStack {
            Text(timeLimit > 0 ? "resend code in \(timeLimit)" : "resend code")
                .foregroundColor(Color.ThemeGray)
                .padding(15)
                .setFont()
                .onTapGesture {
                    if timeLimit < 1 {
                        print("resend OTP ")
                    }
                }
        }
        .onReceive(timer) { _ in
            if timeLimit > 0 {
                timeLimit -= 1
            }
        }
    }
}

Upvotes: -1

Ashley Mills
Ashley Mills

Reputation: 53181

You can achieve this using a TimelineView and Text with style: .timer, as follows:

struct ContentView: View {
        
    var body: some View {
        TimerExample(endDate: .now + 500)
    }
}

struct TimerExample: View {
    
    let endDate: Date
    
    var body: some View {
        TimelineView(.periodic(from: .now, by: 1)) { context in
            VStack {
                Text("Time remaining:")
                Text(endDate, style: .timer)
                    .font(.title)
                Spacer()
            }
            .padding()
        }
        
    }
}

enter image description here

Upvotes: 7

Related Questions