Background: I have dates stored in files.
What I would like to do: I would like to take the difference between two dates in seconds. I can't find any way to do it. My date format looks like that:
2015-23-02-12-23-43
Try this out:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-mm-dd-hh-mm-ss"];
NSDate *date = [dateFormatter dateFromString:string1];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *components = [calendar components:(NSCalendarUnitHour | NSCalendarUnitMinute) fromDate:date];
NSInteger hour = [components hour];
NSInteger minute = [components minute];
Try this:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"yyyy-MM-dd HH:mm:ss"];
NSDate *date = [dateFormatter dateFromString:EnterYourStringHere];
NSString *str = [dateFormatter stringFromDate:date];
If all you need is seconds then use
NSTimeInterval dateInterval = [date timeIntervalSince1970];
Then
NSString secondsString = [NSString stringWithFormat: #"%.0f", dateInterval];
EDIT:
If you have a file full of date strings that look like your example, 2015-23-02-12-23, then you could use code like this:
NSDateFormatter *myFormatter = [[NSDateFormatter alloc] init];
[myFormatter setDateFormat:#"yyyy-mm-dd-hh-mm-ss"];
//an example - you'll read from your file
NSString *aDateString = #"2015-23-02-12-23";
NSDate aDate = [myFormatter dateFromString: aDateString];
NSTimeInterval dateSeconds = [aDate timeIntervalSince1970];
That will give you dateSeconds as a double precision floating point number, which is the norm for numeric date calculations since it deals with fractions of seconds. You can then do numeric comparisons of date's time intervals.
Note that most UNIX systems use the numeric values returned by the timeIntervalSince1970 method, but Mac and iOS uses numeric date values returned by the method timeIntervalSinceReferenceDate. The two methods have different "epoch dates", or dates where they start counting from zero.
timeIntervalSince1970 uses midnight on Jan 1, 1970 (GMT)
timeIntervalSinceReferenceDate uses midnight on Jan 1, 2001 (GMT)
Which you use is up to you, just be sure to use the same method in all cases.
By the way, your date string format is horrible. having all those 2 digit numbers separated by dashes doesn't give the reader any way to tell apart month/day/hours/minutes/seconds. It's all a jumble. You'd be much better off using a standard date format.
In the US it's common to display dates in the form mm/dd/yyyyy (or yyyy/mm/dd, or even yyyy/dd/mm), and times as hh:mm:ss, so in "mm/dd/yyyyy hh:mm:ss" format you'd get:"09/02/2015 13:09:39" (I'm using human-readable date format strings for discussion, not those intended to set up a date formatter.)
Related
Can someone explain why NSDateFormatter return same strings from different dates:
NSDateFormatter *f = [NSDateFormatter new];
f.dateFormat = #"MM/dd/yyyy";
NSDate *dateYear0 = [[NSCalendar currentCalendar] dateWithEra:0 year:0 month:3 day:31 hour:0 minute:0 second:0 nanosecond:0];
NSDate *dateYear1 = [[NSCalendar currentCalendar] dateWithEra:0 year:1 month:3 day:31 hour:0 minute:0 second:0 nanosecond:0];
NSString *dateStrYear0 = [f stringFromDate:dateYear0];
NSString *dateStrYear1 = [f stringFromDate:dateYear1];
NSLog(#"dateYear0=%# \t\t dateStrYear0=%#",dateYear0,dateStrYear0);
NSLog(#"dateYear1=%# \t\t dateStrYear1=%#",dateYear1,dateStrYear1);
Both dateStr1 and dateStr2 have the same values:
NSLog result:
dateYear0=0001-03-30 21:57:56 +0000 dateStrYear0=03/31/0001
dateYear1=0000-03-30 21:57:56 +0000 dateStrYear1=03/31/0001
Its looks like 0 year affect this somehow?
Thanks
That's because year 0 doesn't exist in Gregorian Calendar. When dealing with AD dates minimum possible value for NSDate is "0001-01-01 00:00:00 +0000" therefore it uses "0001" as year whenever a lower value used than 1. You can check minimum NSDate value with distantPast class method.
Also if you want to use BC dates you should check Apple's guideline for more information.
I have this date object from Parse, "2015-07-24 20:36:38 +0000" and I would like to compare it to today's date to see how much time has passed since the date on the date object. Any ideas how to do this?
I have this method I use to get the hour and minute, but I'm stuck on how to use this to compare dates outside of the current day.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"hh:mm"];
NSString *formattedTime = [dateFormatter stringFromDate: date];
You can use an NSTimeInterval for this, the code is:
NSTimeInterval timeInterval = [date timeIntervalSinceNow];
with date being the date from parse as an NSDate, not NSString. and there should be no need to format it before comparing. Hope this helps
If you want this formatted as a string, in iOS 8 and later you can use NSDateComponentsFormatter:
NSDateComponentsFormatter *formatter = [[NSDateComponentsFormatter alloc] init];
formatter.allowedUnits = NSCalendarUnitMinute | NSCalendarUnitHour;
NSString *string = [formatter stringFromDate:date toDate:[NSDate date]];
In my iPhone / iPad app I am showing a UIDatePicker for time. It will display time in this format, 11:00 AM. When User clicks on the time row we expand the time row to display this datePicker row.
I have a time stamp in string "starts": "11:00", // time of day in ISO-8601 format
I need to show this on the picker wheel as selected time when it gets opened up. For this, first of all I get the date at 12 AM using https://stackoverflow.com/a/9040554/4082792. Then I convert the given time (11:00) to number of seconds and add it to the midnight time to get the current time. This time is in local timezone (as I specify the timezone while using NSDateFormatter). When I try to setDate to UIDatePicker with this date, It gives me incorrect time, even though the time is correct in the NSDate variable. For 11:00 AM, it gives me 6:40 while the local time is 4:30.
So, I have two questions :
1) Why is the time wrong on wheel.
2) How can I convert the NSDate from one timezone to another, I need to show it in the local time format.
Snippet :
NSString *strDate = #"11:00";
NSDate *date = [NSDate date];
NSCalendar *calendar = [NSCalendar autoupdatingCurrentCalendar];
NSUInteger preservedComponents = (NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit);
date = [calendar dateFromComponents:[calendar components:preservedComponents fromDate:date]];
///Start time
NSString *startTime = #"11:00";
NSArray *startTimeSeparatedByColon = [startTime componentsSeparatedByString:#":"]; /// From 22:10 to [22, 10];
NSInteger hourPartOfStart = startTimeSeparatedByColon[0] ? [startTimeSeparatedByColon[0] integerValue] : 0;
NSInteger minutePartOfStart = startTimeSeparatedByColon[1] ? [startTimeSeparatedByColon[1] integerValue] : 0;
NSTimeInterval totalTime = (hourPartOfStart*60*60+minutePartOfStart*60);
NSDate *finalDate = [NSDate dateWithTimeInterval:totalTime sinceDate:date];
NSDate *dt = [NSDate dateWithTimeInterval:[NSTimeZone localTimeZone].secondsFromGMT sinceDate:finalDate];
self.datePicker.date = dt;
By default, iOS converts date into the device's time zone.
But if you want to convert date into another time zone, here is the code for that:
NSTimeZone *currentDateTimeZone = [NSTimeZone timeZoneWithAbbreviation:#"EST"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setTimeZone:currentDateTimeZone];
You can get the date in "EST" time zone from this dateFormatter object.
Convert "EDT" TimeZone
NSString *format = #"EEEE dd-MMMM-yyyy HH:mm:ss z";
NSDateFormatter *date_EDTDateFormate = [[NSDateFormatter alloc] init];
date_EDTDateFormate setDateFormat:format];
date_EDTDateFormate setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"EDT"]];
NSString *stringEDT = [dateFormatter_EDT stringFromDate:date_System];
I have two strings coming from my server in which I store the time, and I need to compare the time interval between those two, in minutes, and if it's necessary, in hours. Should I convert to NSDate or use NSString?
The NSStrings look like:
NOW 14:22
LAST TIME 10:18
EDIT #1
Since everyone is saying me to use NSDate, i converted the data in my database to DATETIME, and now i can compare the two NSDate using the following code :
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setLocale:[[NSLocale alloc] initWithLocaleIdentifier:#"pt_BR"]];
[dateFormatter setDateFormat: #"yyyy-MM-dd HH:mm:ss"];
NSDate *currentDateTimeWithOffset = [NSDate dateWithTimeIntervalSinceNow:[[NSTimeZone localTimeZone] secondsFromGMT]];
NSString *strDate = [dateFormatter stringFromDate:currentDateTimeWithOffset];
NSDate * now = [dateFormatter dateFromString:strDate];
NSDate *date = [dateFormatter dateFromString:#"2013-04-09 12:10:18"];
NSLog(#"Difference %f",[now timeIntervalSinceDate:date]);
And the result is the following :
Difference 864.000000
NOW 2013-04-09 15:24:42 +0000
LAST DATE 2013-04-09 12:10:18
Is that correct? the Difference is in Seconds?
If the format gets more complex than the one you've shown, consider using NSDateFormatter. For the simple example:
NSArray *hoursMins = [timeString componentsSeparatedByString:#":"];
NSInteger timeInMins = [hoursMins[0] intValue] * 60 + [hoursMins[1] intValue];
Then subtract the two times in minutes. The date formatter approach looks like this:
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"HH:mm"];
NSDate *date = [df dateFromString:timeString];
You can get a difference in seconds between two dates using:
[date timerIntervalSinceDate:anotherDate];
NSDateFormatter is the "clean" way to do it. But if you are looking for quick and dirty, and those are the actual strings you are getting (that include the NOW and LAST TIME), I'd just use a specific NSRange to pull the hours and minutes out and compare them.
Make sure, though that you check the hours, and if the "now" hour is before the "last time" hour, you add 24 to the now to throw in the day rollover.
With only NSString, NSDateFormatter is used to get NSDate
NSDateFormatter *rfc3339DateFormatter = [[NSDateFormatter alloc] init];
NSLocale *enUSPOSIXLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[rfc3339DateFormatter setLocale:enUSPOSIXLocale];
[rfc3339DateFormatter setDateFormat:#"yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'"];
[rfc3339DateFormatter setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
// Convert the RFC 3339 date time string to an NSDate.
NSDate *date = [rfc3339DateFormatter dateFromString:rfc3339DateTimeString];
If you had separate values for hours, minutes and seconds you could use NSCalendar
NSDateComponents *comps = [[NSDateComponents alloc] init];
[comps setYear:1965];
[comps setMonth:1];
[comps setDay:6];
[comps setHour:14];
[comps setMinute:10];
[comps setSecond:0];
NSDate *date = [gregorian dateFromComponents:comps];
[comps release];
And a perfect solution would be to use timestamps instead of NSString. Not only it's easy to convert timestamps to NSDate (NSDate +dateWithTimeIntervalSinceReferenceDate)and then to NSString when needed, but you can also get the time difference by subtraction.
And with two NSDate objects the time difference is calculated with NSDate -timeIntervalSinceDate.
How to convert an NSDate into Unix timestamp? I've read many posts which do the reverse. But I'm not finding anything related to my question.
I believe this is the NSDate's selector you're looking for:
- (NSTimeInterval)timeIntervalSince1970
A Unix timestamp is the number of seconds since 00:00:00 UTC January 1, 1970. It's represented by the type time_t, which is usually a signed 32-bit integer type (long or int).
iOS provides -(NSTimeInterval)timeIntervalSince1970 for NSDate objects which returns the number of seconds since 00:00:00 GMT January 1, 1970. NSTimeInterval is a double floating point type so you get the seconds and fractions of a second.
Since they both have the same reference (midnight 1Jan1970 UTC) and are both in seconds the conversion is easy, convert the NSTimeInterval to a time_t, rounding or truncating depending on your needs:
time_t unixTime = (time_t) [[NSDate date] timeIntervalSince1970];
You can create a unix timestamp date from a date this way:
NSTimeInterval timestamp = [[NSDate date] timeIntervalSince1970];
- (void)GetCurrentTimeStamp
{
NSDateFormatter *objDateformat = [[NSDateFormatter alloc] init];
[objDateformat setDateFormat:#"yyyy-MM-dd"];
NSString *strTime = [objDateformat stringFromDate:[NSDate date]];
NSString *strUTCTime = [self GetUTCDateTimeFromLocalTime:strTime];//You can pass your date but be carefull about your date format of NSDateFormatter.
NSDate *objUTCDate = [objDateformat dateFromString:strUTCTime];
long long milliseconds = (long long)([objUTCDate timeIntervalSince1970] * 1000.0);
NSString *strTimeStamp = [Nsstring stringwithformat:#"%lld",milliseconds];
NSLog(#"The Timestamp is = %#",strTimestamp);
}
- (NSString *) GetUTCDateTimeFromLocalTime:(NSString *)IN_strLocalTime
{
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd"];
NSDate *objDate = [dateFormatter dateFromString:IN_strLocalTime];
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithAbbreviation:#"UTC"]];
NSString *strDateTime = [dateFormatter stringFromDate:objDate];
return strDateTime;
}
NOTE :- The Timestamp must be in UTC Zone, So I convert our local Time to UTC Time.
Swift
Updated for Swift 3
// current date and time
let someDate = Date()
// time interval since 1970
let myTimeStamp = someDate.timeIntervalSince1970
Notes
timeIntervalSince1970 returns TimeInterval, which is a typealias for Double.
If you wanted to go the other way you could do the following:
let myDate = Date(timeIntervalSince1970: myTimeStamp)
If you want to store these time in a database or send it over the server...best is to use Unix timestamps. Here's a little snippet to get that:
+ (NSTimeInterval)getUTCFormateDate{
NSDateComponents *comps = [[NSCalendar currentCalendar]
components:NSDayCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit
fromDate:[NSDate date]];
[comps setHour:0];
[comps setMinute:0];
[comps setSecond:[[NSTimeZone systemTimeZone] secondsFromGMT]];
return [[[NSCalendar currentCalendar] dateFromComponents:comps] timeIntervalSince1970];
}
My preferred way is simply:
NSDate.date.timeIntervalSince1970;
As per #kexik's suggestion using the UNIX time function as below :
time_t result = time(NULL);
NSLog([NSString stringWithFormat:#"The current Unix epoch time is %d",(int)result]);
.As per my experience - don't use timeIntervalSince1970 , it gives epoch timestamp - number of seconds you are behind GMT.
There used to be a bug with [[NSDate date]timeIntervalSince1970] , it used to add/subtract time based on the timezone of the phone but it seems to be resolved now.
[NSString stringWithFormat: #"first unixtime is %ld",message,(long)[[NSDate date] timeIntervalSince1970]];
[NSString stringWithFormat: #"second unixtime is %ld",message,[[NSDate date] timeIntervalSince1970]];
[NSString stringWithFormat: #"third unixtime is %.0f",message,[[NSDate date] timeIntervalSince1970]];
first unixtime 1532278070
second unixtime 1532278070.461380
third unixtime 1532278070
If you need time stamp as a string.
time_t result = time(NULL);
NSString *timeStampString = [#(result) stringValue];