NSDate is converting really strangely - iphone

I have a time: 7:46 am
I want to convert this to NSDate. I do this:
NSDateFormatter *f = [NSDateFormatter new];
[f setDateFormat:#"h:mm a"];
NSDate *sr = [f dateFromString:#"7:46 am"];
I NSLog sr and I get 1969-12-31 22:46:00 +0000
Those times are not the same. Why is this so messed up?

No. Its not strange. NSDateConverter & NSDate are just doing their intended job here.
You are trying to convert "7:46 am" into a date. It contains only the time. No date is specified in the string. NSDate will default to "1970-01-01"(Unix epoch) if no date is specified. So after you convert the string you will get the date "1970-01-01 7:46 am". When you trying to display this in NSLog, if will display the date after adjusting the timeZone offset value. I guess you live in Japan or Korea. Probably the offset of your region is +09:00. So it diaplays the date subtracting the offset. So you are seeing "1969-12-31 22:46:00 +0000" in the log.
You can use the following method to set that time to a particular date, may be today.
NSString *timeStr = #"7:46 am";
NSDateFormatter *f = [NSDateFormatter new];
[f setDateFormat:#"yyyy-MM-dd"];
NSString *dateStr = [f stringFromDate:[NSDate date]]; // dateStr = 2011-06-10
dateStr = [dateStr stringByAppendingFormat:#" %#", timeStr]; // dateStr = 2011-06-10 7:46 am
[f setDateFormat:#"yyyy-MM-dd h:mm a"];
NSDate *sr = [f dateFromString:dateStr];

You aren't providing the day or the timezone... assuming you want to express "today at 7:42am", you can use this code:
NSDate *currentDate = [NSDate date];
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setHour:7];
[comps setMinute:42];
NSDate *myDate = [calendar dateByAddingComponents:comps toDate:currentDate options:0];
[comps release];
The NSLog of myDate should give you the expected output now (assuming you wanted today#7:46am).

Since you are only specifying the time that you want the NSDate to refer to, and not the date, the formatter is using the default date (which seems to be very close to the UNIX epoch). Like Julio said, you should specify the current date as well, if you want the NSDate to refer to the time on that specific date.

Related

NSDate wrong output when add day to NSDate

NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSString *dateString = [dateFormatter stringFromDate:[NSDate date]];
NSLog(#"%#",dateString);
// Retrieve NSDate instance from stringified date presentation
NSDate *dateFromString = [dateFormatter dateFromString:dateString];
// Create and initialize date component instance
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setDay:2];
// Retrieve date with increased days count
NSDate *newDate = [[NSCalendar currentCalendar]
dateByAddingComponents:dateComponents
toDate:dateFromString options:0];
NSLog(#"Original date: %#", [dateFormatter stringFromDate:dateFromString]);
NSLog(#"New date: %#", [dateFormatter stringFromDate:newDate]);
OutPut
2013-05-17
Original date: 2013-05-17
New date: 1412647-09-06
I add 2 day to that. The new date should be "2013-05-19?. Can anyone tell me what I wrong? Thank in advance.
I assume that you forgot to initialize the day variable. If you add
NSUInteger day = 2;
then your code produces the expected result in my test program.
The init methode of NSDateComponents does not initializes the components. Thus, e.g., year is undefined. Form Apple's documentation:
An instance of NSDateComponents is not responsible for answering questions about a date beyond the
information with which it was initialized. For example, if you initialize one with May 6, 2004,
its weekday is NSUndefinedDateComponent

why date gets changed when i try to change formate? [duplicate]

This question already has an answer here:
NSDateFormatter not giving me correct
(1 answer)
Closed 9 years ago.
this is the code that i am using for changing date formate
NSLog(#"newBirthDates%#",_newwBirthDates);
NSDateFormatter *Form = [[NSDateFormatter alloc] init];
[Form setDateFormat:#"MM/dd"];
NSDate *date1 =[NSDate date];
NSString *string =[Form stringFromDate:date1];
NSLog(#"string%#",string);
NSDate *todaydate =[Form dateFromString:string];
NSLog(#"todaydate%#",todaydate);
this is what i get as output
newBirthDates(
"05/22",
"07/11",
"10/07",
"02/20"
)
newBirthDates(
"05/22",
"07/11",
"10/07",
"02/20"
)
string03/18
todaydate1970-03-17 18:30:00 +0000
now my question is why 3/18 become 03/17?? why one day get decreases
The answer is simple - time zones.
Take a close look at what NSLog prints out
1970-03-17 18:30:00 +0000
By default, a NSDateFormatter is set to your local timezone. That means, if your time zone is +5:30 giving it a date "1970/18/3" results in 1970-03-18 00:00:00 +0530.
However, NSLog always prints dates in GMT (zero) time zone, adding/substracting the time zone difference (5 hours and 30 minutes).
Basically, there is nothing to fix, you just have to understand how NSLog works if you want to use it to check NSDate values.
Your Log is showing as per string value, eliminating all important timezone differences.
Log of NSDate shows you the time from GMT.
And both the values are correct.
The sole primitive method of NSDate, timeIntervalSinceReferenceDate,
provides the basis for all the other methods in the NSDate interface.
This method returns a time value relative to an absolute reference
dateā€”the first instant of 1 January 2001, GMT.
You must read NSDate Documentation.
for getting correct date you can use this one,
NSDateFormatter *Form = [[NSDateFormatter alloc] init];
[Form setDateFormat:#"MM/dd"];
[Form setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDate *date1 =[NSDate date];
NSString *string =[Form stringFromDate:date1];
NSLog(#"string%#",string);
NSDate *todaydate =[Form dateFromString:string];
NSLog(#"todaydate%#",todaydate);
above code will give the correct date.
The Main thing is TimeZone : [Form setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
This is the Correct Code :
NSDateFormatter *Form = [[NSDateFormatter alloc] init];
[Form setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[Form setDateFormat:#"MM/dd"];
NSDate *date =[NSDate date];
NSString *string =[Form stringFromDate:date];
NSDate *todaydate = [Form dateFromString:string];
NSLog(#"todaydate %#",todaydate);

objective-c - NSDateFormatter returns wrong date

I have this piece of code:
// Convert string to date object
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"MMMM d, YYYY"];
NSDate *formatDate = [dateFormat dateFromString:self.date];
NSLog(#"1-%#", self.date);
NSLog(#"2-%#", formatDate);
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSDayCalendarUnit | NSMonthCalendarUnit | NSYearCalendarUnit fromDate:formatDate];
NSString *dateCal = [NSString stringWithFormat:#"%d/%d/%d", [components day], [components month], [components year]];
NSLog(#"3-%#", dateCal);
milage.date = dateCal;
The first NSLog returns:
1-March 23, 2012
The second:
2-2011-12-25 00:00:00 +0000
The third:
3-25/12/2011
Why does the date change when getting the date from the string and formatting it? I'm expecting the third NSLog (or dateCal) to equal 23/3/2012. I live in the UK so its not to do with the timezone..
Thanks,
Jack
Needed to use lower case 'y' in the line:
[dateFormat setDateFormat:#"MMMM d, YYYY"];
Have you used the setLocale method?
Also, from the technical Q&A:
If you're working with user-visible dates, you should avoid setting a date format string because it's very hard to predict how your format string will be expressed in all possible user configurations. Rather, you should try and limit yourself to setting date and time styles (via -[NSDateFormatter setDateStyle:] and -[NSDateFormatter setTimeStyle:]).
Use [dateFormat setDateStyle:NSDateFormatterLongStyle];
Instead of [dateFormat setDateFormat:#"MMMM d, YYYY"];
Will give you reason as soon as I find it.

How to compare just dates not the time?

How can I compare the dates only, not the time. I am using
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
NSString *tempDate = #"2-2-2012"; //Dynamic Date
NSDate *dateString = [dateFormatter dateFromString:tempDate];
NSLog(#"%#",dateString);
It logs this: 2012-02-01 18:30:00 +0000
NSDate *now = [NSDate date];//Current Date
NSLog(#"%#",now);
It logs this: 2011-04-04 14:49:45 +0000
I want to compare Dynamic date and current date, I don't need time. I may not using the correct NSDateFormatter. Can anyone of you tell me how to do this? If I am not clear, please let me know.
Suppose I have to strings
date1 = 3-2-2011;
date2 = 4-5-2020;
I want to convert them in date, only after that I can compare them. Its not happening from my date Formatter. Please have a look.
Thanks!
Simplest way is to compare date by converting it into string.
Sample Code is as shown below:
//Current Date
NSDate *date = [NSDate date];
NSDateFormatter *formatter = nil;
formatter=[[NSDateFormatter alloc] init];
[formatter setDateFormat:#"yyyy-MM-dd"];
NSString *dateString = [formatter stringFromDate:date];
[formatter release];
//Other Date say date2 is of type NSDate again
NSString *date2String = [formatter stringFromDate:date2];
//Comparison of Two dates by its conversion into string as below
if([date2String isEqualToString:dateString])
{
//Your logic if dates are Equal
}
else if(![date2String isEqualToString:dateString])
{
//Your Logic if dates are Different
}
EDIT:
Checkout this link.
Comparing dates
http://www.iphonedevsdk.com/forum/iphone-sdk-development/64625-how-compare-2-dates.html
Hope This Helps You. :)
Use NSCalendar and NSDateComponents to get a date components object. Then you can look at only those parts of the date that you care about.
If you're just trying to determine whether two dates are the same, regardless of time, one way to go is to use NSDate's -timeIntervalSinceDate: method. If the time interval returned is less than 86,400 seconds (i.e. 24 hours * 60 minutes * 60 seconds) then you can feel fairly sure that it's the same day. Changes related to such things as daylight savings time and leap seconds introduce some possibility of error... if that's a problem, go with NSDateComponents.
NSDate *date = [NSDate date];
NSDateFormatter *formatter = nil;
formatter=[[NSDateFormatter alloc] init];
[formatter setDateStyle:NSDateFormatterMediumStyle];
[formatter setTimeStyle:NSDateFormatterNoStyle];
[formatter setLocale:[NSLocale autoupdatingCurrentLocale]];
NSString *dateString = [formatter stringFromDate:date];
[formatter release];

Retrieving current local time on iPhone?

I'm looking to get the current hour and minute on a user's iPhone for display in an app that doesn't show the status bar. Is there a simple way to do this?
// get current date/time
NSDate *today = [NSDate date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// display in 12HR/24HR (i.e. 11:25PM or 23:25) format according to User Settings
[dateFormatter setTimeStyle:NSDateFormatterShortStyle];
NSString *currentTime = [dateFormatter stringFromDate:today];
[dateFormatter release];
NSLog(#"User's current time in their preference format:%#",currentTime);
-(void)currentTime
{
//Get current time
NSDate* now = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *dateComponents = [gregorian components:(NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond) fromDate:now];
NSInteger hour = [dateComponents hour];
NSString *am_OR_pm=#"AM";
if (hour>12)
{
hour=hour%12;
am_OR_pm = #"PM";
}
NSInteger minute = [dateComponents minute];
NSInteger second = [dateComponents second];
[gregorian release];
NSLog(#"Current Time %#",[NSString stringWithFormat:#"%02ld:%02ld:%02ld %#", (long)hour, (long)minute, (long)second,am_OR_pm]);
}
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeZone:[NSTimeZone localTimeZone]];
NSString *currentTime = [dateFormatter stringFromDate:[NSDate date]]
[dateFormatter release]; dateFormatter = nil;
I think you should try this. The timeZone is important.
See this similar question for an answer. You will have to change it to your date format.
[[NSDate date] timeIntervalSince1970];
if you are looking to calculate time intervals, you are better off using CACurrentMediaTime
double currentTime = CACurrentMediaTime();
A shorter approach
NSDate * now = [NSDate date];
timeLabel.text = [NSDateFormatter localizedStringFromDate:now
dateStyle:NSDateFormatterNoStyle
timeStyle:NSDateFormatterShortStyle];
CFAbsoluteTimeGetCurrent()
Absolute time is measured in seconds relative to the absolute reference date of Jan 1 2001 00:00:00 GMT. A positive value represents a date after the reference date, a negative value represents a date before it. For example, the absolute time -32940326 is equivalent to December 16th, 1999 at 17:54:34. Repeated calls to this function do not guarantee monotonically increasing results. The system time may decrease due to synchronization with external time references or due to an explicit user change of the clock.