Set maximum time with UIDatePicker - time mode - swift - swift

Is it possible to customise the UIDatePicker in CountDownTimer mode to not show the picker values past a certain point? For example if I set it to 2 hours it would only show 2 hours downwards.
Currently I have tried a few techniques but all I have succeeded in is setting the countdown point to a certain value using maximumDate.
self.datePickerView.datePickerMode = UIDatePickerMode.CountDownTimer
//For calculating a date with +30 mins
let calendar = NSCalendar.currentCalendar()
let date = calendar.dateByAddingUnit(.CalendarUnitMinute, value: 30, toDate: NSDate(), options: nil)
println("30+Mins \(date)")
//Interval for countdownDuration
let myTimeInterval = NSTimeInterval(timeOffset * 60)
println("myTimeInterval \(myTimeInterval)")
//Tried Methods - countDownDuration sets it to a certain points(in seconds)
self.datePickerView.countDownDuration = myTimeInterval
self.datePickerView.maximumDate = date // This doesn't seem to do anything when in using UIDatePickerMode.CountDownTimer
I presume a possible way is to use just a UIPicker.

Exactly as you say - it's possible to do it yourself with UIPickerView. And that's actually exactly what I did: I built a custom UIPickerView subclass for that purpose. It replicates the functionality of UIDatePicker in countDownTimer mode, while adding support to set maxTimeInterval.
You use it like this:
GSTimeIntervalPicker *picker = [[GSTimeIntervalPicker alloc] init];
picker.maxTimeInterval = (3600 * 3); // set the limit
picker.minuteInterval = 5; // the step. Default is 1 min.
picker.timeInterval = (3600 * 1.5); // 1 h 30 minutes
picker.onTimeIntervalChanged = ^(NSTimeInterval newTimeInterval) {
// Use the value
};
Available on GitHub under MIT license. Blog post here. I'm sorry it's not in Swift, you will have to convert it yourself.

First Thing: you don't need a calendar to add 30 minutes to a given date.
There is a constructor that does what you want in one step:
NSDate(timeInterval: NSTimeInterval, sinceDate: NSDate)
NSDate(timeIntervalSinceNow: NSTimeInterval)
for me,
self.datePickerView.maximumDate = date
shows future dates / time greyed out, so the user has some visual hint.
This doesn't mean, a future date / time is not selectable without additional code.
The user can select a greyed out time. You can check in your handler and when some future date is selected, you just set
self.datePickerView.date = date
as long as you don't call resignFirstResponder(), your date picker scrolls back to now (or any other chosen time) nicely. So the user is not able to select a time in the future with this additional code.
I hope this is near enough to what you need. Future is greyed out instead of invisible and it is not selectable with a little additional code in your handler.

Related

Picking a date with swift UI automation

In the app I'm testing there is a date picker I'm trying to automate. The wheel defaults to tomorrow and I'm attempting to change it to today's date but 2 minutes from now. Below is the code I'm using to attempt this.
app.pickerWheels.element(boundBy: 0).adjust(toPickerWheelValue: "Today")
app.pickerWheels.element(boundBy: 1).adjust(toPickerWheelValue: "1")
app.pickerWheels.element(boundBy: 2).adjust(toPickerWheelValue: "00")
(In the actual code I'm using variables and not hard coding these string)
This code works for the second and third wheel (hours and minutes) but for the first wheel it won't set the value. The test will fail and not continue past that point.
I have also tried passing today's date instead of just "Today" with the same results.
You can use the DateFormatter class with Date to accomplish this.
// Initialize the date formatter. Set the timeZone and format. I chose hours and minutes.
let dateFormatter: DateFormatter = DateFormatter()
dateFormatter.timeZone = NSTimeZone.local
dateFormatter.dateFormat = "HH:mm"
// Initialize the Date instance using a time interval since now.
let d: Date = Date(timeIntervalSinceNow: 2 * 60)
print("Current Time = \(dateFormatter.string(from: Date())), Two-Minutes-From-Now = \(dateFormatter.string(from: d))")
Output: Current Time = 23:57, Two-Minutes-From-Now = 23:59
A Date is stored as a time interval since January 1st, 1970. You can manipulate the date by adding or subtracting seconds from it. Here, I added 2 * 60 or two 60-second minutes to the current time interval (a large value represented in a double). This points to two minutes in the future.
Now, if you print the date without the formatter, it will just display the current time with no regard to your time zone. So if you want it to be accurate to your time zone, you need to set that in the formatter first. Note that it doesn't change the time, just its representation to you.

Unable To Set Date in DatePicker Swift

I have a common datePicker,
where in Part 1 of the code (which is executed when datePicker is changed) I am setting datePicker's minimumDate and maximumDate and this works.
In Part 2 of the code (which is executed when cell is tapped) I am only setting the datePickers date.
When Part 1 is followed by Part 2 of the code I am unable to set datePickers date i.e the datePicker shows the maximumDate set (which is done in part 1 of the code)
When Part 2 of the code executed without part 1, I am able to set the datePickers date.
Can someone please advice where I could be going wrong ?
Part 1
let endTimeString = self.timesArray[row]["endTime"]!
let endTimeObject = self.convertToDateObject(timeString: endTimeString)
let maxStartTimeObject = endTimeObject.addingTimeInterval(-5 * 60.0) // removing 5mins
cell.datePicker.maximumDate = maxStartTimeObject
let startTimeString = self.timesArray[row]["startTime"]
let startTimeObject = self.convertToDateObject(timeString: startTimeString!)
let minEndTimeObject = startTimeObject.addingTimeInterval(5 * 60.0) // adding 5mins
cell.datePicker.minimumDate = minEndTimeObject
Part 2
cell.datePicker.date = dateObject
Is it possible that the date you are trying to set it outside your min/max bounds?

How do I find the time interval remaining from NSTimer

I have set a NSTimer.scheduledTimerWithTimeInterval method which has an interval every 20 minutes. I want to be able to find out how much time is left when the the app goes into background mode. How do I find out how much time is left from the interval?
Thanks
You have access to a NSTimer's fireDate, which tells you when the timer is going to fire again.
The difference between now and the fireDate is an interval you can calculate using NSDate's timeIntervalSinceDate API.
E.G. something like:
let fireDate = yourTimer.fireDate
let nowDate = NSDate()
let remainingTimeInterval = nowDate.timeIntervalSinceDate(fireDate)
When using the Solution of #Michael Dautermann with normal Swift type Timer and Date I have noticed, that his solution will give you a negative value e.g.:
let fireDate = yourTimer.fireDate
let nowDate = Date()
let remainingTimeInterval = nowDate.timeIntervalSinceDate(fireDate)
//above value is negative e.g. when the timers interval was 2 sec. and you
//check it after 0.5 secs this was -1,5 sec.
When you insert a negative value in the Timer.scheduledTimer(timeInterval:,target:,selector:,userInfo:,repeats:) function it would lead to a timer set to 0.1 milliseconds as the Documentation of the Timer mentions it.
So in my case I had to use the negative value of the nowDate.timeIntervalSinceDate(fireDate) result: -nowDate.timeIntervalSinceDate(fireDate)

Retrieve date from double value in NSUserDefaults (Swift)

Hi I'm creating an that has two controls: A NSSlider and a NSTextField that update continuously. I added a NSDateFormatter to the NSTextField so that it shows the current value of the slider formatted as a time. The slider has a range of 0 to 86,400 units (so that the user slides the seconds in a range of 24 hours).
I connected my app to the shared user defaults controller so that the value is stored for the user.
The app shows the correct time in the NSTextField, but it always stores the value in seconds. for example, if the user selected 06:32:14 when moving the slider, the system will actually store 23534.2261709793 in the key startTime
When the user opens the app again, they will see 06:32:14 as expected.
My problem is when I want to read the variable in my code:
I can read the value as Double:
let value = NSUserDefaults.standardUserDefaults().objectForKey("startTimeValue") as? Double
This works fine, if I try to cast it as NSDate it won't work (the value will be set to nil). So I thought that using a NSDateFormatter in code could work (as this is the way interface builder does the work for the user to see the date):
let dateFormatter = NSDateFormatter()
dateFormatter.dateStyle = NSDateFormatterStyle.NoStyle
dateFormatter.timeStyle = NSDateFormatterStyle.ShortStyle
let date = dateFormatter.dateFromString((value?.description)!)
In the previous code I created the date formatter, then set the date style to nothing (I only want to do the time), and the time style to short. But giving the value.description ("23534.2261709793") still won't work. date will still be nil.
Is there something I'm doing wrong?
The double that you are storing / getting from NSUserDefaults is the time interval from Thursday 1st January 1970. So you need to feed that time interval into the NSDate constructor so that it can construct the date for you.
let value = NSUserDefaults.standardUserDefaults().objectForKey("startTimeValue") as? Double
let date = NSDate(timeIntervalSince1970: value)

AppleScript (or swift) add hours to time

I'm trying to add 8Hours to a date (from the clipboard)
set date1 to the clipboard
set newdate to date1 + (8 * hours)
display dialog "Purchases were downloaded at " & newdate buttons {"OK"} default button 1
But this is not working as expected, I'm having the error
Can’t make "06/22/2015 08:15:27 " into type number.
You need to pick the hours as an individual variable, like shown below:
set currentDate to current date
set newHour to ((hours of currentDate) + 8)
You can also use this for days, minutes and seconds.
This will work. You can then use the variables to construct a new date to be used in the display dialog.
PS. Don't forget to change the day if the newHour variable is bigger than 24 hours.
EDIT
Setting a date to the clipboard can be done like this:
set currentDate to current date
set the clipboard to currentDate as Unicode text
Getting the current clipboard and adding it to a variable goes like this:
set currentDate to get the clipboard
display dialog currentDate
I hope this helps!
In Swift, you can call dateByAddingTimeInterval on an NSDate object.
The time interval is measured in seconds.
yourDate.dateByAddingTimeInterval(8 * 60 * 60)
If you wanted to add another method to add 8 hours directly, you could define an extension:
extension NSDate {
func addEightHours() -> NSDate {
return self.dateByAddingTimeInterval(8 * 60 * 60)
}
}