i have got a function with BOOL return value and 2 input (NSDateComponents *) parameters.
My trouble is I have two NSDateComponents values and I want to know if the two date fall within the same calendar week. i tried the simplest solutions to solve problem, my idea was the following:
- (BOOL)isFunctionName:(NSDateComponents *)comp1 andParam:(NSDateComponents *)comp2 {
return (([comp1 week] == [comp2 week]) && ([comp1 year] == [comp2 year]));
}
but it's not correct.
what way i can solve it ?
edited
so i have a function which makes datecomponents from dates.
-(NSDateComponents *)dateToDateComponents:(NSDate *)date {
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *dateComponents = [gregorian components:unitFlags fromDate:date];
[gregorian release];
return dateComponents;
}
and i call it this way:
if ([self isFunctionName: [self dateToDateComponents:startDate] and Param:[self dateToDateComponents:currentTripDate]]){
}
and during my test it returns YES all of my dates (for example 2010.07.21 - 2010.08.18)
This is inspired by Robert's answer. I tweaked it a bit to address the issue when a week crosses two years, e.g. 12/31/2012 & 1/1/2013.
- (BOOL)isOnSameWeekAsDate:(NSDate*)otherDate
{
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
unsigned unitFlags = NSCalendarUnitYearForWeekOfYear | NSCalendarUnitWeekOfYear;
NSDateComponents *components = [calendar components:unitFlags fromDate:self];
NSDateComponents *otherComponents = [calendar components:unitFlags fromDate:otherDate];
return ( [components yearForWeekOfYear] == [otherComponents yearForWeekOfYear] && [components weekOfYear] == [otherComponents weekOfYear] );
}
The NSDateComponent class reference states:
Important: An NSDateComponents object is meaningless in itself; you
need to know what calendar it is
interpreted against, and you need to
know whether the values are absolute
values of the units, or quantities of
the units.
What about comparing NSDates instead?
- (BOOL) weekIsEqual:(NSDate *)date and:(NSDate *)otherDate {
NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDateComponents *dateComponents = [gregorian components:NSWeekdayCalendarUnit | NSYearCalendarUnit fromDate:date];
NSDateComponents *otherDateComponents = [gregorian components:NSWeekdayCalendarUnit | NSYearCalendarUnit fromDate:otherDate];
return [dateComponents week] == [otherDateComponents week] && [dateComponents year] == [otherDateComponents year];
}
edit:
In this line:
unsigned unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
You don't pass NSWeekCalendarUnit, therefore [dateComponent week] returns NSUndefinedDateComponent
edit
Of course, it has to be NSWeekCalendarUnit…
Starting from iOS8, this became much easier:
-(BOOL)isDate:(NSDate *)date1 onSameWeekAs:(NSDate *)date2
{
return [[NSCalendar currentCalendar] isDate:date1
equalToDate:date2
toUnitGranularity:NSCalendarUnitWeekOfYear];
}
From the documentation:
returns YES if both dates have equal date component for all units
greater than or equal to the given unit, otherwise NO.
Related
Currently I have the below code to increment my days to the next friday, however what I need is to get the friday of the current week. For example if it is last Sunday, 03/01. I would expect my response to be last Friday(02/28) not Friday(03/06).
I have checked other answers but am getting confused with how to implement a clean way to accomplish this.
+ (NSDate *)getLastFridayYearsMonthStartingDate:(NSDate *)date {
NSDateComponents *dateComponents = [[NSCalendar gregorianCalendar] components:NSYearCalendarUnit|NSCalendarUnitDay|NSCalendarUnitMonth|NSWeekdayCalendarUnit
fromDate:date];
// Set date to last year, +1 to account for previous business day
[dateComponents setYear: -1];
[dateComponents setDay:[dateComponents day]+1];
// We always want the start date to be the friday of the given week, so we will increment the difference if not
if ([dateComponents weekday] != 6) {
NSInteger daysToFriday = (13 - [dateComponents weekday]) % 7;
[dateComponents setDay:[dateComponents day]+daysToFriday];
}
NSDate *fridayDate = [[NSCalendar gregorianCalendar] dateFromComponents:dateComponents];
return fridayDate;
}
try using setWeekday to set a specific day
-(NSDate *) getFriday:(NSDate *)date {
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[cal setTimeZone:[NSTimeZone systemTimeZone]];
NSDateComponents *comp = [cal components:NSYearCalendarUnit | NSWeekCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit fromDate:date];
[comp setWeekday:6];
[comp setHour:0];
[comp setMinute:0];
[comp setSecond:0];
return [cal dateFromComponents:comp];
}
Scenario:
I have an expense tracking iOS Application and I am storing expenses from a expense detail view controller into a table view (with fetched results controller) that shows the list of expenses along with the category and amount and date. I do have a date attribute in my entity "Money" which is a parent entity for either an expense or an income.
Question:
What I want is to basically categorize my expenses on a monthly basis and display it as the section header title for example : (Nov 1 - Nov 30,2012) and it shows expenses amount and related stuff according to that particular month. Two buttons are provided in that view, if I would press the right button, it will increment the month by a month (Dec 1 - Dec 31, 2012) and similarly the left button would decrement the month by a month.
How would I accomplish that? I am trying the following code - which is kinda working. Suppose I have my current section header as (Nov1 - Nov 30, 2012) and when I press the left button, it gives me the section header (Oct 1 - Oct 30, 2012) which is wrong, it should be Oct 31, 2012 and not Oct 30, 2012.
- (NSDate *)firstDateOfTheMonth
{
self.startDate = [NSDate date];
NSCalendar* calendar = [NSCalendar currentCalendar];
[calendar setTimeZone:[NSTimeZone localTimeZone]];
NSDateComponents* components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:self.startDate];
[components setDay:1];
firstDateOfTheMonth = [[calendar dateFromComponents:components] retain];
return firstDateOfTheMonth;
}
- (NSDate *)lastDateOfTheMonth
{
NSCalendar* calendar = [NSCalendar currentCalendar];
[calendar setTimeZone:[NSTimeZone localTimeZone]];
NSDateComponents* components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:firstDateOfTheMonth];
[components setMonth:[components month]+1];
[components setDay:0];
lastDateOfTheMonth = [[calendar dateFromComponents:components] retain];
return lastDateOfTheMonth;
}
Then I have a method called "monthCalculation" in which I call the above two methods.
- (void)monthCalculation
{
[self firstDateOfTheMonth];
[self lastDateOfTheMonth];
}
Now the following code when I press the left button (to decrement the month by a month):
- (IBAction)showPreviousDates:(id)sender
{
[self monthCalculation];
NSDateComponents *dateComponents = [[[NSDateComponents alloc] init] autorelease];
[dateComponents setMonth:-1];
NSDate *newDate1 = [[NSCalendar currentCalendar]
dateByAddingComponents:dateComponents
toDate:firstDateOfTheMonth options:0];
NSDate *newDate2 = [[NSCalendar currentCalendar]
dateByAddingComponents:dateComponents
toDate:lastDateOfTheMonth options:0];
self.startDate = newDate1;
self.endDate = newDate2;
NSLog(#" self start date in previous mode =%#", self.startDate);
NSLog(#" self end date in previous mode =%#", self.endDate);
}
The following code when I press the right button (to increment the month by a month):
- (IBAction)showNextDates:(id)sender
{
[self monthCalculation];
NSDateComponents *dateComponents = [[[NSDateComponents alloc] init] autorelease];
[dateComponents setMonth:1];
NSDate *newDate1 = [[NSCalendar currentCalendar]
dateByAddingComponents:dateComponents
toDate:firstDateOfTheMonth options:0];
NSDate *newDate2 = [[NSCalendar currentCalendar]
dateByAddingComponents:dateComponents
toDate:lastDateOfTheMonth options:0];
self.startDate = newDate1;
self.endDate = newDate2;
NSLog(#" self start date in previous mode =%#", self.startDate);
NSLog(#" self end date in previous mode =%#", self.endDate);
}
Am I doing it right? or there is a better way to do achieve this? Any help will be appreciated.
Here are some methods that should do what you want:
First, in your viewDidLoad method add:
self.startDate = [NSDate date];
[self updateDateRange];
This gives you a starting point. Then, I added the following five methods (Note: previousMonthButtonPressed/nextMonthButtonPressed should be wired up to your buttons):
// Return the first day of the month for the month that 'date' falls in:
- (NSDate *)firstDayOfMonthForDate:(NSDate *)date
{
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *comps = [cal components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
fromDate:date];
comps.day = 1;
return [cal dateFromComponents:comps];
}
// Return the last day of the month for the month that 'date' falls in:
- (NSDate *)lastDayOfMonthForDate:(NSDate *)date
{
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *comps = [cal components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
fromDate:date];
comps.month += 1;
comps.day = 0;
return [cal dateFromComponents:comps];
}
// Move the start date back one month
- (IBAction)previousMonthButtonPressed:(id)sender {
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *comps = [cal components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
fromDate:self.startDate];
comps.month -= 1;
self.startDate = [cal dateFromComponents:comps];
[self updateDateRange];
}
// Move the start date forward one month
- (IBAction)nextMonthButtonPressed:(id)sender {
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *comps = [cal components:NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit
fromDate:self.startDate];
comps.month += 1;
self.startDate = [cal dateFromComponents:comps];
[self updateDateRange];
}
// Print the new range of dates.
- (void)updateDateRange
{
NSLog(#"First day of month: %#", [self firstDayOfMonthForDate:self.startDate]);
NSLog(#"Last day of month: %#", [self lastDayOfMonthForDate:self.startDate]);
}
Try this:
- (NSDate *)lastDateOfTheMonth
{
NSCalendar* calendar = [NSCalendar currentCalendar];
[calendar setTimeZone:[NSTimeZone localTimeZone]];
NSDateComponents* components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:firstDateOfTheMonth];
[components setMonth:[components month]+1];
NSDateComponents* offset = [[[NSDateComponents alloc] init] retain];
[offset setDay:-1];
lastDateOfTheMonth = [[calendar dateByAddingComponents:offset toDate:[components date] options:0] retain];
return lastDateOfTheMonth;
}
I am trying to have points in time and then compare them. I have figured out how to compare them, but I am trying to create NSDate objects to represent times of day, and it is causing some trouble. I used NSDateFromComponents and used the setHour: and setMinute: functions, but it does not successfully modify the object. It also needs to automatically set the other components of the date to the current time and date.
COMPARING OBJECTS:
static bool DateIsBetween(NSDate *beginDate, NSDate *date, NSDate *endDate) {
return [date timeIntervalSince1970] > [beginDate timeIntervalSince1970] && [date timeIntervalSince1970] < [endDate timeIntervalSince1970];
}
CREATING DATE OBJECTS:
NSCalendar *calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
[calendar setTimeZone:[NSTimeZone timeZoneWithName:#"EST"]];
NSDateComponents *weekdayComponents = [calendar components:NSWeekdayCalendarUnit fromDate:todayDate];
NSDateComponents *genericTimeComponents = [[NSDateComponents alloc]init];
[genericTimeComponents setHour:5];
[genericTimeComponents setMinute:0];
[genericTimeComponents setDay:weekdayComponents.day];
[genericTimeComponents setYear:weekdayComponents.year];
[genericTimeComponents setMonth:weekdayComponents.month];
NSDateComponents *secondComps = [[NSDateComponents alloc]init];
[secondComps setHour:7];
[secondComps setMinute:0];
[secondComps setDay:weekdayComponents.day];
[secondComps setYear:weekdayComponents.year];
[secondComps setEra:weekdayComponents.era];
[secondComps setMonth:weekdayComponents.month];
Make sure to use parentheses in your date compare function (for the sake of clarity only; logically, it should work just fine):
static bool DateIsBetween(NSDate *beginDate, NSDate *date, NSDate *endDate) {
return (([date timeIntervalSince1970] > [beginDate timeIntervalSince1970]) && ([date timeIntervalSince1970] < [endDate timeIntervalSince1970]));
}
For such cases, it's a good idea to create a category for NSDate class and write an objective-c method.
For the rest, I tried the following code and it worked for me:
NSDate * now = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
[gregorian setTimeZone:[NSTimeZone localTimeZone]];
NSDateComponents *genericTimeComponents = [gregorian components:(NSWeekdayCalendarUnit |NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit |NSYearCalendarUnit|NSMonthCalendarUnit|NSEraCalendarUnit)
fromDate:now];
[genericTimeComponents setHour:5];
[genericTimeComponents setMinute:0];
// Quick Check
NSLog(#"GTC=%#", genericTimeComponents);
Hello
I have a problem with setting a firstWeekDay, here is what I do:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
comp = [gregorian components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekCalendarUnit | NSWeekdayCalendarUnit) fromDate:targetDate];
[comp setWeekday:2];
NSDate *firstWeekDay = [gregorian dateFromComponents:comp];
If Saturday 2011-01-01 is targetDate, the firstWeekDay in my calendar appears to be Monday 2011-12-26, but in fact it should be Monday 2010-12-26. How can I make it right?
To fix this problem, Add NSYearForWeekOfYearCalendarUnit in the NSDateComponents.
Ex:
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* comps = [calendar components:NSYearForWeekOfYearCalendarUnit |NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:curDate];
[comps setWeekday:2]; // 2: monday
firstDayOfTheWeek = [calendar dateFromComponents:comps];
[comps setWeekday:7]; // 7: saturday
lastDayOfTheWeek = [calendar dateFromComponents:comps];
Try this
// adjust them for first day of previous week (Monday)
[comp setWeekday:2];
[comp setWeek:([comp week] - 1)];
Note this solution assumes the first day of the week is Monday.
Below also covers the edge case,
- (NSDate *)getFirstDayOfTheWeekFromDate:(NSDate *)givenDate
{
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:givenDate];
[components setWeekday:2]; // 1 == Sunday, 7 == Saturday
if([[calendar dateFromComponents:components] compare: curDate] == NSOrderedDescending) // if start is later in time than end
{
[components setWeek:[components week]-1];
}
return [calendar dateFromComponents:components];
}
The Swift solution (thanks #YvesJusot):
let calendar = NSCalendar.currentCalendar()
let comps = calendar.components(NSCalendarUnit.WeekOfYearCalendarUnit|NSCalendarUnit.YearCalendarUnit|NSCalendarUnit.MonthCalendarUnit|NSCalendarUnit.WeekCalendarUnit|NSCalendarUnit.WeekdayCalendarUnit, fromDate: NSDate()) as NSDateComponents
comps.setValue(2, forComponent: NSCalendarUnit.WeekdayCalendarUnit)
let monday = calendar.dateFromComponents(comps)!
println("\(monday)")
You suppose to use dynamic values instead of hardcoding 2 as Monday!
NSCalendar* calendar = [NSCalendar currentCalendar];
NSDateComponents* comps = [calendar components:NSYearForWeekOfYearCalendarUnit|NSYearCalendarUnit|NSMonthCalendarUnit|NSWeekCalendarUnit|NSWeekdayCalendarUnit fromDate:[NSDate date]];
comps.weekday = calendar.firstWeekday;
firstDayOfTheWeek = [calendar dateFromComponents:comps];
comps.weekday = calendar.firstWeekday - 1;
lastDayOfTheWeek = [calendar dateFromComponents:comps];
I did some changes in #JasonGarrett answer and it works for me.
let calendar = NSCalendar.currentCalendar()
let flags : NSCalendarUnit = NSCalendarUnit.CalendarUnitDay | NSCalendarUnit.CalendarUnitMonth | NSCalendarUnit.CalendarUnitYear
let comps = calendar.components(flags, fromDate: NSDate()) as NSDateComponents
comps.setValue(2, forComponent: NSCalendarUnit.CalendarUnitWeekday)
let monday = calendar.dateFromComponents(comps)!
// Make these two methods as categories to NSDate
// Use This to get First date of the week (Monday)
- (NSDate *) getFirstDayOfWeek {
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *compOfDate = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday) fromDate:self];
NSInteger numOfDaysToAdd = compOfDate.weekday == 1 ? -6 : (2 - compOfDate.weekday);
NSDateComponents *compToAdd = [[NSDateComponents alloc] init];
compToAdd.day = numOfDaysToAdd;
return [calendar dateByAddingComponents:compToAdd toDate:self options:0];
}
// Use This to get last date of the week (Sunday)
- (NSDate *)getLastDayOfWeek {
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *compOfDate = [calendar components:(NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitWeekday) fromDate:self];
NSInteger numOfDaysToAdd = compOfDate.weekday == 1 ? 0 : (8 - compOfDate.weekday);
NSDateComponents *compToAdd = [[NSDateComponents alloc] init];
compToAdd.day = numOfDaysToAdd;
return [calendar dateByAddingComponents:compToAdd toDate:self options:0];
}
how do I set an existing NSDate's time?
That is I have a date (say current date/time), but then want to set this to a specific time (e.g. 11.23am) say. What is the quickest way to do this in objective C?
I'm looking at NSCalendar and see methods such as dateByAddingComponents:toDate:options:, and dateFromComponents:, but these don't seem to quite hit the mark for what I need here. For example:
dateFromComponents: - I would have to work out all components for this to work which seems like overkill
dateByAddingComponents:toDate:options: - I don't want to ADD in my case but rather "set" the time.
NSDate *date = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents *components = [gregorian components: NSUIntegerMax fromDate: date];
[components setHour: 7];
[components setMinute: 59];
[components setSecond: 17];
NSDate *newDate = [gregorian dateFromComponents: components];
I use NSUIntegerMax instead of specific OR-combined bit masks because it's easier, but if you want to specify which data components to receive, be my guest.
iOS 7 Note: I'm putting this in a few of these questions because use of NSUIntegerMax no longer seems to work on iOS7, and using it caused me to chase my tail for about 3 hours. I just discovered that when I use NSUIntegerMax, NSDateComponentsignores set year. So for example this DOES NOT change the year:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *comps = [gregorian components:NSUIntegerMax fromDate:date];
[comps setYear:year];
return [gregorian dateFromComponents:comps];
Whereas this DOES:
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSUInteger timeComps = (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit | NSTimeZoneCalendarUnit);
NSDateComponents *comps = [gregorian components:timeComps fromDate:date];
[comps setYear:year];
return [gregorian dateFromComponents:comps];
It may be an iOS7 bug or it may be that using NSUIntegerMax working was a fluke which no longer works. I will file a bug report and get a definitive answer.
Regardless, if you want to avoid unexpected consequences specify ALL the components else you might be chasing your tail!
Swift 2.0 version of how you'd set a given date to 8am
extension NSDate {
func setTo8AM() -> NSDate {
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let components = calendar.components(([.Day, .Month, .Year]), fromDate: self)
components.hour = 8
return calendar.dateFromComponents(components)!
}
}
Apply this to set the Time from an another date to an existing Date
NSDate *today = [NSDate date]; // from which i need only "Year" "Month" "Date"
NSCalendar *calendar = [NSCalendar currentCalendar]
NSDateComponents *dateComponents = [calendar components:( NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit ) fromDate:today];
NSDate *timeDate = datePicker.date; // from which i need only "Hours" "Minutes" and "Seconds"
NSDateComponents *timeComponents = [calendar components:( NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit ) fromDate:timeDate];
[dateComponents setHour:[timeComponents hour]];
[dateComponents setMinute:[timeComponents minute]];
[dateComponents setSecond:[timeComponents second]];
NSDate *newDate = [calendar dateFromComponents:dateComponents]; // New Date with My "Year" "Month" "Date" "Hours" "Minutes" and "Seconds"
NSLog(#"New Date: %#",newDate);
Here's a more generic Swift (v2.1.1) extension that builds on Andrew Schreiber's helpful answer.
extension NSDate {
func dateWithTime(hour: Int, minute: Int, second: Int) -> NSDate? {
let calendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!
let components = calendar.components(([.Day, .Month, .Year]), fromDate: self)
components.hour = hour
components.minute = minute
components.second = second
let newDate = calendar.dateFromComponents(components)
return newDate
}
}
A swift example. For my purposes, I wanted to get the date for around 12 noon tomorrow.
var tomorrow:NSDate = NSDate().dateByAddingTimeInterval(60*60*24); //60seconds*60minutes*12hours
var gregorian:NSCalendar = NSCalendar(calendarIdentifier: NSCalendarIdentifierGregorian)!;
var unit : NSCalendarUnit = (NSCalendarUnit.YearCalendarUnit|NSCalendarUnit.MonthCalendarUnit|NSCalendarUnit.DayCalendarUnit|NSCalendarUnit.HourCalendarUnit|NSCalendarUnit.MinuteCalendarUnit);
var comps:NSDateComponents = gregorian.components(unit, fromDate: tomorrow);
comps.setValue(12, forComponent: NSCalendarUnit.HourCalendarUnit);
comps.setValue(0, forComponent: NSCalendarUnit.MinuteCalendarUnit);
var noon_tomorrow : NSDate = gregorian.dateFromComponents(comps)!;