I am new to Swift and am trying a scheduler. I have the start time selected and I need to add 5 minutes (or multiples of it) to the start time and display it in an UILabel?
#IBAction func timePickerClicked(sender: UIDatePicker) {
var dateFormatter = NSDateFormatter()
dateFormatter.timeStyle = NSDateFormatterStyle.ShortStyle
var dateStr = dateFormatter.stringFromDate(startTime.date)
let sttime = dateStr
startTimeDisplay.text = dateStr
}
// How to advance time by 5 minutes for each section based on the start time selected and display time
// section 1 = start time + 5
// section 2 = start time + 10*
Two approaches:
Use Calendar and date(byAdding:to:wrappingComponents:). E.g., in Swift 3 and later:
let calendar = Calendar.current
let date = calendar.date(byAdding: .minute, value: 5, to: startDate)
Just use + operator (see +(_:_:)) to add a TimeInterval (i.e. a certain number of seconds). E.g. to add five minutes, you can:
let date = startDate + 5 * 60
(Note, the order is specific here: The date on the left side of the + and the seconds on the right side.)
You can also use addingTimeInterval, if you’d prefer:
let date = startDate.addingTimeInterval(5 * 60)
Bottom line, +/addingTimeInterval is easiest for simple scenarios, but if you ever want to add larger units (e.g., days, months, etc.), you would likely want to use the calendrical calculations because those adjust for daylight savings, whereas addingTimeInterval doesn’t.
For Swift 2 renditions, see the previous revision of this answer.
You can use Calendar's method
func date(byAdding component: Calendar.Component, value: Int, to date: Date, wrappingComponents: Bool = default) -> Date?
to add any Calendar.Component to any Date. You can create a Date extension to add x minutes to your UIDatePicker's date:
Xcode 8 and Xcode 9 • Swift 3.0 and Swift 4.0
extension Date {
func adding(minutes: Int) -> Date {
return Calendar.current.date(byAdding: .minute, value: minutes, to: self)!
}
}
Then you can just use the extension method to add minutes to the sender (UIDatePicker):
let section1 = sender.date.adding(minutes: 5)
let section2 = sender.date.adding(minutes: 10)
Playground testing:
Date().adding(minutes: 10) // "Jun 14, 2016, 5:31 PM"
Swift 4:
// add 5 minutes to date
let date = startDate.addingTimeInterval(TimeInterval(5.0 * 60.0))
// subtract 5 minutes from date
let date = startDate.addingTimeInterval(TimeInterval(-5.0 * 60.0))
Swift 5.1:
// subtract 5 minutes from date
transportationFromDate.addTimeInterval(TimeInterval(-5.0 * 60.0))
extension Date {
func withAddedMinutes(minutes: Double) -> Date {
addingTimeInterval(minutes * 60)
}
func withAddedHours(hours: Double) -> Date {
withAddedMinutes(minutes: hours * 60)
}
}
useCase
let anHourFromNow = Date().withAddedHours(hours: 1)
let aMinuteFromNow = Date().withAddedMinutes(minutes: 1)
You can use in swift 4 or 5
let date = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd H:mm:ss"
let current_date_time = dateFormatter.string(from: date)
print("before add time-->",current_date_time)
//adding 5 miniuts
let addminutes = date.addingTimeInterval(5*60)
dateFormatter.dateFormat = "yyyy-MM-dd H:mm:ss"
let after_add_time = dateFormatter.string(from: addminutes)
print("after add time-->",after_add_time)
output:
before add time--> 2020-02-18 10:38:15
after add time--> 2020-02-18 10:43:15
You can do date arithmetic by using NSDateComponents. For example:
import Foundation
let comps = NSDateComponents()
comps.minute = 5
let cal = NSCalendar.currentCalendar()
let r = cal.dateByAddingComponents(comps, toDate: NSDate(), options: nil)
It is what you see when you try it in playground
NSDate.init with timeIntervalSinceNow:
Ex:
let dateAfterMin = NSDate.init(timeIntervalSinceNow: (minutes * 60.0))
Save this little extension:
extension Int {
var seconds: Int {
return self
}
var minutes: Int {
return self.seconds * 60
}
var hours: Int {
return self.minutes * 60
}
var days: Int {
return self.hours * 24
}
var weeks: Int {
return self.days * 7
}
var months: Int {
return self.weeks * 4
}
var years: Int {
return self.months * 12
}
}
Then use it intuitively like:
let threeDaysLater = TimeInterval(3.days)
date.addingTimeInterval(threeDaysLater)
Swift 3:
let minutes: TimeInterval = 1 * 60
let nowPlusOne = Date() + minutes
I think the simplest will be
let minutes = Date(timeIntervalSinceNow:(minutes * 60.0))
In case you want unix timestamp
let now : Date = Date()
let currentCalendar : NSCalendar = Calendar.current as NSCalendar
let nowPlusAddTime : Date = currentCalendar.date(byAdding: .second, value: accessTime, to: now, options: .matchNextTime)!
let unixTime = nowPlusAddTime.timeIntervalSince1970
Related
I am not sure what I am doing wrong, I need to find difference between two dates and extract seconds from it, below is my code. I am not getting correct seconds. There is difference of seconds.
public func captureStartTime() {
captureStartDateTime = Date()
}
public func captureEndTime(eventType: String, eventElement: String) {
let difference = Date().timeIntervalSince(captureStartDateTime)
let interval = Int(difference)
let seconds = interval % 60
let secondsDescrp = String(format: "%02d", seconds)
}
interval is the answer you want. That is the total number of seconds between the two dates.
Your seconds value would only be useful if you wanted to calculate the number of hours, minutes, and seconds or the number of minutes and seconds from the total number of seconds.
Use the following code to get the difference between two dates, Store current time in startTime when pressed button 1 and store current date time in endTime when pressed button 2, See this code, I hope this helps you.
var startTime:Date!
var endTime:Date!
#IBAction func buttonStartTime(_ sender: UIButton) {
startTime = Date()
}
#IBAction func buttonEndTime(_ sender: UIButton) {
endTime = Date()
let formatter = DateComponentsFormatter()
formatter.allowedUnits = [.second]
formatter.unitsStyle = .full
let difference = formatter.string(from: startTime, to: endTime)!
print(difference)//output "8 seconds"
}
Output
8 seconds
you can also use default date components and according to that compare your dates and you can get the difference in year, month, day etc
let dateString1 = "2019-03-07T14:20:20.000Z"
let dateString2 = "2019-03-07T14:20:40.000Z"
//set date formate
let Dateformatter = DateFormatter()
Dateformatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
//convert string to date
let dateold = Dateformatter.date(from: dateString1)!
let datenew = Dateformatter.date(from: dateString2)!
//use default datecomponents with two dates
let calendar1 = Calendar.current
let components = calendar1.dateComponents([.year,.month,.day,.hour,.minute,.second], from: dateold, to: datenew)
let seconds = components.second
print("Seconds: \(seconds)")
I have a datePickerthat I use to select a starting date and time, and a durationTextLabelto add minutes to that date and time. I set the duration to be minimum 30 if no text is inserted, but the value in
resulting date and time is identical.
Can you see where I'm mistaking?
Thank you very much as usual.
Here's the function:
func setQueryParameters() {
let dateFormatter = DateFormatter()
var convertedDate: String!
dateFormatter.dateFormat = "yyyy/MM/dd/hh/mm"
convertedDate = dateFormatter.string(from: datePicker.date)
let calendar = Calendar.current
let components = (calendar as NSCalendar).components([.year, .month, .day, .weekday, .hour, .minute] , from: datePicker.date)
let year: Int = components.year!
let month: Int = components.month!
let day: Int = components.day!
let weekday: Int = components.weekday!
let hour: Int = components.hour!
let minute: Int = components.minute!
var duration: Double?
duration = Double(durationTextField.text!)
let endDate = datePicker.date.addingTimeInterval(duration!)
let endComponents = (calendar as NSCalendar).components([.hour, .minute], from: endDate)
let endHour: Int = endComponents.hour!
let endMinute: Int = endComponents.minute!
if durationTextField.text != nil {
duration = Double(durationTextField.text!) ?? 30.00
} else { return}
// Opening Time Query parameter
openingTimeQueryStart = Int("\(String(describing: weekday))"+"00"+"00")!
openingTimeQueryEnd = Int("\(String(describing: weekday))"+"\(String(describing: hour))"+"\(String(describing: minute))")!
print("opening query is \(openingTimeQueryEnd)")
// Closing Time Query parameter
closingTimeQueryStart = Int("\(String(describing: weekday))"+"\(String(endHour))"+"\(String(endMinute))")!
closingTimeQueryEnd = Int("\(String(describing: weekday))"+"00"+"00")!
print("closing time query is \(closingTimeQueryStart)")
// Booking Query parameter
let bookingQueryString = "\(String(describing: year))"+"\(String(describing: month))"+"\(String(describing: day))"+"\(String(describing: weekday))"+"\(String(describing: hour))"+"\(String(describing: minute))"+"\(String(endHour))"+"\(String(endMinute))"
bookingQuery = Int(bookingQueryString)!// ?? openingTimeQuery // found nil unwripping optional
}
There are many problems here.
You actually never make any use of dateFormatter other than creating and then never using convertedDate. So delete that unused code.
You have indicated at duration should be in minutes but you treat it as seconds. You need to multiply by 60 to convert it to minutes.
All of your code for calculating things such as openingTimeQueryEnd depend on each value being two digits but your code doesn't give the desired results.
For example, the line:
openingTimeQueryEnd = Int("\(String(describing: weekday))"+"\(String(describing: hour))"+"\(String(describing: minute))")!
should be rewritten as:
openingTimeQueryEnd = Int(String(format: "%02d%02d%02d", weekday, hour, minute))!
or as:
openingTimeQueryEnd = weekday * 10000 + hour * 100 + minute
Make similar changes to the other similar lines.
I'm working on a very simple app that counts down to a date. I found several tutorials but nothing in Swift 4. It seems like a lot has changed as I keep getting compiler errors.
Here is my code:
class ViewController: UIViewController {
#IBOutlet weak var CountdownText: UILabel!
let formatter = DateFormatter()
let userCalendar = NSCalendar.current
let requestedComponent: NSCalendar.Unit = [
NSCalendar.Unit.month,
NSCalendar.Unit.day,
NSCalendar.Unit.hour,
NSCalendar.Unit.minute,
NSCalendar.Unit.second,
]
func printTime()
{
formatter.dateFormat = "MM/dd/yy hh:mm:ss a"
let startTime = NSDate()
let endTime = formatter.date(from: "12/03/18 2:00:00 p")
func timeDifference (requestedComponent: NSCalendar.Unit, from: startTime, to: endTime!, options: [NSCalendar.Options]) {}
CountdownText.text = "\(timeDifference.day) Days \(timeDifference.minute) Minutes \(timeDifference.second) Seconds"
}
}
My errors are:
Use of undeclared type 'startTime'
Use of undeclared type 'endTime'
How to use
Copy the Code to your specific View Controller
Change the value of variable dateString with your date in the format
Date Format "< Month > < date >, < year > < hour >:< minute >:< second >"
Ex. "March 4, 2018 13:20:10"
Code
The below code will be useful for achieving a countdown timer of your custom date.
//
// DateCountDownTimer.swift
// CountDownTimerLearning
//
// Created by ThomasVEK on 04/03/18.
// Copyright © 2018 TVEK Solutions. All rights reserved.
//
import Foundation
func defaultUpdateActionHandler(string:String)->(){
}
func defaultCompletionActionHandler()->(){
}
public class DateCountDownTimer{
var countdownTimer: Timer!
var totalTime = 60
var dateString = "March 4, 2018 13:20:10" as String
var UpdateActionHandler:(String)->() = defaultUpdateActionHandler
var CompletionActionHandler:()->() = defaultCompletionActionHandler
public init(){
countdownTimer = Timer()
totalTime = 60
dateString = "March 4, 2018 13:20:10" as String
UpdateActionHandler = defaultUpdateActionHandler
CompletionActionHandler = defaultCompletionActionHandler
}
public func initializeTimer(pYear:Int, pMonth:String, pDay:Int, pHour:Int, pMin:Int, pSec:Int){
self.dateString = "\(pMonth) \(pDay), \(pYear) \(pHour):\(pMin):\(pSec)" as String
// Setting Today's Date
let currentDate = Date()
// Setting TargetDate
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MM-dd-yyyy HH:mm:ss"
dateFormatter.timeZone = NSTimeZone.local
let targedDate = dateFormatter.date(from: dateString) as! Date
// Calculating the difference of dates for timer
let calendar = Calendar.current.dateComponents([.day, .hour, .minute, .second], from: currentDate, to: targedDate)
let days = calendar.day!
let hours = calendar.hour!
let minutes = calendar.minute!
let seconds = calendar.second!
totalTime = hours * 60 * 60 + minutes * 60 + seconds
totalTime = days * 60 * 60 * 24 + totalTime
}
func numberOfDaysInMonth(month:Int) -> Int{
let dateComponents = DateComponents(year: 2015, month: 7)
let calendar = Calendar.current
let date = calendar.date(from: dateComponents)!
let range = calendar.range(of: .day, in: .month, for: date)!
let numDays = range.count
print(numDays)
return numDays
}
public func startTimer(pUpdateActionHandler:#escaping (String)->(),pCompletionActionHandler:#escaping ()->()) {
countdownTimer = Timer.scheduledTimer(timeInterval: 1, target: self, selector: #selector(updateTime), userInfo: nil, repeats: true)
self.CompletionActionHandler = pCompletionActionHandler
self.UpdateActionHandler = pUpdateActionHandler
}
#objc func updateTime() {
self.UpdateActionHandler(timeFormatted(totalTime))
if totalTime > 0 {
totalTime -= 1
} else {
endTimer()
}
}
func endTimer() {
self.CompletionActionHandler()
countdownTimer.invalidate()
}
func timeFormatted(_ totalSeconds: Int) -> String {
let seconds: Int = totalSeconds % 60
let minutes: Int = (totalSeconds / 60) % 60
let hours: Int = (totalSeconds / 60 / 60) % 24
let days: Int = (totalSeconds / 60 / 60 / 24)
return String(format: "%dD %02dH %02dM %02dS", days, hours, minutes, seconds)
}
}
You have specified timeDifference function inside printTime() function and in timeDifference() function you have defined from and to parameters which ones types are startTime and endTime which ones are not types. Replace them with NSDate like:
func timeDifference (requestedComponent: NSCalendar.Unit, from: NSDate, to: NSDate, options: [NSCalendar.Options]) {}
and then call this function with startTime and ednTime variables that you have defined.
Also I think that you should define timeDifference function outside of printTime function.
Hi I am getting the value of time as a string. The number which i am getting is in the seconds. Now i want to convert the Seconds to minutes by using swift3.
The Seconds which i am getting is:
540 this is in seconds.
Now i want to convert the seconds to the minutes.
For example it should show as 09:00 .
How to achieve this using Swift3 code.
Currently i am not using any conversion code.
let duration: TimeInterval = 7200.0
let formatter = DateComponentsFormatter()
formatter.unitsStyle = .positional // Use the appropriate positioning for the current locale
formatter.allowedUnits = [ .hour, .minute, .second ] // Units to display in the formatted string
formatter.zeroFormattingBehavior = [ .pad ] // Pad with zeroes where appropriate for the locale
let formattedDuration = formatter.string(from: duration)
Here is one method:
let duration: TimeInterval = 540
// new Date object of "now"
let date = Date()
// create Calendar object
let cal = Calendar(identifier: .gregorian)
// get 12 O'Clock am
let start = cal.startOfDay(for: date)
// add your duration
let newDate = start.addingTimeInterval(duration)
// create a DateFormatter
let formatter = DateFormatter()
// set the format to minutes:seconds (leading zero-padded)
formatter.dateFormat = "mm:ss"
let resultString = formatter.string(from: newDate)
// resultString is now "09:00"
// if you want hours
// set the format to hours:minutes:seconds (leading zero-padded)
formatter.dateFormat = "HH:mm:ss"
let resultString = formatter.string(from: newDate)
// resultString is now "00:09:00"
If you want your duration in seconds to be formatted as a "time of day," change the format string to:
formatter.dateFormat = "hh:mm:ss a"
Now, the resulting string should be:
"12:09:00 AM"
This will vary, of course, based on locale.
Consider using the Swift Moment framework: https://github.com/akosma/SwiftMoment
let duration: TimeInterval = 7200.0
let moment = Moment(duration)
let formattedDuration = "\(moment.minutes):\(moment.seconds)"
You can use this:
func timeFormatter(_ seconds: Int32) -> String! {
let h: Float32 = Float32(seconds / 3600)
let m: Float32 = Float32((seconds % 3600) / 60)
let s: Float32 = Float32(seconds % 60)
var time = ""
if h < 10 {
time = time + "0" + String(Int(h)) + ":"
} else {
time = time + String(Int(h)) + ":"
}
if m < 10 {
time = time + "0" + String(Int(m)) + ":"
} else {
time = time + String(Int(m)) + ":"
}
if s < 10 {
time = time + "0" + String(Int(s))
} else {
time = time + String(Int(s))
}
return time
}
I am trying to collect steps from CMPedometer for 10 days. It works fine for 7 days but returns 0 for last three days.
Here is the code:
var days:[String] = []
var stepsTaken:[Int] = []
let activityManager = CMMotionActivityManager()
let pedoMeter = CMPedometer()
var cnt = 0
override func viewDidLoad() {
super.viewDidLoad()
getDataForLast10Days()
}
func getDataForLast10Days() {
if(CMPedometer.isStepCountingAvailable()){
let serialQueue : DispatchQueue = DispatchQueue(label: "com.example.MyQueue", attributes: .concurrent)
let formatter = DateFormatter()
formatter.dateFormat = "d MMM"
serialQueue.sync(execute: { () -> Void in
let today = NSDate()
for day in 1...10{
let from = NSDate(timeIntervalSinceNow: Double(-7+day) ))
let hour = Calendar.current.component(.hour, from: from as Date)
let min = Calendar.current.component(.minute, from: from as Date)
let sec = Calendar.current.component(.second, from: from as Date)
let timeToSub = (hour * 60 + min) * 60 + sec
let fromDate = NSDate(timeIntervalSinceNow: (Double(-10+day) * (86400 ) ) - Double(timeToSub))
let toDate = NSDate(timeIntervalSinceNow: (Double(-10+day+1) * (86400) ) - Double(timeToSub))
let dtStr = formatter.string(from: (toDate as Date))
self.pedoMeter.queryPedometerData(from: fromDate as Date , to: toDate as Date) { (data : CMPedometerData!, error) -> Void in
//print("From Date: \(fromDate)","\n\n")
if(error == nil){
// print(data,"\n\n")
print("\(dtStr) : \(data.numberOfSteps)")
self.days.append(dtStr)
self.stepsTaken.append(Int(data.numberOfSteps))
}
}
}
})
}
}
But as the days increase since I have created the app, data increases for one day everyday. It's been 2 days since I created the app. It has data for 9 days and so on. How do I tackle this?
Please let me know what is wrong.
Everything is alright.
According to the method definition for the instance method queryPedometerData(from:to:withHandler:)
Only the past seven days worth of data is stored and available for you
to retrieve. Specifying a start date that is more than seven days in
the past returns only the available data.
See Apple's Documentation here.