Note: Bug reported to Apple
Radar number: 29265429 (Link)
I am using a UIDatePicker. When I give Gregorian calendar it works fine. The days starts from 1 to 31
However, when I give it Islamic islamicUmmAlQura it gives me a strange behaviour. The days starts from 1 to 30 but there is a '2' above 1 and below 30 such that days are as follows 2,1,2,3,4 ... 30
I have created a new empty iOS project and placed the following code into the viewDidLoad method:
let picker = UIDatePicker(frame: CGRect(x: 0, y: 30, width: 0, height: 0))
picker.datePickerMode = .date
picker.date = Date()
picker.calendar = Calendar(identifier: .islamicUmmAlQura)
picker.autoresizingMask = UIViewAutoresizing.flexibleRightMargin
picker.frame.size.width = 300
view.addSubview(picker)
Screenshot:
It is not that hard to make your own UIPicker that looks like a UIDatePicker, but you have to be careful because the bug is in NSCalendar as well as NSDatePicker.
Just to be clear the extra '2' is not selectable, just like 30 is not selectable in a short month. NSDatePicker does not hide invalid days or months, but makes them unselectable. So in the Gregorian calendar if you select February you will still see 29, 30, and 31, but trying to select them the picker will got to 28. The DataPicker figures out how many months and days to show by calling maximumRangeOfUnit: on the calendar. In an Islamic calendar the correct maximum is {1, 30}, but NSCalendar returns {1,31} for maximumRangeOfUnit:NSCalendarUnitDay for all Islamic calendars.
So there are two bugs. One is that NSCalendar is saying that there can be 31 days in an Islamic Month (which I don't believe is true), and the second issue is that NSDatePicker is showing the 31st day a 2 instead of 31.
Making your own NSDatePicker is really not that hard. The amount of element in each component is always the same (just make sure to manually set 30 for the days and not use the value from NSCalendar). The tricky part is deciding if a date is invalid and showing the element as gray and not letting the picket rest on it. You can use rangeOfUnit:InUnit:forDate to get the number of days in a month or number of months in a year. If an invalid element get selected them move the value down to the highest valid date (ie if a user selects 30 in a month with 29 days select 29).
Once a row is selected you can convert from day-month-year to an NSDate with dateFromComponents on NSCalendar.
Related
I am trying to get week number(1,2,3,4,5) with in the month from Jquery UI datepicker. I googled and get the code of iso8601Week but not normal week number.
Kindly Help
This should give you close to what you want, although I've only smoke tested it and there are probably some more edge conditions that need to be addressed.
I basically took the iso8601Week of the first day of the month, and subtracted it from that of the selected date. That works as is for most dates, but ISO 8601 puts days before Jan 4th in the previous year if they fall before Thursday. That's the reason for the % 52.
The code assumes an input called testDate and a label called label1:
$('#testDate').datepicker({
onSelect: function(dateText, inst) {
var d = new Date(dateText);
var d1 = new Date(d.getFullYear(), d.getMonth(), 1)
var x = $.datepicker.iso8601Week(d) % 52;
var y = $.datepicker.iso8601Week(d1) % 52;
$('#label1').text(x-y+1);
}
});
I left in all the variables with partial results in them so you could tinker around with the values. This code assumes that the week begins on Monday (which is the ISO 8601 standard), and that partial weeks before Monday are week 1. So, if the month begins on a Monday, the first Monday is in week 1, and if the month begins on any other day, the first Monday is in week 2. Which looks a bit strange if the 2nd of the month is on Monday and also in week 2, but if you don't like that, you'll have to spend some time deciding in detail what you do like.
I'm trying to have a UIDatePicker to present only the date, month and year to the user. I want to avoid presenting them with the hours, minutes and seconds like it comes by default. I've tried looking for something that might help but can only find solutions that aren't explained clearly in Objective-C, however I'm coding in Swift. Any ideas? Thanks in advance!
you need to chose the mode of the date picker
#IBOutlet weak var myDatePicker: UIDatePicker!
override func viewDidLoad() {
super.viewDidLoad()
myDatePicker.datePickerMode = .date // or .Date (Swift 2.x)
}
date picker options .
Declaration SWIFT
var datePickerMode: UIDatePickerMode
Discussion The
value of this property indicates the mode of a date picker. It
determines whether the date picker allows selection of a date, a time,
both date and time, or a countdown time. The default mode is
UIDatePickerModeDateAndTime. See Date Picker Mode for a list of mode
constants.
UIDatePickerMode
The mode of the date picker.
Declaration Constants
Time
The date picker displays hours, minutes, and (optionally) an AM/PM designation. The exact items shown and their order depend upon the locale set. An example of this mode is [ 6 | 53 | PM ].
Available in iOS 2.0 and later.
Date
The date picker displays months, days of the month, and years. The exact order of these items depends on the locale setting. An example of this mode is [ November | 15 | 2007 ].
Available in iOS 2.0 and later.
DateAndTime
The date picker displays dates (as unified day of the week, month, and day of the month values) plus hours, minutes, and (optionally) an AM/PM designation. The exact order and format of these items depends on the locale set. An example of this mode is [ Wed Nov 15 | 6 | 53 | PM ].
Available in iOS 2.0 and later.
CountDownTimer
The date picker displays hour and minute values, for example [ 1 | 53 ]. The application must set a timer to fire at the proper interval and set the date picker as the seconds tick down.
Available in iOS 2.0 and later.
If you're using storyboards just change mode to "date" in the Attributes inspector.
YourPickerView.datePickerMode=UIDatePickerModeDate;
I wonder if there is a way to custom a datepicker's time range?
How can I remove minute column and leave only 9 and 5 in hour column? is that possible?
Maybe you should considere to use this cocoapod:
https://www.cocoacontrols.com/controls/dvdatepickertableviewcell
or this webpage:
http://blog.deeplink.me/post/81386967477/how-to-easily-customize-uidatepicker-for-ios
and try to custom it as you want.
For UIDatepicker it is not possible to remove the minutes column or only to show 9 and 5 hour in hour column.
UIDatePickerModeDateAndTime:
The date picker displays dates (as unified day of the week, month, and day of the month values) plus hours, minutes, and (optionally) an AM/PM designation. The exact order and format of these items depends on the locale set. An example of this mode is [ Wed Nov 15 | 6 | 53 | PM ].
You need to use custom datepicker for that,you may consider to look at this link for custom picker https://github.com/mwermuth/MWDatePicker
for MWDatePicker first date were invisible but changing the font color like this [datePicker setFontColor:[UIColor blueColor]]; in viewdidLoad in MWViewController.m make them visible.And then modifying the method fillWithCalendar in MWDatePicker.m like this
- (void)fillWithCalendar{
minutes = #[#""];
hours = #[#"05",#"09"];
////others coding
}
i think would give you desired output.
I have dataPicker in my app implemented. But it only shows month,day,hour. How could I able to add year in the date picker. Any idea?
datePicker.datePickerMode = UIDatePickerModeDate;
UIDatePickerModeDate
The date picker displays months, days of the month, and years. The exact order of these items depends on the locale setting. An example
of this mode is [ November | 15 | 2007 ].
Available in iOS 2.0 and later.
Declared in UIDatePicker.h.
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIDatePicker_Class/Reference/UIDatePicker.html
Also you can change from storyboard set Mode: (Refer to screenshot)
If you want to add month, date, year as well as time, add one picker that implements the dates only using (UIDatePickerModeDate) and an additional one for the time (UIDatePickerModeTime).
I want to add 1 month to date, but it is adding only 4 weeks.
I tried like this,
2012-05-04 + DateTimeUtilities.ONEMONTH = 2012-05-31
The result i am getting is 2012-05-31
I want to add a full month (30 days or 31, or when month is a leapyear 29 or 28).
Try converting your time to a Calendar object then increment the month field:
Calendar cal = Calendar.getInstance();
cal.setTime(new Date(timeInMillis));
cal.set(Calendar.MONTH, cal.get(Calendar.MONTH)+1);
long newTimeInMillis = cal.getTime().getTime();
You may want to check for overflow from December to January and increment the year.
The API documentation confirms that DateTimeUtilities.ONEMONTH is four weeks, so what you got is what you should expect.