NSString to NSDate return null value - ios

Here i am getting current time and check whether its in am/pm format. If its not like that, i convert 24 hour time format into 12 hour time format and add AM/PM manually.
This is my code:
- (NSString *) getCurrentTime {
NSDate *today = [NSDate date];
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init];
[timeFormatter setDateFormat:#"hh:mm:ss a"];
NSString *currentTime = [timeFormatter stringFromDate:today];
currentTime = [self checkTimeFormat:currentTime];
return currentTime;
}
And
- (NSString *) checkTimeFormat:(NSString *) currentTime
{
NSArray *timeArray = [currentTime componentsSeparatedByString:#":"];
int intHour = [[timeArray objectAtIndex:0] intValue];
NSString *lastVal = [timeArray objectAtIndex:2];
if ([lastVal rangeOfString:#"M"].location == NSNotFound) {
if (intHour < 12)
lastVal = [NSString stringWithFormat:#"%# AM", [timeArray objectAtIndex:2]];
else
lastVal = [NSString stringWithFormat:#"%# PM", [timeArray objectAtIndex:2]];
}
if (intHour > 12)
intHour = intHour - 12;
currentTime = [NSString stringWithFormat:#"%d:%#:%#", intHour, [timeArray objectAtIndex:1], lastVal];
NSLog(#"Current Time ==>> %#", currentTime);
return currentTime;
}
Conversion of NSString into NSDate code below:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"hh:mm:ss a"];
NSDate *testDate = [dateFormatter dateFromString:getCurrentTime];
NSLog(#"testDate => %#", testDate);
If the Time is in 12 hour format (am/pm), testDate value is getting correctly.
If the Time is in 24 hour format, testDate value is null
What is the issue?
Thanks in Advance.

You can try:
NSDate *today = [NSDate date];
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init];
[timeFormatter setDateFormat:#"HH:mm:ss"];
NSString *currentTime24 = [timeFormatter stringFromDate:today];
[timeFormatter setDateFormat:#"hh:mm:ss a];
NSDate *currentTime12 = [timeFormatter dateWithString:currentTime24];
NSString *currentTime = [timeFormatter stringWithDate:currentTime12];

Related

get Timezone in format of UTC+5:30

I want to get timezone of user in String formatted like UTC+5:30
I have tried to get like this.
NSTimeZone *timeZone=[NSTimeZone localTimeZone];
NSLog(#"%# || %#",timeZone.abbreviation,timeZone.name);
This gives me this output.
(but not getting time as i want)
IST || Asia/Kolkata
Thanks
You can use NSDate Formatter to get the offset from UTC:
NSDateFormatter *dates = [[NSDateFormatter alloc]init];
[dates setDateFormat:#"Z"];
NSLog(#"%#", [dates stringFromDate:[NSDate date]]);
This will log: +0530 (+5:30)
If you want it in your specific format you can simply do:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"Z"];
NSString *offetString = [dateFormatter stringFromDate:[NSDate date]];
NSString *formattedString = [NSString stringWithFormat:#"UTC%#:%#",[offetString substringWithRange:NSMakeRange(0, 3)],[offetString substringWithRange:NSMakeRange([offetString length] - 2, 2)]];
NSDateFormatter *df = [[NSDateFormatter alloc]init];
df.timeZone = [NSTimeZone localTimeZone];
df.dateFormat = #"Z";
NSString *localTimeZoneOffset = [df stringFromDate:[NSDate date]];
NSLog(#"%#",localTimeZoneOffset);
You will get output like,
+0530 for UTC+5:30.
Update : (As asked in comment)
Try below code for your desired format,
NSDateFormatter *df = [[NSDateFormatter alloc]init];
df.timeZone = [NSTimeZone localTimeZone];
df.dateFormat = #"Z";
NSString *localTimeZoneOffset = [df stringFromDate:[NSDate date]];
NSLog(#"%#",localTimeZoneOffset);
NSString *one = [localTimeZoneOffset substringToIndex:1];
NSString *two = [localTimeZoneOffset substringWithRange:NSMakeRange(1, 2)];
NSString *three = [localTimeZoneOffset substringWithRange:NSMakeRange(3, 2)];
NSString *result = [NSString stringWithFormat:#"utc%#%#:%#",one,two,three];
NSLog(#"result : %#",result);

How to get NSTimeZone from string?

Assume that I have string like this from server #"2014-03-08T16:59+0000".
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *date = [self dateFromJSONString:#"2014-03-08T16:59+0000"];
NSDateComponents *dateComponents = [calendar components:(NSTimeZoneCalendarUnit) fromDate:date];
NSLog(#"TimeZone is %#", [[dateComponents timeZone] abbreviation]);
But the TimeZone is not base on the string, it based on the currentTimeZone of the device.
Is it possible to extract timeZone from string ?
You have to parse the offset from GMT from your string yourself.
Something like this, but you'll have to tweak for your slightly different format:
/**
This is assuming format yyyy-MM-dd'T'HH:mm:ssZZZZZ . ie the last 5 chars are timezone offset from gtm in the form (+|-)##:##
*/
-(NSTimeZone*)timezoneFromDateString:(NSString*)dateString {
NSTimeZone *timezone = nil;
NSString *timezoneComponent = [dateString substringFromIndex:19];
if(timezoneComponent.length == 6) {
NSArray *components = [[timezoneComponent substringFromIndex:1] componentsSeparatedByString:#":"];
NSInteger offset = [[timezoneComponent substringToIndex:1] isEqualToString:#"-"] ? -1 : 1;
if(components.count == 2) {
offset *= [components[0] integerValue] * 60*60 + [components[1] integerValue] *60;
timezone = [NSTimeZone timeZoneForSecondsFromGMT:offset];
}
}
return timezone;
}
-(NSArray*)convertToLocalDate:(NSString*)dateStr{
NSArray *convert;
NSString *time=#"";
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
[dateFormatter1 setDateFormat:#"MM/dd/yyyy hh:mm:ss a"];
NSDate *date = [dateFormatter1 dateFromString:dateStr];
//NSLog(#"date : %#",date);
NSTimeZone *currentTimeZone = [NSTimeZone localTimeZone];
NSTimeZone *utcTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"UTC"];
NSInteger currentGMTOffset = [currentTimeZone secondsFromGMTForDate:date];
NSInteger gmtOffset = [utcTimeZone secondsFromGMTForDate:date];
NSTimeInterval gmtInterval = currentGMTOffset - gmtOffset;
NSDate *destinationDate = [[NSDate alloc] initWithTimeInterval:gmtInterval sinceDate:date] ;
NSDateFormatter *dateFormatters = [[NSDateFormatter alloc] init];
[dateFormatters setDateFormat:#"dd.MM.yyyy"];
[dateFormatters setTimeZone:[NSTimeZone systemTimeZone]];
dateStr = [dateFormatters stringFromDate: destinationDate];
NSDateFormatter *dateFormatters1 = [[NSDateFormatter alloc] init];
[dateFormatters1 setDateFormat:#"hh:mm a"];
[dateFormatters1 setTimeZone:[NSTimeZone systemTimeZone]];
time = [dateFormatters1 stringFromDate: destinationDate];
convert = [[NSArray alloc ]initWithObjects:dateStr,time,nil];
return convert;
}
If you are sure that the string you need to parse is always formatted in that way, then regexes provide a simple way to do it:
NSString *str = #"2014-03-08T16:59+0000";
NSString *pattern = #"^.*T\\d{2}:\\d{2}";
NSString *timezone = [str stringByReplacingOccurrencesOfString: pattern
withString: #""
options: NSRegularExpressionSearch
range: NSMakeRange(0, str.length)];

How to get list of all UTC abbreviation in ios?

I have an app where i want to provide a list of UTC timezone so that the user could select destination time. I have all the country abbreviations in picker view. But i want UTC abbreviations.
Can anyone please suggest me how could i achieve this.
Thanks
You can use the knownTimeZoneNames property of NSTimeZone for all timezones.
[NSTimeZone knownTimeZoneNames]
Or you can use abbreviationDictionary for getting all abbreviations
[[NSTimeZone abbreviationDictionary] allKeys]
If you want time of these timezones, the use the below code
NSArray *abbs = [[NSTimeZone abbreviationDictionary] allKeys];
for (id eachObj in abbs) {
NSString *dateStr = [self dateFromTimeZoneAbbreviation:eachObj];
NSLog(#"%#",dateStr);
}
define the method as
-(NSString *)dateFromTimeZoneAbbreviation:(NSString *)abb {
NSString *dateStr;
NSTimeZone *currentTimeZone = [NSTimeZone localTimeZone];
NSTimeZone* timeZoneFromAbbreviation = [NSTimeZone timeZoneWithAbbreviation:abb];
NSInteger currentGMTOffset = [currentTimeZone secondsFromGMTForDate:[NSDate date]];
NSInteger gmtOffset = [timeZoneFromAbbreviation secondsFromGMTForDate:[NSDate date]];
NSTimeInterval gmtInterval = currentGMTOffset - gmtOffset;
NSDate *destinationDate = [[NSDate alloc] initWithTimeInterval:gmtInterval sinceDate:[NSDate date]] ;
NSDateFormatter *dateFormatters = [[NSDateFormatter alloc] init];
[dateFormatters setDateFormat:#"dd-MMM-yyyy hh:mm"];
/*[dateFormatters setDateStyle:NSDateFormatterShortStyle];
[dateFormatters setTimeStyle:NSDateFormatterShortStyle];
[dateFormatters setDoesRelativeDateFormatting:YES];*/
[dateFormatters setTimeZone:[NSTimeZone systemTimeZone]];
dateStr = [dateFormatters stringFromDate: destinationDate];
NSLog(#"DateString : %#, TimeZone : %#", dateStr , timeZoneFromAbbreviation.abbreviation);
return dateStr;
}
NSLog(#"%#", [NSTimeZone knownTimeZoneNames]);//viewDidLoad
for(id timezone in [NSTimeZone knownTimeZoneNames]){
NSLog(#"%#",[self getTimeZoneStringForAbbriviation:timezone]);
NSLog(#"%#", timezone);
}
-(NSString*)getTimeZoneStringForAbbriviation:(NSString*)abbr{
NSTimeZone *atimezone=[NSTimeZone timeZoneWithName:abbr];
int minutes = (atimezone.secondsFromGMT / 60) % 60;
int hours = atimezone.secondsFromGMT / 3600;
NSString *aStrOffset=[NSString stringWithFormat:#"%02d:%02d",hours, minutes];
return [NSString stringWithFormat:#"GMT%#",aStrOffset];
}

Custom DatePicker using UIPIckerView

I am new to ios development. I am making a custom datepicker using uipickerview. I have datesArray to be used as a data source for uipickerview.
I want to know how to show only Labels : today,tomorrow,Fri,Sat,Sun,Mon,Tues for current week and rest dates in format "EEE, LLL d".
I tried this code but it didn't work.
for(int i=0;i<22;i++)
{
NSDate *myDate = [NSDate dateWithTimeIntervalSinceNow:60 * 60 * 24 * i];
NSDate *now=[NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateFormat:#"EEE, LLL d"];
if(myDate==now)
{
NSString *myDateString=#"today";
[datesArray addObject:myDateString];
}
else
{
NSString *myDateString = [dateFormatter stringFromDate:myDate];
[datesArray addObject:myDateString];
}
}
Try this.Hope it helps
NSString *dateFromWS = #"2013-10-16";//im taking it as static you have to take string coming from webservice
for (int i = 0; i < 22; i++)
{
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
[dateFormatter1 setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter1 setDateFormat:#"yyyy-MM-dd"];
NSDate *myDate = [NSDate dateWithTimeIntervalSinceNow:60 * 60 * 24 * i];
NSDate *now = [dateFormatter1 dateFromString:dateFromWS];
NSDate *tomorrow = [NSDate dateWithTimeInterval:60 * 60 * 24 * 1 sinceDate:now];
//NSDate *dummy = [NSDate dateWithTimeInterval:60 * 60 * 24 * 1 sinceDate:now];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateFormat:#"EEE, LLL d"];
NSString *loopDate = [dateFormatter stringFromDate:myDate];
NSString *today = [dateFormatter stringFromDate:now];
NSString *tomorrowString = [dateFormatter stringFromDate:tomorrow];
if ([loopDate isEqualToString:today]) {
[datesArray addObject:#"today"];
} else if ([loopDate isEqualToString:tomorrowString]) {
[datesArray addObject:#"tomorrow"];
} else if ((i/7) < 1) {
[datesArray addObject:[loopDate substringToIndex:3]];
} else {
[datesArray addObject:loopDate];
}
}
if(myDate==now)
is comparing 2 pointers not 2 dates. You need to use the below code
if([myDate compare:now] == NSOrderedSame)
In addition to Simon's pointer issue, your dates will include the time info and so is never likely to be identical. May be the same day but not the same time. You need to find if the day matches. I do this by:
for(int i=0;i<22;i++)
{
NSDate *myDate = [NSDate dateWithTimeIntervalSinceNow:60 * 60 * 24 * i];
NSDate *myDateNoTime = nil;
// Note: Create sysCal as a property so it is not being repeatedly recreated here
[self.sysCal rangeOfUnit:NSDayCalendarUnit startDate:&myDateNoTime interval:nil forDate:myDate];
NSDate *now=[NSDate date];
NSDate *todayDateNoTime = nil;
[self.sysCal rangeOfUnit:NSDayCalendarUnit startDate:&todayDateNoTime interval:nil forDate:now];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setDateFormat:#"EEE, LLL d"];
if([myDateNoTime isEqualToDate:todayDateNoTime])
{
NSString *myDateString=#"today";
[datesArray addObject:myDateString];
}
else
{
NSString *myDateString = [dateFormatter stringFromDate:myDate];
[datesArray addObject:myDateString];
}
}
Given your server date requirement and, in my opinion, a better way of handling a picker, I would put this in the datasource method instead.
-(NSString *)pickerView:(UIPickerView *)pickerView titleForRow:(NSInteger)row forComponent:(NSInteger)component {
NSString *resultString = nil;
NSDate *myDate = [self dateForRow:row];
NSDate *myDateNoTime = nil;
// Note: Create sysCal as a property so it is not being repeatedly recreated here
[self.sysCal rangeOfUnit:NSDayCalendarUnit startDate:&myDateNoTime interval:nil forDate:myDate];
NSDate *now=[NSDate date];
NSDate *todayDateNoTime = nil;
[self.sysCal rangeOfUnit:NSDayCalendarUnit startDate:&todayDateNoTime interval:nil forDate:now];
if([myDateNoTime isEqualToDate:todayDateNoTime])
{
resultString = #"Today";
} else {
// Note: using property for date formatter so I am not repeatedly creating here
resultString = [self.dayFormatter stringFromDate:myDate];
}
return resultString;
}
To determine date for the row use:
-(NSDate *)dateFromRow:(NSInteger)inRow {
NSDateComponents *daysToAdd = [[NSDateComponents alloc] init];
[daysToAdd setCalendar:self.sysCal];
NSInteger daysCalc = (-1 * (inRow -2));
[daysToAdd setDay:daysCalc];
NSDate *resultDate = nil;
NSDate *calcDate = [self.sysCal dateByAddingComponents:daysToAdd
toDate:self.myServerDate
options:0];
[self.sysCal rangeOfUnit:NSDayCalendarUnit startDate:&resultDate interval:nil forDate:calcDate];
return resultDate;
}
I suppose you are already set with the way you are doing it but I think you would find this more flexible, no limit to 21 days before or after the server date. Aircode, excuse any typos or syntax errors.
Swift 4.0
for i in 0..<22 {
var myDate = Date(timeIntervalSinceNow: 60 * 60 * 24 * i)
var now = Date()
var dateFormatter = DateFormatter()
dateFormatter.dateStyle = .medium
dateFormatter.dateFormat = "EEE, LLL d"
if myDate == now {
var myDateString = "today"
datesArray.append(myDateString)
} else {
var myDateString: String = dateFormatter.string(from: myDate)
datesArray.append(myDateString)
}
}

Issue with NSDate from NSDateComponents

i have a string like 2013-03-05T07:37:26.853 and i want to get the Output : 2013-03-05 07:37:26. I want the final output in NSDate object. i am using below function to convert desire output. and it returning wrong time.
- (NSDate *) getDateFromCustomString:(NSString *) dateStr
{ NSArray *dateStrParts = [dateStr componentsSeparatedByString:#"T"];
NSString *datePart = [dateStrParts objectAtIndex:0];
NSString *timePart = [dateStrParts objectAtIndex:1];
NSArray *dateParts = [datePart componentsSeparatedByString:#"-"];
NSArray *timeParts = [timePart componentsSeparatedByString:#":"];
NSDateComponents *components = [[NSDateComponents alloc] init];
[components setHour:[[timeParts objectAtIndex:0] intValue]];
[components setMinute:[[timeParts objectAtIndex:1] intValue]];
[components setSecond:[[timeParts objectAtIndex:2] intValue]];
[components setYear:[[dateParts objectAtIndex:0] intValue]];
[components setMonth:[[dateParts objectAtIndex:1] intValue]];
[components setDay:[[dateParts objectAtIndex:2] intValue]];
NSCalendar *currentCalendar = [NSCalendar currentCalendar];
NSDate *date = [currentCalendar dateFromComponents:components];
NSLog(#"Date 1:%#",date); // Returns wrong time (2013-03-05 02:07:26)
/* i had tried the below.
NSDateFormatter * format = [[NSDateFormatter alloc] init];
[format setTimeZone:NSTimeZoneNameStyleStandard];
[format setDateFormat:#"yyyy-MM-dd hh:mm:ss"];
NSLog(#"Date 2:%#",[format stringFromDate:date]); // Returns correct date (2013-03-05 07:37:26)
NSDate *fDate = [format dateFromString:[format stringFromDate:date]];
DLog(#"Date 3:%#",fDate); // Returns wrong time (2013-03-05 02:07:26)
*/
[components release];
return date;
}
Plz suggest me if any idea.
What you're seeing here is a time zone issue. If you want to NSLog a correct looking date, we'll need to give the input string a GMT time zone:
Add this in your code and see what happens:
[components setTimeZone: [NSTimeZone timeZoneForSecondsFromGMT: 0]];
Try this,
NSString *departTimeDate = #"2013-03-05T07:37:26.853";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy'-'MM'-'dd'T'HH':'mm':'ss'.'SSS"];
NSDate *date = [dateFormatter dateFromString:departTimeDate];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSLog(#"Expected Result___ %#",[dateFormatter stringFromDate:date]); //2013-03-05 07:37:26
Try this : issue is Time zone.
+ (NSDate *) getDate:(NSString *) dateStr
{
NSArray *dateStrParts = [dateStr componentsSeparatedByString:#"T"];
NSString *datePart = [dateStrParts objectAtIndex:0];
NSString *timePart = [dateStrParts objectAtIndex:1];
NSString *t = [[timePart componentsSeparatedByString:#"."] objectAtIndex:0];
NSString *newDateStr = [NSString stringWithFormat:#"%# %#",datePart,t];
//2013-03-05 07:37:26
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[df setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [df dateFromString:newDateStr];
DLog(#"%#",date);
return date;
}

Resources