以下代码在iOS 4.3下显示奇怪的行为(也许是其他版本)。在此示例中,显示日期设置为UIDatePicker
的{{1}}。 4 Aug 2011 2:31 PM
下方的UILabel
显示参考日期。下面标有1,5,10的三个UIDatePicker
设置了UIButtons
上的minuteInterval
。
点击1 - 显示UIDatePicker
中所选日期为UIDatePicker
,并且分钟间隔为1,这是预期的。
点击5 - 显示4 Aug 2011 2:31 PM
中的所选日期为UIDatePicker
,并且分钟间隔为5,这是预期的(可以说时间应该向下舍入,但那是不是一个大问题。)
点击10 - 显示4 Aug 2011 2:35 PM
中所选日期为UIDatePicker
,分钟间隔为10.好分钟间隔是否正确,但所选时间是2:10?人们可能会预期2:40(如果向上舍入)或2:30(如果向下舍入)。
BugDatePickerVC.h
4 Aug 2011 2:10 PM
BugDatePickerVC.m
#import <UIKit/UIKit.h>
@interface BugDatePickerVC : UIViewController {
NSDateFormatter *dateFormatter;
NSDate *date;
UIDatePicker *datePicker;
UILabel *dateL;
UIButton *oneB;
UIButton *fiveB;
UIButton *tenB;
}
- (void) buttonEventTouchDown:(id)sender;
@end
答案 0 :(得分:8)
好的,我可以通过使用以下代码将UIDatePicker
日期值明确设置为舍入到分钟间隔的日期来更改行为:
- (void) handleUIControlEventTouchDown:(id)sender
{
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Set the date picker's minute interval.
NSInteger minuteInterval = [sender tag];
// Setting the date picker's minute interval can change what is selected on
// the date picker's UI to a wrong date, it does not effect the date
// picker's date value.
//
// For example the date picker's date value is 2:31 and then minute interval
// is set to 10. The date value is still 2:31, but 2:10 is selected on the
// UI, not 2:40 (rounded up) or 2:30 (rounded down).
//
// The code that follow's setting the date picker's minute interval
// addresses fixing the date value (and the selected date on the UI display)
// . In the example above both would be 2:30.
datePicker.minuteInterval = minuteInterval;
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Calculate the proper date value (and the date to be selected on the UI
// display) by rounding down to the nearest minute interval.
NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSMinuteCalendarUnit fromDate:date];
NSInteger minutes = [dateComponents minute];
NSInteger minutesRounded = ( (NSInteger)(minutes / minuteInterval) ) * minuteInterval;
NSDate *roundedDate = [[NSDate alloc] initWithTimeInterval:60.0 * (minutesRounded - minutes) sinceDate:date];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Set the date picker's value (and the selected date on the UI display) to
// the rounded date.
if ([roundedDate isEqualToDate:datePicker.date])
{
// We need to set the date picker's value to something different than
// the rounded date, because the second call to set the date picker's
// date with the same value is ignored. Which could be bad since the
// call above to set the date picker's minute interval can leave the
// date picker with the wrong selected date (the whole reason why we are
// doing this).
NSDate *diffrentDate = [[NSDate alloc] initWithTimeInterval:60 sinceDate:roundedDate];
datePicker.date = diffrentDate;
[diffrentDate release];
}
datePicker.date = roundedDate;
[roundedDate release];
}
注意UIDatePicker
日期设置两次的部分。这很好玩。
任何人都知道如何关闭动画来调用minuteInterval
?点击5然后点击10时的幻像滚动有点难看。
答案 1 :(得分:6)
我使用mmoris的上述解决方案并创建了一个返回舍入日期的方法..(对于ARC)
- (NSDate *)getRoundedDate:(NSDate *)inDate{
NSDate *returnDate;
NSInteger minuteInterval = 10;
NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSMinuteCalendarUnit fromDate:inDate];
NSInteger minutes = [dateComponents minute];
NSInteger minutesRounded = ( (NSInteger)(minutes / minuteInterval) ) * minuteInterval;
NSDate *roundedDate = [[NSDate alloc] initWithTimeInterval:60.0 * (minutesRounded - minutes) sinceDate:inDate];
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Set the date picker's value (and the selected date on the UI display) to
// the rounded date.
if ([roundedDate isEqualToDate:inDate])
{
// We need to set the date picker's value to something different than
// the rounded date, because the second call to set the date picker's
// date with the same value is ignored. Which could be bad since the
// call above to set the date picker's minute interval can leave the
// date picker with the wrong selected date (the whole reason why we are
// doing this).
NSDate *diffrentDate = [[NSDate alloc] initWithTimeInterval:60 sinceDate:roundedDate];
returnDate = diffrentDate;
//[diffrentDate release];
}
returnDate = roundedDate;
return returnDate;
}
答案 2 :(得分:4)
这是另一种方法,具有Objective-C类别!
我采取了@ zurbergram的舍入行为(上/下至最接近)和@mmorris的整体答案的精神,并提出了这个类别:
#import <UIKit/UIKit.h>
@interface UIDatePicker (SetDateRounded)
-(void)setMinimumDateRoundedByMinuteInterval:(NSDate *)minimumDate;
-(void)setDateRoundedByMinuteInterval:(NSDate *)date animated:(BOOL)animatedYesNo;
@end
@implementation UIDatePicker (SetDateRounded)
-(void)setDateRoundedByMinuteInterval:(NSDate *)date animated:(BOOL)animatedYesNo
{
NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSMinuteCalendarUnit fromDate:date];
NSInteger minutes = [dateComponents minute];
NSInteger minutesRounded = roundf((float)minutes / (float)[self minuteInterval]) * self.minuteInterval;
NSDate *roundedDate = [[NSDate alloc] initWithTimeInterval:60.0 * (minutesRounded - minutes) sinceDate:date];
[self setDate:roundedDate animated:animatedYesNo];
}
-(void)setMinimumDateRoundedByMinuteInterval:(NSDate *)date
{
NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSMinuteCalendarUnit fromDate:date];
NSInteger minutes = [dateComponents minute];
NSInteger minutesRounded = roundf((float)minutes / (float)[self minuteInterval]) * self.minuteInterval;
NSDate *roundedDate = [[NSDate alloc] initWithTimeInterval:60.0 * (minutesRounded - minutes) sinceDate:date];
[self setMinimumDate:roundedDate];
}
@end
然后在您的实现中,您可以执行以下操作:
#import "UIDatePicker+SetDateRounded.h"
...
- (void)viewDidLoad
{
[super viewDidLoad];
_datePicker.minuteInterval = 15;
[_datePicker setMinimumDateRoundedByMinuteInterval:[NSDate date]];
[_datePicker setDateRoundedByMinuteInterval:[NSDate date] animated:YES];
}
...
Bonus方法:setMinimumDateRoundedByMinuteInterval:允许您设置选择器的初始最小值以匹配相同的行为。一个重构是将实际计算部分抽象为自己的方法,而不是复制意大利面,但我相信人们可以为自己优化它。
答案 3 :(得分:3)
以下是getRoundedDate的更新版本:向上或向下舍入,以便下午1:03向下舍入到下午1:00和下午1:12到下午1:15
-(NSDate *)getRoundedDate:(NSDate *)inDate
{
NSInteger minuteInterval = 15;
NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:NSMinuteCalendarUnit fromDate:inDate];
NSInteger minutes = [dateComponents minute];
float minutesF = [[NSNumber numberWithInteger:minutes] floatValue];
float minuteIntervalF = [[NSNumber numberWithInteger:minuteInterval] floatValue];
// Determine whether to add 0 or the minuteInterval to time found by rounding down
NSInteger roundingAmount = (fmodf(minutesF, minuteIntervalF)) > minuteIntervalF/2.0 ? minuteInterval : 0;
NSInteger minutesRounded = ( (NSInteger)(minutes / minuteInterval) ) * minuteInterval;
NSDate *roundedDate = [[NSDate alloc] initWithTimeInterval:60.0 * (minutesRounded + roundingAmount - minutes) sinceDate:inDate];
return roundedDate;
}
答案 4 :(得分:1)
UIDatePicker的问题只有小时和分钟,每次我选择一个时间,选择器在UI中添加20分钟,而不是在选定的时间。在我的情况下,解决方案非常简单,在设置选择器的值之前设置picker.minuteInterval=5
。
希望这会对其他人有所帮助。
答案 5 :(得分:1)
zurbergram 代码:
register_post_type( 'series', array(
答案 6 :(得分:1)
Swift 4 版本
func round(date: Date, for minuteInterval: Int) -> Date {
let dateComponents = Calendar.current.dateComponents([.minute], from: date)
let minutes = dateComponents.minute!
// Determine whether to add 0 or the minuteInterval to time found by rounding down
let intervalRemainder = Double(minutes).truncatingRemainder(
dividingBy: Double(minuteInterval)
)
let halfInterval = Double(minuteInterval) / 2.0
let roundingAmount: Int
if intervalRemainder > halfInterval {
roundingAmount = minuteInterval
} else {
roundingAmount = 0
}
let minutesRounded = minutes / minuteInterval * minuteInterval
let timeInterval = TimeInterval(
60 * (minutesRounded + roundingAmount - minutes)
)
let roundedDate = Date(timeInterval: timeInterval, since: date)
return roundedDate
}