After comparing two dates (currentDate and _timerStartDate) I get the following output
nstimeinterval: 88.998212
2014-05-14 14:07:08.284 currentDate: 14-05-2014 14:07:08
2014-05-14 14:07:08.284 stopDate: 14-05-2014 14:05:39
2014-05-14 14:07:08.284 hour: 10
This is correct and expected. However when I break timerDate down I get 10 hours from the NSLog...I'm expecting zero. What am I doing wrong?
Here is my code:
NSDate *currentDate = [NSDate date];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:_timerStartDate];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"mm:ss"];
NSString *timeString=[dateFormatter stringFromDate:timerDate];
NSLog(#"nstimeinterval: %f", timeInterval);
[dateFormatter setDateFormat:#"dd-MM-yyyy HH:mm:ss"];
NSLog(#"currentDate: %#", [dateFormatter stringFromDate:currentDate]);
NSLog(#"stopDate: %#", [dateFormatter stringFromDate:_timerStartDate]);
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components: ( NSHourCalendarUnit | NSYearCalendarUnit) fromDate:timerDate];
NSLog(#"year: %li", (long)components.year);
NSLog(#"timer: %#", timeString);
timerTicksForCounter = timeString;
NSLog(#"hour: %li", (long)components.hour);
What is it you're actually trying to accomplish? To populate an NSDateComponents with the time elapsed between two dates? In that case, you probably want -[NSCalendar components:fromDate:toDate:options:], with the from-date being your start, and the to-date being the current date when you stop. In the mean time, you seem to be doing a lot of complicated and possibly unnecessary mashing of dates together.
Related
I want to change hour in NSDate. I did something like this:
NSDate *final = [gregorian dateBySettingUnit:NSCalendarUnitHour value:hour.intValue ofDate:self.dateForNewEvent options:NSCalendarMatchStrictly];
where self.dateForNewEvent = 2018-07-09 07:24:13 +0000
and hour.intValue = 5 and i expect date = 2018-07-09 05:00:00 + 0000 but i got 2018-07-10 03:00:00 UTC. How should I do it to get expected date ?
To change the hours of a specific NSDate, you need to manipulate it via NSDateComponents. Please try below code for the same:
NSDate *now = [NSDate date]; // YOUR DATE INSTANCE
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSCalendarIdentifierGregorian];
NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate:now];
[components setHour:5];
NSDate *today5am = [calendar dateFromComponents:components];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
NSLog(#"Date ===>>> %#",[dateFormatter stringFromDate:[NSDate date]]);
Hope this helps!
I think you are mixing NSDate with NSCalendar: NSDate is a point in time, internally represented in UTC. To get the local date/time as it is displayed on a calendar or watch , you use NSCalendar.
So if you are in MEST (UTC+2) and set the time to "5" hours on your calendar, this will be UTC "3" hours.
To get the calendar date/time back, you could use components(_:from:) from NSCalendar.
Just check this code:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssZZZZZ"];
NSDate * dateForNewEvent = [dateFormatter dateFromString: #"2018-07-09T07:24:13+00:00"];
NSLog(#"dateForNewEvent: %#", dateForNewEvent);
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *comps = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear|NSCalendarUnitHour|NSCalendarUnitMinute fromDate:dateForNewEvent];
[comps setHour:5];
NSDate *final = [gregorian dateFromComponents:comps];
NSLog(#"final: %#", final);
Output as expected:
2018-07-09 11:11:43.542 jdoodle[22:22] dateForNewEvent: 2018-07-09 07:24:13 +0000
2018-07-09 11:11:43.542 jdoodle[22:22] final: 2018-07-09 05:24:00 +0000
Suppose, my birthdate is (mon/day/year) 10-05-1932 (as NSDate), how to convert this to NSTimeInterval.
Again, how to convert back that NSTimeInterval to NSDate back?
I tried using different methods of NSDate but haven't succeed yet.
What I'm doing?
NSString *strdate = #"10-05-1932";
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"MM-dd-yyyy"];
NSDate *date = [df dateFromString:strdate];
NSLog(#"%.f", -[date timeIntervalSinceNow]);
This logs 2616605071 (as on 4th September 2015 at 16:21) – When I checked it with the site like this it gives me wrong date.
NSTimeInterval timeInterval = date.timeIntervalSinceReferenceDate;
NSDate *anotherDate = [NSDate dateWithTimeIntervalSinceReferenceDate: timeInterval];
Try the code below. date and anotherDate will be identical.
NSCalendar *calendar = [NSCalendar currentCalendar];
calendar.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setDay:10];
[components setMonth:5];
[components setYear:1934];
NSDate *date = [calendar dateFromComponents:components];
NSLog(#"%#", date);
NSTimeInterval timeInterval = [date timeIntervalSinceReferenceDate];
NSDate *anotherDate = [NSDate dateWithTimeIntervalSinceReferenceDate:timeInterval];
NSLog(#"%#", anotherDate);
UPDATE:
It's incorrect because you get timestamp (time interval) from that website which use UNIX timestamp. Also, it's incorrect because you use timeIntervalSinceNow which will likely change every time you call the method because it's relative to the current time. If you want the date/time interval that compatible with that website. Use:
NSTimeInterval timeInterval = date.timeIntervalSince1970;
NSDate *anotherDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
You can copy the timeInterval from the code above (-1188000000) and paste it on the website and it will give you a correct date.
Internally, NSDate store time interval relative to reference date (Jan 1st, 2001). The website you mentioned is UNIX timestamp that relative to Jan 1st, 1970.
This is just worked!
NSString *strdate = #"10-05-1932";
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"MM-dd-yyyy"];
NSDate *date = [df dateFromString:strdate];
NSLog(#"%#",date);
NSTimeInterval interval = [date timeIntervalSince1970];
NSLog(#"%f", interval);
NSDate *date2 = [NSDate dateWithTimeIntervalSince1970:interval];
NSLog(#"%#",date2);
Thanks to #sikhapol
I have 2 dates. Date1 in yyyy-MM-dd 21:00:00 +0000. Date2 in yyyy-MM-dd
I need to compare it and get age result.
Problem is that Ia have an error in NSDateComponents string.
NSDate *date1 = [NSDate date];
NSDate *date2temp = uBirthdate;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSString *dateString = [dateFormatter stringFromDate:date2temp];
[dateString stringByAppendingString:#" 21:00:00 +0000"];
NSDate *date2 = [dateFormatter dateFromString:dateString];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:NSYearCalendarUnit fromDate:date2 toDate:date1 options:0];
NSInteger editedAge = components.year;
NSLog(#"%d ", editedAge);
It will be better to cut off '21:00:00 +0000' from date1, but I do not know how can I do it
iOS Programming: I just want to let iOS7 get the "America/Chicago" current date and time.
I searched a lot on Internet, but there are a lot of different solutions. I tried several solutions, but they do not work.
You can use the NSCalendar and NSTimezone classes. The following code segment demonstrates retrieving the current hour and minute. Extending it to retrieve other date components is straight-forward -
long hour;
long minute;
NSCalendar *cal=[NSCalendar currentCalendar];
NSDate *now=[NSDate date];
NSTimeZone *tz=[NSTimeZone timeZoneWithName:#"America/Chicago"];
[cal setTimeZone:tz];
NSDateComponents *comp=[cal components:NSHourCalendarUnit|NSMinuteCalendarUnit fromDate:now];
hour=[comp hour];
min=[comp minute];
You can use this method,
- (NSDate *) getCountryDateWithTimeZone:(NSString *)zone
{
NSDate *now = [NSDate date];
NSTimeZone *szone = [NSTimeZone timeZoneWithName:zone];
NSInteger sourceGMTOffset = [szone secondsFromGMTForDate:now];
NSTimeInterval interval = sourceGMTOffset;
NSDate *destinationDate = [NSDate dateWithTimeInterval:interval sinceDate:now];
return destinationDate;
}
And,
[self getCountryDateWithTimeZone:#"America/Chicago"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *firstDate = #"2014-06-05 12:55:00";
NSDate *date=[dateFormatter dateFromString:firstDate];
NSDate *currentDate = [NSDate date];
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSDayCalendarUnit|NSHourCalendarUnit|NSMinuteCalendarUnit|NSSecondCalendarUnit fromDate:date toDate:currentDate options:0];
NSLog(#"The difference between from date and to date is %d days and %d hours and %d minute and %d second",components.day,components.hour,components.minute,components.second);
Output:
DateBookApp[1179:70b] The difference between from date and to date is 0 days and 22 hours and 57 minute and 12 Second
In short words I plan to get current dateTime, change the time and make it local to Malaysia Time by applying +0800 to timezone.
The result is unexpected :
-(NSDate *)departureDateTime
{
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];
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-mm-dd HH:mm:ss Z"];
[dateFormat setLocale:[NSLocale currentLocale]];
NSString *newDateString = [NSString stringWithFormat:#"%#",newDate];
NSString *maskString = [NSString stringWithFormat:#"%#", [newDateString substringToIndex:20]];
NSString *append = [maskString stringByAppendingString:#"+0800"];
NSLog(#"%#",append);
NSDate *finalLocalDate = [dateFormat dateFromString:append];
return finalLocalDate;
}
Results :
for NSLog Append : 2013-12-07 23:59:17 +0800
but finalLocalDate : 2013-01-07 15:59:17 +0000
Found the answer with much shorter solution, so I posted here in case it helps anyone in future.
for returning, the problem was different time zones so by adding this line of
[components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:(+0*3600) ] ];
we set the timezone to system time zone then we remove unnecessary codes :
-(NSDate *)departureDateTime
{
NSDate *date = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier: NSGregorianCalendar];
NSDateComponents *components = [gregorian components: NSUIntegerMax fromDate: date];
[components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:(+0*3600) ] ];
[components setHour: 7];
[components setMinute: 59];
[components setSecond: 17];
NSDate *newDate = [gregorian dateFromComponents: components];
NSLog(#"%#",newDate);
return newDate;
}
Correct Result : 2013-12-08 07:59:17 +0000
try this:
NSTimeInterval now = [[NSDate date] timeIntervalSince1970];
NSDate *malaysianTime = [NSDate dateWithTimeIntervalSince1970:now+(8*60*60)]; //8h in seconds
If your computer is running in the correct timezone don't set a timezone.
Create your newDate value and then --
NSDateFormatter* fmt = [[NSDateFormatter alloc] init];
[fmt setDateFormat:#"yyyy-MM-dd HH:mm:ss Z"];
NSString* printableDate = [fmt stringFromDate:newDate];
NSLog(#"The date is %#", printableDate);
Only set a timezone (in both NSCalendar and NSDateFormatter) if the desired timezone is not the one your computer/phone is currently using.
Note that if you NSLog newDate directly it will print in GMT timezone. This is the way it's supposed to be -- you always use NSDateFormatter for a printable date. When you NSLog an NSDate directly you get GMT, by design.