I have date string: Monday, October 11, 2010. How can I create a NSDate object out of it and then get different components like day, month, date, year from it. Please note that format/locale of this string may change at runtime.
Use an NSDateFormatter to create the NSDate, then you can access its components through NSDate properties (you'll need to adjust the format string below):
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setDateFormat:#"EEE, dd MMM yyyy HH:mm:ss ZZZ"];
if(NSDate *myDate = [df dateFromString:string]) {
//Do something with myDate
}
another possibility:
NSCalendar *calendar = [NSCalendar currentCalendar];
NSInteger units = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
NSDateComponents *components = [calendar components:units fromDate:date];
NSInteger year = [components year];
...
Related
I want to change hour in NSDate. I did something like this:
NSDate *final = [gregorian dateBySettingUnit:NSCalendarUnitHour value:hour.intValue ofDate:self.dateForNewEvent options:NSCalendarMatchStrictly];
where self.dateForNewEvent = 2018-07-09 07:24:13 +0000
and hour.intValue = 5 and i expect date = 2018-07-09 05:00:00 + 0000 but i got 2018-07-10 03:00:00 UTC. How should I do it to get expected date ?
To change the hours of a specific NSDate, you need to manipulate it via NSDateComponents. Please try below code for the same:
NSDate *now = [NSDate date]; // YOUR DATE INSTANCE
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier: NSCalendarIdentifierGregorian];
NSDateComponents *components = [calendar components:NSCalendarUnitYear|NSCalendarUnitMonth|NSCalendarUnitDay|NSCalendarUnitHour|NSCalendarUnitMinute|NSCalendarUnitSecond fromDate:now];
[components setHour:5];
NSDate *today5am = [calendar dateFromComponents:components];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateStyle:NSDateFormatterMediumStyle];
[dateFormatter setTimeStyle:NSDateFormatterMediumStyle];
NSLog(#"Date ===>>> %#",[dateFormatter stringFromDate:[NSDate date]]);
Hope this helps!
I think you are mixing NSDate with NSCalendar: NSDate is a point in time, internally represented in UTC. To get the local date/time as it is displayed on a calendar or watch , you use NSCalendar.
So if you are in MEST (UTC+2) and set the time to "5" hours on your calendar, this will be UTC "3" hours.
To get the calendar date/time back, you could use components(_:from:) from NSCalendar.
Just check this code:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"yyyy-MM-dd'T'HH:mm:ssZZZZZ"];
NSDate * dateForNewEvent = [dateFormatter dateFromString: #"2018-07-09T07:24:13+00:00"];
NSLog(#"dateForNewEvent: %#", dateForNewEvent);
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *comps = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear|NSCalendarUnitHour|NSCalendarUnitMinute fromDate:dateForNewEvent];
[comps setHour:5];
NSDate *final = [gregorian dateFromComponents:comps];
NSLog(#"final: %#", final);
Output as expected:
2018-07-09 11:11:43.542 jdoodle[22:22] dateForNewEvent: 2018-07-09 07:24:13 +0000
2018-07-09 11:11:43.542 jdoodle[22:22] final: 2018-07-09 05:24:00 +0000
I have following code to convert string to date. Is it possible that it sets time as "00:00:00" and not the current time?
NSDateFormatter *dateformat = [[NSDateFormatter alloc] init];
[dateformat setDateFormat:#"yyyy-MM-dd"];
NSString *str = #"2014-08-08";
NSDate *dt = [dateformat dateFromString:str];
This gives dt as "2014-08-08 15:20:00 +0000" because I did the operation at 15:20.
Edit: I am using this date to convert it to integer later to store it in database:
int t = [dt timeIntervalSince1970];
If you are displaying the date dt with NSLog you will see what the date description method provides. If you want to see the date in a specific way that suits you use NSDateFormatter to format the date.
Example:
NSDateFormatter *dateformat = [[NSDateFormatter alloc] init];
[dateformat setDateFormat:#"yyyy-MM-dd"];
NSString *str = #"2014-08-08";
NSDate *dt = [dateformat dateFromString:str];
NSDateFormatter *displayDateformat = [[NSDateFormatter alloc] init];
[displayDateformat setDateFormat:#"yyyy-MM-dd"];
NSString *displayDateString = [displayDateformat stringFromDate:dt];
NSLog(#"displayDateString: %#", displayDateString);
Output:
2014-08-08
Note per Apple docs: "This method returns a time value relative to an absolute reference dateāthe first instant of 1 January 2001, GMT."
A good practice is to use NSDateComponents
NSDate *yourDate = [NSDate date];
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDateComponents *dateComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:yourDate];
[calendar setTimeZone:[NSTimeZone localTimeZone]];
// Set the time components manually
[dateComponents setHour:0];
[dateComponents setMinute:0];
[dateComponents setSecond:0];
yourDate = [calendar dateFromComponents:dateComponents];
Update
iOS8 :
[[NSCalendar currentCalendar] startOfDayForDate:[NSDate date]];
I am using following piece of code to get next week date from a given date at 12:00am:
NSDate *now = [NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit |NSHourCalendarUnit fromDate:now];
[components setHour:0];
NSDate *todayDate = [calendar dateFromComponents:components];
int daysToAdd = 7;
NSDate *tomorrowDate = [todayDate dateByAddingTimeInterval:60*60*24*daysToAdd];
NSString *stringDate = [NSString stringWithFormat:#"%#",tomorrowDate];
todoItemDueDateText.text = stringDate;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"EEEE, dd MMMM YYYY"];
NSString *fechasimulada = [dateFormatter stringFromDate:tomorrowDate];
dateFieldSimulatedText.text = fechasimulada;
If I log the result date, it is working fine.
Now, a similar piece of code to get next month date from a given date at 12:00am:
NSDate *now = [NSDate date];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents *components = [calendar components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:now];
[components setHour:0];
NSDate *todayDate = [calendar dateFromComponents:components];
//NSDate *today = [NSDate date];
NSDateComponents* dateComponents = [[NSDateComponents alloc]init];
[dateComponents setMonth:1];
//NSCalendar* calendar = [NSCalendar currentCalendar];
NSDate* tomorrowDate = [calendar dateByAddingComponents:dateComponents toDate:todayDate options:0];
NSString *stringDate = [NSString stringWithFormat:#"%#",tomorrowDate];
todoItemDueDateText.text = stringDate;
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:#"EEEE, dd MMMM YYYY"];
NSString *fechasimulada = [dateFormatter stringFromDate:tomorrowDate];
I don't know why, but the second piece of code gives the expected date but -1 hour.
UPDATE:
I will show you the dates:
Source date (today at 12:00am)+7 h
Next week date from previous given date:
Next month date from previous given date:
NSDate takes Daylight Savings into account. If you cross a DST day, you'll experience this issue.
Hi I have a countdown timer in my app and I am looking for a way to take my timestamp date and modify it based on the time zone without formatting it. The time stamp is GMT and it looks like this:
theDate = [NSDate dateWithTimeIntervalSince1970:1387929601];
Then I have my countdown formatter here:
-(void)updateCountdownText
{
//Update the Countdown Label
NSCalendar *calendar = [[NSCalendar alloc]initWithCalendarIdentifier:NSGregorianCalendar];
int units = NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateComponents *components = [calendar components:units fromDate:[NSDate date] toDate:theDate options:0];
[dateLabel setText:[NSString stringWithFormat:#"%d%c %d%c %d%c %d%c", [components day], 'd', [components hour], 'h', [components minute], 'm', [components second], 's']];
}
Since I'm already formatting the timestamp below all i would like to do is take the GMT timestamp number and convert it according to the local time zone. So I would just like to add the time zone code before the dateWithTimeInterval and then change that number (keeping it a timestamp) according to the time zone. Is this possible? Thanks!
Try this one:
//Timestamp convert to NSDate
double time=[myString doubleValue];//in yourcase mystring=#"1387929601"; mystring is timestamp
NSTimeInterval interval =time ;
NSDate *online = [NSDate dateWithTimeIntervalSince1970:interval];
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"hh:mm a dd-MMM-yyyy"];
NSLog(#"Timestamp date is: %#", [dateFormatter stringFromDate:online]);
NSString *mystr=[dateFormatter stringFromDate:online];
NSCalendar *cal = [NSCalendar currentCalendar];
NSDate *now = [dateFormatter dateFromString:mystr];
value1=([[NSTimeZone localTimeZone] secondsFromGMT]);
value1=value1/3600;
float value123=((value1) * 3600);
NSTimeZone *tz = [NSTimeZone timeZoneForSecondsFromGMT:(value123)]; // for PST
NSDateComponents *dc = [cal components: NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit fromDate:now];
[cal setTimeZone:tz];
NSDate *newDate = [cal dateFromComponents:dc];
NSDateFormatter *dateFormatter1 = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter1 setDateFormat:#"hh:mm a dd-MMM-yyyy"];
NSLog(#"result: %#", [dateFormatter1 stringFromDate:newDate]);
May it will work for you.
happy coding...
Use NSDateFormatter to get correct time zone of your theDate object.
NSDateFormatter *formatter = [[NSDateFormatter alloc]init];
[formatter setTimeZone:[NSTimeZone localTimeZone];
NSTimeZone has a property secondsFromGMT. So you can use [NSTimeZone systemTimeZone].secondsFromGMT; to obtain the difference, add it to your time interval and instantiate the date.
Format the NSDate to adjust for time zone:
NSTimeZone *tz = [[NSTimeZone timeZoneForSecondsFromGMT:(-8 * 3600)];
[dateFormatter setTimeZone:tz];
NSString* s = [dateFormatter stringFromDate:now];
If I have a string representing a time, say "10:45 am", and do the following to parse the string:
NSDateFormatter *dateFormat;
dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"h:mm a"];
NSLog(#"%#", [dateFormat dateFromString:#"10:45 AM"]);
I would get this logged:
2013-09-09 17:52:30.416 TimeTest[49491:a0b] 2000-01-01 15:45:00 +0000
How can I create an NSDate for the current day at the given time? I tried this
NSDate *date = [NSDate date];
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"h:mm a"];
NSDate *time = [formatter dateFromString:#"10:45 AM"];
NSDateComponents *timeComponents = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit | NSMinuteCalendarUnit ) fromDate:time];
NSDateComponents *dateComponents = [[NSCalendar currentCalendar] components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:date];
NSDateComponents *newComponents = [[NSDateComponents alloc]init];
newComponents.timeZone = [NSTimeZone systemTimeZone];
[newComponents setDay:[dateComponents year]];
[newComponents setMonth:[dateComponents month]];
[newComponents setYear:[dateComponents year]];
[newComponents setHour:[timeComponents hour]];
[newComponents setMinute:[timeComponents minute]];
NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *combinedDate = [gregorianCalendar dateFromComponents:newComponents];
NSLog(#"%#", combinedDate);
with the result
2013-09-09 19:57:14.506 TimeTest[49712:a0b] 2019-03-06 15:45:00 +0000
How should I go about this?
I'm not exactly sure what you are looking for. For what I understand, you want to build a date with the current year, month and day, but with your supplied time by parsing it from a string.
If that is the case, as others have pointed out, you need to play with NSDateComponents.
Based on your code I wrote these lines. They should build a date by merging two dates. The current one and the one you parsed.
// Get the full current date
NSDate *date = [NSDate date];
// Get the current calendar
NSCalendar *calendar = [NSCalendar currentCalendar];
// Split the date into components but only take the year, month and day and leave the rest behind
NSDateComponents *dateComponents = [calendar components:(NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit) fromDate:date];
// Build the date formatter
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"h:mm a"];
// Convert the string time into an NSDate
NSDate *time = [formatter dateFromString:#"10:45 AM"];
// Split this one in components as well but take the time part this time
NSDateComponents *timeComponents = [[NSCalendar currentCalendar] components:(NSHourCalendarUnit | NSMinuteCalendarUnit ) fromDate:time];
// Do some merging between the two date components
dateComponents.hour = timeComponents.hour;
dateComponents.minute = timeComponents.minute;
// Extract the NSDate object again
NSDate *result = [calendar dateFromComponents:dateComponents];
// Check if this was what you where looking for
NSLog(#"%#",result);
Please be aware that this sample code is by far non-optimized. There are more crisp ways to obtain what you are looking for by using time intervals, but I felt like you wanted a dirty simple example on how to do components copy and paste and then extracting dates.
This will create a date for the beginning of the day in the current time zone.
NSDate *today = [NSDate date];
NSTimeInterval interval;
NSCalendar *cal = [NSCalendar currentCalendar];
[cal rangeOfUnit:NSDayCalendarUnit
startDate:&today
interval:&interval
forDate:today];
Now we add the time:
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
// I have to set the locale to posix_en_us, as my system is using 24hour style as default
dateFormatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_US_POSIX"];
[dateFormatter setDateFormat:#"hh:mm a"];
NSDate *time = [dateFormatter dateFromString:#"10:45 AM"];
NSDateComponents *comps = [cal components:(NSHourCalendarUnit | NSMinuteCalendarUnit)
fromDate:time];
NSDate *dateAndTime = [cal dateByAddingComponents:comps
toDate:today
options:0];
dateAndTime will now be todays date with 10:45 am in the local timezone.
controlling in the debugger:
po dateAndTime
$0 = 0x41b7df138c00000d 2013-09-10 08:45:00 +0000
This is correct, as my timezone is 2 hours ahead to GMT, as we still have summer time.