Date Formatting is Weird - ios

I have a date string that looks like this:
1391640679661
When I use this code:
NSString *seconds = #"1391640679661";
NSDate *date = [NSDate dateWithTimeIntervalSince1970:[seconds doubleValue]];
I end up with this:
46069-05-03 07:27:41 +0000
So what's happening here? Is this a particular date format that I'm not accounting for? Or am I doing something else wrong?

Apple's own api will do all the hard work for you to format components as per your need.
If you want to get individual components as well you can apply below approach.
NSTimeInterval theTimeInterval = 1391640679661;
// Get the system calendar
NSCalendar *sysCalendar = [NSCalendar currentCalendar];
// Create the NSDates
NSDate *date1 = [[NSDate alloc] init];
NSDate *date2 = [[NSDate alloc] initWithTimeInterval:theTimeInterval sinceDate:date1];
// Get conversion to months, days, hours, minutes
unsigned int unitFlags = NSHourCalendarUnit | NSMinuteCalendarUnit | NSDayCalendarUnit | NSMonthCalendarUnit;
NSDateComponents *conversionInfo = [sysCalendar components:unitFlags fromDate:date1 toDate:date2 options:0];
NSLog(#"Conversion: %dmin %dhours %ddays %dmoths",[conversionInfo minute], [conversionInfo hour], [conversionInfo day], [conversionInfo month]);

To convert a timestamp string into NSDate, you need to divid the timestamp double value to 1000, and then call dateWithTimeIntervalSince1970:
NSString *timestamp = #"1391640679661";
double seconds = [timestamp doubleValue]/1000.0;
NSDate *date = [NSDate dateWithTimeIntervalSince1970:seconds];
The result is:
2014-02-05 22:51:19 +0000

Related

NSDate dateWithTimeIntervalSince1970 adding an extra day on

I have a method that updates a label and acts as a stop watch. It works fine accept when I format the string to factor days in it adds an additional day on. For example. If the stopwatch is started ten minutes ago the label will display:
01:00:10:00
it should just display 00:00:10:00
- (void)updateTimer
{
NSDate *currentDate = [NSDate date];
NSDate *dateValue=[[NSUserDefaults standardUserDefaults] objectForKey:#"pickStart"];
NSTimeInterval timeInterval = [currentDate timeIntervalSinceDate:dateValue];
NSDate *timerDate = [NSDate dateWithTimeIntervalSince1970:timeInterval];
// Create a date formatter
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd:HH:mm:ss"];
[dateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0.0]];
// Format the elapsed time and set it to the label
NSString *timeString = [dateFormatter stringFromDate:timerDate];
self.stopWatchLabel.text = timeString;
}
Any help would be greatly appreciated.
What you are doing isn't appropriate. Your goal seems to be to convert timeInterval into days, hours, minutes, and seconds. Your use of timerDate and NSDateFormatter are not the proper way to achieve that goal.
timeInterval is not an offset from January 1, 1970 and timeInterval doesn't represent a date.
What you should do is get the difference between currentDate and dateValue as a set of NSDateComponents.
- (void)updateTimer {
NSDate *currentDate = [NSDate date];
NSDate *dateValue = [[NSUserDefaults standardUserDefaults] objectForKey:#"pickStart"];
unsigned int unitFlags = NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *comps = [[NSCalendar currentCalendar] components:unitFlags fromDate:dateValue toDate:currentDate options:0];
int days = [comps day];
int hours = [comps hours];
int minutes = [comps minutes];
int seconds = [comps seconds];
NSString *timeString = [NSString stringWithFormat:#"%d:%02d:%02d:%02d", days, hours, minutes, seconds];
self.stopWatchLabel.text = timeString;
}
There is no "additional day", the "date" you produce is a point in time after the 1st Jan 1970, so if your format includes the day you get at least a 1...
Just stick with the NSTimeInterval value and use NSDateComponentsFormatter - which also formats time intervals despite the name - or just do the math yourself to get the seconds, minutes, etc. and format those.
HTH

How to get days in a week from today in objective c

I am trying to get the days of a week in reference to their date.
Ex.: 14th October is a Wednesday.
I am creating a collection view cell and displaying the date as follows.
In the 14th cell it would display Wednesday, but how to get the next day as Thursday, then Friday...and so on.
I have got todays date and which day it is as follows,
day = [components day];
week = [components month];
year = [components year];
weekday = [components weekday];
NSString *string = [NSString stringWithFormat:#"%ld.%ld.%ld", (long)day, (long)week, (long)year];
NSLog(#"%#",string);
NSDate *todayDate = [NSDate date]; // get today date
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"EEEE"];
NSString *convertedDateString = [dateFormatter stringFromDate:todayDate];// here convert date in
NSLog(#"Today formatted date is %#",convertedDateString);
And i have found this method online, which returns the days in string when you pass the integer, but i am having trouble in this too, not understanding which integer to pass every time so I get different strings.
static inline NSString *stringFromWeekday(int weekday){
static NSString *strings[] = {
#"Sunday",
#"Monday",
#"Tuesday",
#"Wednesday",
#"Thursday",
#"Friday",
#"Saturday",
};
return strings[weekday];
}
You already got everything in place. You should be getting the correct day name in the convertedDateString string. You just have to add 24 hours to your todayDate object and use the dateformatter again to get the next day.
NSDate *todayDate = [NSDate date]; // get today date
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"EEEE"];
NSString *convertedDateString = [dateFormatter stringFromDate:todayDate];// here convert date in
You can get the next day like this.
NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:(NSDayCalendarUnit | NSMonthCalenderUnit | NSYearCalenderUnit | NSWeekdayCalendarUnit) fromDate:today];
[dateComponents setDay:dateComponents.day+1];
NSDate *nextDay = [dateComponents date];
// Get the day by following same approach in the top
You will get days in a week from today using below code.
NSDate *today = [NSDate date];
NSCalendar *gregorian = [[NSCalendar alloc]
initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *weekdayComponents =
[gregorian components:(NSDayCalendarUnit | NSWeekdayCalendarUnit) fromDate:today];
NSInteger day = [weekdayComponents day];
NSInteger weekday = [weekdayComponents weekday];

iOS) value of timeIntervalSince70 is fixed when i approach at the level of second

I want to update label that shows time left between 2 nsdates everysecond.
my code is below :
NSDate *nowDate = [NSDate date];
double diff = [campaignDate timeIntervalSince1970] - [nowDate timeIntervalSince1970];
int diff_day = diff/60/60/24 - 1;
int diff_hour = ((int)diff/60/60)%24;
int diff_min = ((int)diff/60)%60;
int diff_sec = ((int)diff/60/60)%60;
When i logged diff_sec , it always shows me 49
day,hour and min value is printed in working order
why does that diff_sec make a problem? is there any solution ?
I think you should use NSDateComponents to get the number of days/hours/minutes/seconds between two days.
Then you can get the remaing time like this:
NSDate *fromDate = [NSDate date];
NSDate *toDate = [NSDate dateWithTimeIntervalSinceNow:12345];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *difference = [calendar components:NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond fromDate:fromDate toDate:toDate options:0];
NSLog(#"Event in %# days, %#:%#:%#", #(difference.day), #(difference.hour), #(difference.minute), #(difference.second));
Use NSCalendar
NSDate *dateA;
NSDate *dateB;
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit
fromDate:dateA
toDate:dateB
options:0];
NSLog(#"Difference in date components: %i/%i/%i", components.day, components.month, components.year);
The error is in calculating diff_sec, the divisions by 60 are incorrect because diff is already in seconds.
Incorrect code:
int diff_sec = ((int)diff/60/60)%60;
Correct code
int diff_sec = ((int)diff)%60;

NSCalendarUnitSecond returning zero

I have this method returning a string. But the seconds value is always zero. What am I doing wrong?
-(NSString*)secondsBetweenDate:(NSDate*)startDate andDate:(NSDate*)endDate {
NSCalendar *calendar = [NSCalendar currentCalendar];
unsigned int unitFlags = NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
NSDateComponents *difference = [calendar components:unitFlags fromDate:startDate toDate:endDate options:0];
long hour = [difference hour];
long min = [difference minute];
long sec = [difference second];
NSLog(#"Hour: %ld Min: %ld Sec: %ld", hour, min, sec);
return [NSString stringWithFormat:#"%02ld:%02ld:%02ld", hour, min, sec];
}
Why don't you use the default NSDate difference calculations?
Returns an NSTimeInterval which is in seconds:
typedef double NSTimeInterval; Description Used to specify a time
interval, in seconds.
Operation is:
[aDate timeIntervalSinceDate:anotherDate];
Your code is correct. If you use the dates that actually differ in their seconds value it yields the expected results.
[self secondsBetweenDate:[NSDate dateWithTimeIntervalSinceNow:-99999] andDate:[NSDate date]];
logs:
Hour: 27 Min: 46 Sec: 39
And 99999 Seconds is 27*60*60 +46*60 +39
In our discussion in the comments we discovered that you had more of a conceptional problem. If you need to show a countdown or stopwatch type string you have to use the current time as one of the date parameters.
So if you want to show the time that has passed since a specific date (like a stop watch) you use:
NSDate *now = [NSDate date];
string = [self secondsBetweenDate:yourStartDate andDate:now];
If you want to show the time until a specific date (like a countdown) you use:
NSDate *now = [NSDate date];
string = [self secondsBetweenDate:now andDate:yourEndDate];
Btw: If you are only targetting iOS 8 and later you can use NSDateComponentsFormatter to format your date
NSDateComponentsFormatter *df = [[NSDateComponentsFormatter alloc] init];
df.unitsStyle = NSDateComponentsFormatterUnitsStylePositional;
df.allowedUnits = NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
NSString *dateString = [df stringFromDate:startDate toDate:[NSDate date]];

issue with NSDate I am removing year but takes 0001 as year

Below is my code, and I will explain things in it
NSDateFormatter *formater = [[NSDateFormatter alloc] init] ;
[formater setDateFormat:#"MM-dd"];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger desiredComponents = (NSDayCalendarUnit | NSMonthCalendarUnit);
NSDateComponents *firstComponents = [calendar
components:desiredComponents fromDate:fDate];
NSDateComponents *secondComponents = [calendar
components:desiredComponents fromDate:eDate];
NSDateComponents *thirdComponents = [calendar
components:desiredComponents fromDate:mdate];
NSDate *from = [calendar dateFromComponents:firstComponents];
NSDate *end = [calendar dateFromComponents:secondComponents];
NSDate *middle = [calendar dateFromComponents:thirdComponents];
NSString * froms = [formater stringFromDate:from];
NSLog(#"sringfroms:%#",froms);
NSLog(#"datefrom:%#",from);
NSString * ends = [formater stringFromDate:from];
NSLog(#"sringends:%#",ends);
NSLog(#"dateend:%#",end);
NSString * middles = [formater stringFromDate:from];
NSLog(#"sringmiddles:%#",middles);
NSLog(#"datemiddle:%#",middle);
And this is what gets printed.
sringfroms:06-30
datefrom:0001-06-29 18:06:32 +0000
sringends:06-30
dateend:0001-08-02 18:06:32 +0000
sringmiddles:06-30
datemiddle:0001-07-14 18:06:32 +0000
You can see that i am removing year from date which get printed in string but when i make date it takes 0001 automatically. I am using kal calendar and i want to mark for month and day only so it should get marked for every year
if (([middle compare:from] == NSOrderedDescending)
&&([middle compare:end] == NSOrderedAscending)) {
[holidays addObject:[Holiday holidayNamed:naMMe
birthDate:bDate iDs:aIDDS date:middle]];
}
Any help will be highly appreciated
Its OKAY, since you are not using NSYearCalendarUnit in your following code
NSInteger desiredComponents = (NSDayCalendarUnit | NSMonthCalendarUnit);
so NSDate is assuming 0001 as default year, if you add NSYearCalendarUnit in the above code it will give correct year, like below
NSInteger desiredComponents = (NSDayCalendarUnit
| NSMonthCalendarUnit | NSYearCalendarUnit);
Well,if you are not mensioned any component then it'l take always
first value(01,0001 etc) that is default nature of NSCalendar,for resolving your
problem you need to convert that date to your date formatt.

Resources