Create a NSDate with a user selected time in objective c - objective-c

int hour = [[array objectAtIndex:0] intValue]; //hour = 17
int min = [[array objectAtIndex:1] intValue]; //min = 51
NSLog(#"hour value is %d",hour);
NSLog(#"min value is %d",min);
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:[NSDate date]];
int year = [components year];
int month = [components month];
int day = [components day];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
dateFormatter.timeStyle = NSDateFormatterNoStyle;
[components setYear:year];
[components setMonth:month];
[components setDay:day];
[components setHour:hour];
[components setMinute:min];
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] ;
NSDate *itemDate = [cal dateFromComponents:components];
NSLog(#"the date is %#",itemDate);
Output:
the date is 2012-11-03 01:00:00 +0000 . But i want the output to be 2012-11-03 17:51:00..how can i get it?What am i doing wrong?

It appears your issue is a simple matter of not realizing that the NSDate object will be created using your own current timezone but the NSLog will print out the NSDate description using UTC. Since you appear to be in PDT (it will be PST later this weekend when the clocks change in the USA), your NSLog should show the desired date/time but it will appear to be 7 hours (8 hours later this weekend) off.
To show your date in the local timezone, use an NSDateFormatter to convert the NSDate to an NSString.

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
NSLog(#"the date is %#", dateString);

Related

NSDate: I enter only utc time components and set the calendar correctly, but the NSDate somehow gets recalculated to my timezone

I have a date as a string which is in UTC format. I create the NSDate correctly and set the calendar as well to UTC. Nevertheless the date in the end is in local time zone. If my UTC time was 21:25 and I set it up with this code, I in the end get via a NSLog of the new date 23:25. Why?
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setYear:[[timeStamp substringWithRange:NSMakeRange(0, 4)] floatValue]];
[dateComponents setMonth:[[timeStamp substringWithRange:NSMakeRange(5, 2)] floatValue]];
[dateComponents setDay:[[timeStamp substringWithRange:NSMakeRange(8, 2)] floatValue]];
[dateComponents setHour:[[timeStamp substringWithRange:NSMakeRange(11, 2)] floatValue]];
[dateComponents setMinute:[[timeStamp substringWithRange:NSMakeRange(14, 2)] floatValue]];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
[calendar setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
NSDate *configuredDate = [calendar dateFromComponents:dateComponents];
BTW: I am in timezone Berlin. So +2 would be correct, but still, the date should be in UTC?!
Here is the edit:
2018-10-17 19:11:54.964754+0200 FollowMe[2005:91382] Time stamp before: 2018-10-17T17:37Z
2018-10-17 19:11:54.965017+0200 FollowMe[2005:91382] Configured date: Wed Oct 17 19:37:00 2018
2018-10-17 19:11:54.965096+0200 FollowMe[2005:91382] Time Interval: 1539797820.000000
The solution I found was to set the defaultTimezone to "UTC" before creating the calendar, and then create the date using dateFromComponents.
Now the date is correctly created, and can be retrieved and converted to whatever timezone needed using a dateFormatter, for which the desired timezone is set.
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setYear:1987];
[components setMonth:4];
[components setDay:10];
[components setHour:0];
[components setMinute:0];
[components setSecond:0];
[components setNanosecond:0];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDate *date = [gregorianCalendar dateFromComponents:components];
NSLog(#"%#", date); // puts out Fri Apr 10 00:00:00 1987
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss.s ZZZZ"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"Europe/Berlin"]];
NSLog(#"%#", [dateFormatter stringFromDate:date]); // puts out 1987-04-10 00:00:00.0 GMT+02:00
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
NSLog(#"%#", [dateFormatter stringFromDate:date]); // puts out 1987-04-09 22:00:00.0 GMT
Now if I change defaultTimeZone:
NSTimeZone *UTCzone=[NSTimeZone timeZoneWithAbbreviation:#"UTC"];
NSTimeZone.defaultTimeZone= UTCzone;
and then re-create a calendar, and a date (from the same components):
NSCalendar *gregorianCalendar2 = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDate *date2 = [gregorianCalendar2 dateFromComponents:components];
NSLog(#"%#", date2); // puts out Fri Apr 10 02:00:00 1987 [dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"Europe/Berlin"]];
NSLog(#"%#", [dateFormatter stringFromDate:date2]); // puts out 1987-04-10 02:00:00.0 GMT+02:00
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
NSLog(#"%#", [dateFormatter stringFromDate:date2]); // puts out 1987-04-10 00:00:00.0 GMT
It was frustrating because I could find no mention in the Xcode documentation that NSDate is always created with the default timezone. Of course I tried using what the documentation says (https://developer.apple.com/library/archive/documentation/Cocoa/Conceptual/DatesAndTimes/Articles/dtTimeZones.html#//apple_ref/doc/uid/20000185-BBCBDGID),
[gregorianCalendar setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
that just didn't work... Can't figure out for the life of me why not. If anybody knows, please share.

I have a method that takes timezone name as a parameter and gives the current date's day component. But it gives different incorrect results

Suppose i have two parameters
Australia/Sydney (GMT+10) offset 36000 &
Asia/Kolkata (IST) offset 19800
as timezones, it gives different values for the day component of current day itself. I am not able to figure out what am i doing wrong.. :( A little clue will be appreciated
-(NSInteger)getDayWithTimeZoneName:(NSString *)timeZoneName{
// Instantiate a timezone
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:timeZoneName];
//Instantiate a date formatter
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setLocale:[NSLocale currentLocale]];
[df setTimeZone:timeZone];
[df setDateFormat:#"yyyy-MM-dd"];
NSString *dateStr = [df stringFromDate:[NSDate date]];
NSDate *date = [df dateFromString:dateStr];
// NSDateComponents *components = [[NSCalendar currentCalendar] components: NSCalendarUnitDay fromDate:date];
NSDateComponents *components = [[[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar]components:NSDayCalendarUnit fromDate:date];
NSInteger day = [components day];
NSLog(#"Date component for timeZone %# is %ld", timeZoneName,(long)day);
return day;
}
NSFormatter isn't designed to convert or calculate dates:
NSString *dateStr = [df stringFromDate:[NSDate date]];
dateStr is the date in Sydney (2016-05-16 0:00).
NSDate *date = [df dateFromString:dateStr];
date is GMT, 10 hours behind Sydney (2016-05-15 14:00).
Use NSCalendar to calculate dates:
NSCalendar *calendar = [NSCalendar currentCalendar];
calendar.timeZone = timeZone;
NSDateComponents *components = [calendar components:NSCalendarUnitDay fromDate:[NSDate date]];
NSInteger day = [components day];

Convert date-based NSString to NSDateComponents

Is it possible to parse out date components from an NSString-based date? For instance, if I have an NSDateFormatter with yyyy-MM-dd HH:mm:ss.SSS ZZZ, how can I get an NSDateComponents object from this string directly?
Specifically, I'd like to preserve timezones, and differentiate this NSDateComponents object with one created from the yyyy-MM-dd format.
Not so directly, but with a few steps:
NSDateFormatter *formatter = [NSDateFormatter new];
[formatter setDateFormat:#"yyyy-MM-dd HH:mm:ss.SSS ZZZ"];
NSString *dateString = #"2016-03-15 12:00:00.000 +0800";
NSDate *date = [formatter dateFromString:dateString];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [gregorian components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear | NSCalendarUnitTimeZone fromDate:date];
NSInteger day = [components day];
NSInteger month = [components month];
NSInteger year = [components year];
NSTimeZone *timeZone = [components timeZone];

Convert NSString to NSDate and timeZone?

Ive been racking my brains with no luck. Could someone please tell my how i would convert this string:
NSString *dateTimeStr =[[self.responseArray objectAtIndex:indexPath.row]objectForKey:#"date_time"];
2014-04-13T17:00:00+11:0
into a NSDate? and time format ?
how can i covert this date into time format ?
here is my code:
NSString *dateTimeStr =[[self.responseArray objectAtIndex:indexPath.row]objectForKey:#"date_time"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
[dateFormatter setDateFormat:#"yyyy-MM-ddHH:mm:ss"];
NSDate *date = [dateFormatter dateFromString:dateTimeStr];
NSLog(#"date %#", date);
NSTimeInterval seconds = [date timeIntervalSinceReferenceDate];
in console
NSLog(#"seconds==> %f", seconds);
i have time in miliseconds then how can i take out minutes/hours/ ?
NSString *dateString = #"2014-04-13T17:00:00+11:00";
NSDateFormatter *dateFormatter = [NSDateFormatter new];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssZ"];
NSDate *date = [dateFormatter dateFromString:dateString];
NSDateComponents *dateComponents = [[NSCalendar currentCalendar]
components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit
fromDate:date];
NSInteger year = [dateComponents year];
NSInteger month = [dateComponents month];
NSInteger day = [dateComponents day];

NSDate conversion setting weekday

I have an NSDate object *myDate.I can get the week day from this date and I want to set the weekday to an integer c and get the new date object in that week only.
I searched for it and I found the answer,here is the code..
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setDay:1];
NSDate *newDate = [[NSCalendar currentCalendar] dateByAddingComponents:comps toDate:[NSDate date] options:0];
NSLog(#"new date==%#",newDate);
This will return date of the next day.
NSDate *date = [NSDate date];
NSDateFormatter *formatter = [[[NSDateFormatter alloc] init] autorelease];
[formatter setDateFormat:#"MMM dd, yyy"];
date = [formatter dateFromString:string];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger units = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit;
NSDateComponents *components = [calendar components:units fromDate:date];
NSInteger day = [components day];
NSInteger weekday = [components weekday]; // if necessary