Trying to set current date and date parameters to past date - ios

I am trying to create a function that pulls data that only has a time stamp of a specific date. It is for a project and the most recent data in the set is from February. I still want to use the standard yesterday, last week, last month parameters.
Is there any way to set the "current date" to a specific date so I can make the time frames based on that instead of the actual current date?
This is what I've tried
NSString *datestr = #"2014-02-16T04:59:50.021Z";
NSDateFormatter *dformat = [[NSDateFormatter alloc]init];
[dformat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssz"];
NSDate *date = [dformat dateFromString:datestr];
NSTimeInterval secondsPerDay = 24 * 60 * 60;
NSDate *yesterday = [[NSDate date] dateByAddingTimeInterval: date -secondsPerDay];
NSDate *lastWeek = [[NSDate alloc]initWithTimeIntervalSinceNow: - secondsPerDay * 7];
NSDate *lastMonth = [[NSDate alloc]initWithTimeIntervalSinceNow:-secondsPerDay * 30];
Trying to subtract secondsPerDay from date yields an arithmetic error. Any workarounds?

You can't subtract an NSTimeInterval (which is a double) from an NSDate (which is an object). You want to send the dateByAddingTimeInterval: message to the date from which the time will be subtracted:
NSString *datestr = #"2014-02-16T04:59:50.021Z";
NSDateFormatter *dformat = [[NSDateFormatter alloc]init];
[dformat setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssz"];
NSDate *date = [dformat dateFromString:datestr];
NSTimeInterval secondsPerDay = 24 * 60 * 60;
NSDate *yesterday = [date dateByAddingTimeInterval:-secondsPerDay];
NSDate *lastWeek = [date dateByAddingTimeInterval:-(secondsPerDay * 7)];
NSDate *lastMonth = [date dateByAddingTimeInterval:-(secondsPerDay * 30)];
Note, however, that lastMonth will not be exactly correct, since not every month has 30 days. Instead, you may also want to look at NSDateComponents:
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *todayComponents = [NSDateComponents new];
todayComponents.year = 2014;
todayComponents.month = 2;
todayComponents.day = 16;
todayComponents.hour = 4;
todayComponents.minute = 59;
todayComponents.second = 50;
NSDate *today = [calendar dateFromComponents:todayComponents];
NSDateComponents *offset = [NSDateComponents new];
offset.day = -1;
NSDate *yesterday = [calendar dateByAddingComponents:offset toDate:today options:0];
offset = [NSDateComponents new];
offset.day = -7;
NSDate *lastWeek = [calendar dateByAddingComponents:offset toDate:today options:0];
offset = [NSDateComponents new];
offset.month = -1;
NSDate *lastMonth = [calendar dateByAddingComponents:offset toDate:today options:0];

Related

NSDateComponents wrongly adds one extra hour

I'm trying to create a method in Objective-C which would get the total number of minutes from a time value, written in "HHmm" format.
E.g. for "0210" the return value should be 130.
+ (int)totalMinutesFromHHmm:(NSString *)HHmm {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"UTC"];
[dateFormatter setTimeZone:timeZone];
[dateFormatter setDateFormat:#"HHmm"];
NSLocale *enLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en-GB"];
[dateFormatter setLocale:enLocale];
NSDate *date = [dateFormatter dateFromString:HHmm];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *components = [calendar components:( NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond) fromDate:date];
NSInteger hour = [components hour];
NSInteger minute = [components minute];
return (int)(hour * 60 + minute);
}
The problem is the hour component: it's always one hour off.
On this picture the NSDate shows a 09:22 time, but on the picture below you can see the hour component is 10 (the minute component is correctly set to 22).
I looked at other posts ('NSDateComponents on hour off', etc.), but couldn't find a solution that works. Any idea what I'm doing wrong?
Time Zone / locale might not need to come into this. I could be misunderstanding, but it seems like you are just trying to take a string in HHmm format and calculate the total minutes.
If you need to use NSDate still for some reason, this could work:
+ (int)totalMinutesFromHHmm:(NSString*)HHmm
{
NSString* refHHmm = #"0000";
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HHmm"];
NSDate* refDate = [dateFormatter dateFromString:refHHmm];
NSDate* date = [dateFormatter dateFromString:HHmm];
int minutes = [date timeIntervalSinceDate:refDate] / 60;
return minutes;
}
Otherwise, this could be a simpler option, since you know you will have a 4-character string representing the hours and minutes:
+ (int)totalMinutesFromHHmm:(NSString*)HHmm
{
int minutes = [[HHmm substringWithRange:NSMakeRange(0, 2)] intValue] * 60;
minutes += [[HHmm substringWithRange:NSMakeRange(2, 2)] intValue];
return minutes;
}

The setHour Function changing the timezone for a function

So I am trying to get the current date and time and then trying to override the Hours and the minutes so as to set up a fire time. But whenever I use the [comp sethour] functionality it reverts it to GMT timings for some reason.
In the header file I have :
static int re_hour = 19;
static int re_minute = 52;
and in the .m File I have this function
- (void) ScheduleTimer {
NSCalendar* myCalendar = [NSCalendar currentCalendar];
//Get The GMT Time
NSDate* now = [NSDate date];
//Get The Current Timezone and then convert the Time
NSTimeZone* currentTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
NSTimeZone* nowTimeZone = [NSTimeZone systemTimeZone];
NSInteger currentGMTOffset = [currentTimeZone secondsFromGMTForDate:now];
NSInteger nowGMTOffset = [nowTimeZone secondsFromGMTForDate:now];
NSTimeInterval interval = nowGMTOffset - currentGMTOffset;
NSDate* nowDate = [[NSDate alloc] initWithTimeInterval:interval sinceDate:now];
//Setting the restart Time
NSDateComponents *comp = [myCalendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit|NSTimeZoneCalendarUnit fromDate:nowDate];
[comp setHour:re_hour];
[comp setMinute:re_minute];
NSDate *restartTime = [myCalendar dateFromComponents:comp];
NSLog(#"The time of restart :%#",restartTime);
}
and it always seems to return:
2014-08-26 19:52:34.032 SASMobile[2605:60b] The time of restart :2014-08-27 02:52:34 +0000

How to calculate NSDate between two NSDate in IOS

I want show whether particular office is opened or closed depends on the weekday
i am getting office timings from my server
NSString *open = #"10:00 AM";
NSString *close = #"6:00 PM";
NSDateFormatter *df11 = [[NSDateFormatter alloc]init];
[df11 setDateFormat:#"dd-MM-yyyy"];
NSString *date11=[df11 stringFromDate:[NSDate date]];
NSDateFormatter *df = [[NSDateFormatter alloc]init];
[df setDateFormat:#"dd-MM-yyyy hh:mm a"];
NSDate *date1 = [NSDate date];
NSString *dte1 = [df stringFromDate:date1];
date1 = [df dateFromString:dte1];
NSString *dte2 = [NSString stringWithFormat:#"%# %#",date11, open];
NSDate *date2 = [df dateFromString:dte2];
NSString *dte3 = [NSString stringWithFormat:#"%# %#",date11,close];
NSDate *date3 = [df dateFromString:dte3];
if([date1 compare:date2]==NSOrderedDescending && [date1 compare:date3]==NSOrderedAscending)
open=YES;
else
open=NO;
In this case i didn't get any problem, but for some other office i got like this
NSString *open = #"11:30 AM";
NSString *close = #"12:30 AM";/*means here day is changing but still i am using current date
for this case the above code is not working, bcoz of day changes, i am not getting any idea how to follow, i was struggling from last day for solution
please help me
thank you
get days between two dates
NSDate *date1 = [NSDate dateWithString:#"2013-08-08"];
NSDate *date2 = [NSDate dateWithString:#"2013-09-09"];
NSTimeInterval secondsBetween = [date2 timeIntervalSinceDate:date1];
int numberOfDays = secondsBetween / 86400;
NSLog(#"There are %d days in between the two dates.", numberOfDays);
You can also get different between two dates GO
Extract the week day and hour from the date and do an explicit test on them:
const NSInteger openHour = 10;
const NSInteger closeHour = 18;
NSDate *dateToTest = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSWeekdayCalendarUnit|NSHourCalendarUnit
fromDate:dateToTest];
BOOL open =
[components weekDay] >= [calendar firstWeekDay] &&
[components weekDay] < [calendar firstWeekDay] + 5 &&
[components hour] >= openHour &&
[components hour] < closeHour;

ios - get in between dates (in actual date, not number of days)

I have two date string and I wanted to get the in between dates.
For example,
NSString *startDate = #"25-01-2014";
NSString *endDate = #"02-02-2014";
In between dates will be (26-01-2014, 27-01-2014, 28-01-2014.......)
preferably include startDate and endDate as well. Most of the question I managed to find asked for number of days. But I needed it to be actual date. Is there anyway that I can get the in between dates?
NSString *start = #"2010-09-01";
NSString *end = #"2010-12-05";
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:#"yyyy-MM-dd"];
NSDate *startDate = [f dateFromString:start];
NSDate *endDate = [f dateFromString:end];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorianCalendar components:NSDayCalendarUnit
fromDate:startDate
toDate:endDate
options:0];
NSLog(#"Difference in date components: %d", components.day);
I managed to find this which only returns number of days difference.
NSString *start = #"2010-09-01";
NSString *end = #"2010-12-05";
NSDateFormatter *f = [[NSDateFormatter alloc] init];
[f setDateFormat:#"yyyy-MM-dd"];
NSDate *startDate = [f dateFromString:start];
NSDate *endDate = [f dateFromString:end];
NSMutableArray *dates = [#[startDate] mutableCopy];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorianCalendar components:NSDayCalendarUnit
fromDate:startDate
toDate:endDate
options:0];
for (int i = 1; i < components.day; ++i) {
NSDateComponents *newComponents = [NSDateComponents new];
newComponents.day = i;
NSDate *date = [gregorianCalendar dateByAddingComponents:newComponents
toDate:startDate
options:0];
[dates addObject:date];
}
[dates addObject:endDate];
The array dates now contains the list of dates between startDate and endDate, including those, for midnight in the timezone of the device.
Note, that on some timezones this might cause trouble, as the switch from and to Daylight Saving Time might occur at that moment, see WWDC 2011 Video "Session 117 - Performing Calendar Calculations" for further information. One trick is to shift the hour to a save time, i.e. noon, do the calculation and than subtract 12 hours.
Ok, you're most of the way there. You have a date formatter that converts the date strings to NSDates. You have the number of days between the dates. Now you need to loop from the start date for that many days, adding a variable number of days to the start date.
The method you need is dateByAddingComponents:toDate:options:.
Something like this (goes immediately after your code) :
int days = components.day;
NSDateComponents *daysToAdd = [[NSDateComponents alloc] init];
for (int count = 0; count <= days; count++)
{
daysToAdd.day = count;
NSDate *loopDate = [gregorianCalendar dateByAddingComponents: daysToAdd
toDate: startDate
options: 0 ];
NSLog(#"Day %d = %#", count+1, [f stringFromDate: loopDate]);
}
I haven't tested it, but that's the basic idea...
The code above should include both the start and end dates.
If you don't want to include the start date, make the loop start at count = 1 instead of count = 0.
If you don't want to include the end date, make the loop check count < days.
A little late but found a fix to the 'TIMEZONE' time issue that vikingosegundo talked about in his answer. I simply converted the NSDate to an NSString by calling a stringFromDate method on the formatter *f in your for loop...
for (int i = iStart; i < components.day; ++i) {
NSDateComponents *newComponents = [NSDateComponents new];
newComponents.day = i;
newComponents.hour = 0;
newComponents.minute = 0;
newComponents.second = 0;
NSDate *date = [gregorianCalendar dateByAddingComponents:newComponents
toDate:startDate
options:0];
// THIS IS THE CODE I ADDED TO MINE //
// convert NSDate to string calling on *f (NSDateformatter)
NSString *string = [f stringFromDate:date];
// split the string to separate year, month, etc...
NSArray *array = [string componentsSeparatedByString:#"-"];
// create second NSString withFormat and only add the variable from the date that you find pertinent
NSString *sDateNew = [NSString stringWithFormat:#"%#-%#-%#",array[0],array[1],array[2]];
// then simply add the sDateNew string to dates array
[dates addObject:sDateNew];
}
I think this should be put into the comment section of your answer vikingsegundo but it would not let me.

Get time from pressed button (hold pressed)

When trying to get the time, I am not getting the expected value.
When I ran this, the time was 19:59. And in the timeDifferenceString, the Value was 71976.894206.
I think that this is the current time.
I calculate 71976 / 3600 = 19,99 h
0,99 * 60 = 59,4 m
0,4 * 60 = 24 s
So I get the time 19:59:24 o'clock. But I want get the difference between the first time and the second time and not the current time in seconds.
I want only get the time when I (hold) pressed the button
and the time that the button is not pressed (by starting the first time if I press on the button and stopped if I press on an other button).
- (IBAction)pressTheButton:(id)sender {
NSDate * now = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"hh:mm:ss:SSS"];
NSString *currentTime = [formatter stringFromDate:now];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components; //= [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:now];
[components setHour:10];
NSDate* firstDate = [NSDate date];
NSString *getTime = [formatter stringFromDate:now];
getTime = [formatter stringFromDate:firstDate];
if (iX==0)
{
components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:now];
firstDate = [calendar dateFromComponents:components];
getTime = [formatter stringFromDate:firstDate];
//firstDate = [NSDate date];//[dateFormatter dateFromString:#"00:01:00:090"];
}
components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:now];
//NSDate* secondDate = [dateFormatter dateFromString:#"10:01:02:007"];
NSDate * secondDate = [calendar dateFromComponents:components];
getTime = [formatter stringFromDate:firstDate];
NSTimeInterval timeDifference = [firstDate timeIntervalSinceDate:secondDate];
NSString *timeDifferenceString = [NSString stringWithFormat:#"%f", timeDifference];
timeDiff[iX] = [timeDifferenceString intValue];
[timeLabel setText:timeDifferenceString];
iX++;
}
If you have a better solution for my problem pleas help me.
Look at UIControlEventTouchDown, UIControlEventTouchUpInside here: http://developer.apple.com/library/ios/#documentation/uikit/reference/UIControl_Class/Reference/Reference.html
Then I suppose you want to store an NSDate of when you pressed down in some sort of ivar or property (UIControlEventTouchDown) and another one when you release the button (UIControlEventTouchUpInside or UIControlEventTouchUpOutside) and then call -timeIntervalSinceDate: on that date. So it would look roughly like this:
- (IBAction)pressedDown:(id)sender {
self.pressedDownDate = [NSDate date];
}
- (IBAction)touchedUp:(id)sender {
NSDate *now = [NSDate date];
NSLog(#"Time passed: %d", [now timeIntervalSinceDate:self.pressedDownDate]);
}

Resources