Hours in NSDate every time in 24-hour style? - ios

I have this date formatter:
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init];
[timeFormatter setDateFormat:#"HH:mm"];
If I use this:
NSDate *myDate = [timeFormatter dateFromString:#"13:00"];
It returns this:
"1:00"
This is because the simulator has switched off 24-hour. But for my app I really need "13:00" instead of "1:00"
--- EDIT 1 ---
Added new code:
NSCalendar *calendar= [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSCalendarUnit unitFlags = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init];
[timeFormatter setDateFormat:#"HH:mm"];
NSDate *timeForFirstRow = [timeFormatter dateFromString:#"13:00"];
NSDateComponents *dateComponents = [calendar components:unitFlags fromDate:timeForFirstRow];
NSInteger hour = [dateComponents hour]; //This will be 1 instead of 13
NSInteger minute = [dateComponents minute];

If you want to force it to 12-hour or 24-hour mode, regardless of the user's 24/12 hour mode setting, you should set the locale of the date formatter to en_US_POSIX (for 12-hour), or, say, en_GB for the 24-hour mode.
That is,
NSLocale* formatterLocale = [[[NSLocale alloc] initWithLocaleIdentifier:#"en_GB"] autorelease];
[timeFormatter setLocale:formatterLocale];
Some more on that here:
http://developer.apple.com/iphone/library/qa/qa2010/qa1480.html

I had this same issue recently and came across this document which lists all the date format patterns: http://unicode.org/reports/tr35/tr35-6.html#Date_Format_Patterns
I was able to get 24-times working just by using k:mm as the date format:
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:#"k:mm"];

You have to two steps here
NSLocale* locale = [[NSLocale alloc] initWithLocaleIdentifier:#"en_GB"];
[formatter setLocale:locale];
[formatter setDateFormat:#"hh:mm a"];
here a in the formatter gives am/pm format

From Apple Documentation, the time formatting strings follow Unicode Technical Standard #35.
As stated in UTR #35, uppercase HH gives you 24-hour style time while lowercase hh gives you 12-hour style time.
In short, if you need 24-hour style, use [timeFormatter setDateFormat:#"HH:mm"]; and if you need 12-hour style, use [timeFormatter setDateFormat:#"hh:mm"];

If it helps anyone I have just had an issue where I want to display the time for the user in the way they have set on their device:
let timeFormatter = NSDateFormatter()
timeFormatter.timeStyle = NSDateFormatterStyle.ShortStyle
//get the time from the picker
The send the time to our API in 24 style:
timeFormatter.locale = NSLocale(localeIdentifier: "en_GB")
//get the time again

Related

how to get date value when its create from current date

How to convert string date #"2016-10-19T12:37:15.0896144+00:00" int second/Min/hour/days/months/year.
I have date create value i.e #"2016-10-19T12:37:15.0896144+00:00"
**after few seconds need to show " 50 sec"
after few minutes need to show "40 min"
after few hours need to show #"20 hours"
after few days need to show #"3 days"
after few month need to show #"4 month"
after few year need to show #"2 years"**
What I tried is which i not working.
NSString* format = #"2016-10-19T12:37:15.0896144+00:00";
// Set up an NSDateFormatter for UTC time zone
NSDateFormatter* formatterUtc = [[NSDateFormatter alloc] init];
[formatterUtc setDateFormat:format];
[formatterUtc setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
// Cast the input string to NSDate
NSDate* utcDate = [formatterUtc dateFromString:[formatterUtc stringFromDate:timeString]];
// Set up an NSDateFormatter for the device's local time zone
NSDateFormatter* formatterLocal = [[NSDateFormatter alloc] init];
[formatterLocal setDateFormat:format];
[formatterLocal setTimeZone:[NSTimeZone localTimeZone]];
// Create local NSDate with time zone difference
NSDate* localDate = [formatterUtc dateFromString:[formatterLocal stringFromDate:utcDate]];
NSTimeInterval seconds = [[NSDate date] timeIntervalSinceDate:localDate];
Your input is highly appreciated.
Use NSDateFormatter to convert your strings to dates. Then use NSDateComponentsFormatter with maximumUnitCount of 1 and allowedUnits to include seconds, minutes, hours, days, month, and year.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyy-MM-dd'T'HH:mm:ss.SSSSSSSZ";
dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"];
NSDate *date1 = [dateFormatter dateFromString:#"2016-08-19T12:37:15.0896144+00:00"];
NSDate *date2 = [NSDate date]; // or, if date2 is also from a string, just use that dateFormatter again
NSDateComponentsFormatter *componentsFormatter = [[NSDateComponentsFormatter alloc] init];
componentsFormatter.unitsStyle = NSDateComponentsFormatterUnitsStyleFull;
componentsFormatter.allowedUnits = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
componentsFormatter.maximumUnitCount = 1;
NSString *string = [componentsFormatter stringFromDate:date1 toDate:date2];
If you're wondering about the locale setting, see Apple Technical Q&A 1480.

setting time when formatting date using NSDateformatter

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]];

NSDateFormatter not converting to correct date

I have a problem converting a string date to NSDate since the conversion is not correct. This is my code:
NSString *stringDate = #"6/20/2014 8:38:52 PM";
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"MM/dd/yyyy hh:mm:ss a"];
NSDate *timeStamp = [dateFormatter dateFromString:stringDate];
The log always says TIMESTAMP: 2014-06-20 12:38:37 +0000.
How can I convert it to a correct date? Thanks in advance.
I believe you are doing this to display the date in the log:
NSLog(#"timeStamp = %#", timeStamp);
Instead keep the date formatter around (store it globally or something) and do:
NSLog(#"timeStamp = %#", [dateFormatter stringFromDate:timeStamp]);
The difference is the first line of code calls [NSDate description] to format the date, which uses UTC/GMT time zone, where as the second line of code uses the time zone configured in the date formatter (which by default is the same the locale's time zone), and crucially the same time zone you used to parse the string in the first place.
Add
[dateFormatter setTimeZone:[NSTimeZone timeZoneWithName:#"UTC"]];
And you get date in UTC time zone.
You can use this. It will give you proper output
NSDateComponents *dateComponents = [[NSDateComponents alloc] init];
[dateComponents setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[dateComponents setYear:2014];
[dateComponents setMonth:6];
[dateComponents setDay:20];
[dateComponents setHour:8];
[dateComponents setMinute:38];
[dateComponents setSecond:52];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDate *date = [calendar dateFromComponents:dateComponents];
//NSDate *timeStamp = [dateFormatter dateFromString:stringDate];
NSLog(#"date = %#",date);
//solutions[2247:70b] date = 2014-06-20 08:38:52 +0000 printing date

iOS: display time as am/pm

I am new to objective c. I wish to do the following:
Convert 24 hour format to 12 hour and then add +2 to hour and display it like: 4:00 pm
I get the 12 hour format but after adding +2 to it , the time is displayed always as "am", i.e even if it is 4 pm it is displayed as 4 am. Below is my code:
NSDate *now = [NSDate date];
NSDateFormatter *timeFormatter=[[NSDateFormatter alloc]init];
timeFormatter.dateFormat=#"hh:00 a";
NSString *currentHour=[timeFormatter stringFromDate:now ];
lblcurrentHour.text=[NSString stringWithFormat:#"%#",currentHour];
NSLog(#"%#",currentHour);
int hour=[[timeFormatter stringFromDate:now]intValue];
NSDateFormatter *dateFormatter1 = [[NSDateFormatter alloc] init];
dateFormatter1.dateFormat = #"HH:mm";
NSDate *date1 = [dateFormatter1 dateFromString:[NSString stringWithFormat:#"%02d:00",hour+=3]];
dateFormatter1.dateFormat = #"hh:mm a";
lblnextHour.text = [dateFormatter1 stringFromDate:date1]; // prints 4:00 am not pm
How do i solve this? Where am i getting wrong?
If I understand your requirements correctly, you want to take the current time and display the minutes as :00, anchoring to the current hour. Then you want to add two hours and display that time. The following code prints 04:00 AM and 06:00 AM to the console (local time is 0421.)
For calendrical calculations, I would avoid using NSDateFormatter as you are doing when you compute the time two hours from now. There are too many ways that can go astray. For example, what happens when the now time is 2300?
A good reference on calendrical calculations in Cocoa is here
#import <Foundation/Foundation.h>
int main(int argc, const char * argv[])
{
#autoreleasepool {
// use gregorian calendar for calendrical calculations
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
// get current date
NSDate *date = [NSDate date];
NSCalendarUnit units = NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit;
units |= NSHourCalendarUnit | NSMinuteCalendarUnit;
NSDateComponents *currentComponents = [gregorian components:units fromDate:date];
// change the minutes to 0
currentComponents.minute = 0;
date = [gregorian dateFromComponents:currentComponents];
// format and display the time
NSDateFormatter *timeFormatter = [[NSDateFormatter alloc] init];
timeFormatter.dateFormat = #"hh:mm a";
NSString *currentTimeString = [timeFormatter stringFromDate:date];
NSLog(#"Current hour = %#",currentTimeString);
// add two hours
NSDateComponents *incrementalComponents = [[NSDateComponents alloc] init];
incrementalComponents.hour = 2;
NSDate *twoHoursLater = [gregorian dateByAddingComponents:incrementalComponents toDate:date options:0];
// format and display new time
NSString *twoHoursLaterStr = [timeFormatter stringFromDate:twoHoursLater];
NSLog(#"Two hours later = %#",twoHoursLaterStr);
}
return 0;
}
Try this:
NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:#"hh:mm:ss a"];
NSLog(#"Today's Date and Time: %#", [formatter stringFromDate:[NSDate date]]);
Output:
Today's Date and Time: 02:43:33 PM

How do I get the day of the week with Foundation?

How do I get the day of the week as a string?
NSDateFormatter *dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
[dateFormatter setDateFormat:#"EEEE"];
NSLog(#"%#", [dateFormatter stringFromDate:[NSDate date]]);
outputs current day of week as a string in locale dependent on current regional settings.
To get just a week day number you must use NSCalendar class:
NSCalendar *gregorian = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDateComponents *comps = [gregorian components:NSWeekdayCalendarUnit fromDate:[NSDate date]];
int weekday = [comps weekday];
Just use these three lines:
CFAbsoluteTime at = CFAbsoluteTimeGetCurrent();
CFTimeZoneRef tz = CFTimeZoneCopySystem();
SInt32 WeekdayNumber = CFAbsoluteTimeGetDayOfWeek(at, tz);
Many of the answers here are deprecated. This works as of iOS 8.4 and gives you the day of the week as a string and as a number.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"EEEE"];
NSLog(#"The day of the week: %#", [dateFormatter stringFromDate:[NSDate date]]);
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *comps = [gregorian components:NSCalendarUnitWeekday fromDate:[NSDate date]];
int weekday = [comps weekday];
NSLog(#"The week day number: %d", weekday);
Here's how you do it in Swift 3, and get a localised day name…
let dayNumber = Calendar.current.component(.weekday, from: Date()) // 1 - 7
let dayName = DateFormatter().weekdaySymbols[dayNumber - 1]
-(void)getdate {
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd"];
NSDateFormatter *format = [[NSDateFormatter alloc] init];
[format setDateFormat:#"MMM dd, yyyy HH:mm"];
NSDateFormatter *timeFormat = [[NSDateFormatter alloc] init];
[timeFormat setDateFormat:#"HH:mm:ss"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init] ;
[dateFormatter setDateFormat:#"EEEE"];
NSDate *now = [[NSDate alloc] init];
NSString *dateString = [format stringFromDate:now];
NSString *theDate = [dateFormat stringFromDate:now];
NSString *theTime = [timeFormat stringFromDate:now];
NSString *week = [dateFormatter stringFromDate:now];
NSLog(#"\n"
"theDate: |%#| \n"
"theTime: |%#| \n"
"Now: |%#| \n"
"Week: |%#| \n"
, theDate, theTime,dateString,week);
}
I needed a simple (Gregorian) day of the week index, where 0=Sunday and 6=Saturday to be used in pattern match algorithms. From there it is a simple matter of looking up the day name from an array using the index. Here is what I came up with that doesn't require date formatters, or NSCalendar or date component manipulation:
+(long)dayOfWeek:(NSDate *)anyDate {
//calculate number of days since reference date jan 1, 01
NSTimeInterval utcoffset = [[NSTimeZone localTimeZone] secondsFromGMT];
NSTimeInterval interval = ([anyDate timeIntervalSinceReferenceDate]+utcoffset)/(60.0*60.0*24.0);
//mod 7 the number of days to identify day index
long dayix=((long)interval+8) % 7;
return dayix;
}
Here is the updated code for Swift 3
Code :
let calendar = Calendar(identifier: .gregorian)
let weekdayAsInteger = calendar.component(.weekday, from: Date())
To Print the name of the event as String:
let dateFromat = DateFormatter()
datFormat.dateFormat = "EEEE"
let name = datFormat.string(from: Date())
I think this topic is really useful, so I post some code Swift 2.1 compatible.
extension NSDate {
static func getBeautyToday() -> String {
let now = NSDate()
let dateFormatter = NSDateFormatter()
dateFormatter.dateFormat = "EEEE',' dd MMMM"
return dateFormatter.stringFromDate(now)
}
}
Anywhere you can call:
let today = NSDate.getBeautyToday()
print(today) ---> "Monday, 14 December"
Swift 3.0
As #delta2flat suggested, I update answer giving user the ability to specify custom format.
extension NSDate {
static func getBeautyToday(format: String = "EEEE',' dd MMMM") -> String {
let now = Date()
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = format
return dateFormatter.string(from: now)
}
}
Vladimir's answer worked well for me, but I thought that I would post the Unicode link for the date format strings.
http://www.unicode.org/reports/tr35/tr35-25.html#Date_Format_Patterns
This link is for iOS 6. The other versions of iOS have different standards which can be found in the X-Code documentation.
This way it works in Swift:
let calendar = NSCalendar.currentCalendar()
let weekday = calendar.component(.CalendarUnitWeekday, fromDate: NSDate())
Then assign the weekdays to the resulting numbers.
I had quite strange issue with getting a day of week. Only setting firstWeekday wasn't enough. It was also necesarry to set the time zone. My working solution was:
NSCalendar* cal = [NSCalendar currentCalendar];
[cal setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
[cal setFirstWeekday:1]; //Sunday
NSDateComponents* comp = [cal components:( NSWeekOfMonthCalendarUnit | NSYearCalendarUnit | NSMonthCalendarUnit | NSDayCalendarUnit | NSWeekdayCalendarUnit | NSWeekCalendarUnit) fromDate:date];
return [comp weekday] ;
Swift 2: Get day of week in one line. (based on neoscribe answer)
let dayOfWeek = Int((myDate.timeIntervalSinceReferenceDate / (60.0*60.0*24.0)) % 7)
let isMonday = (dayOfWeek == 0)
let isSunday = (dayOfWeek == 6)
self.dateTimeFormatter = [[NSDateFormatter alloc] init];
self.dateTimeFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0]; // your timezone
self.dateTimeFormatter.locale = [NSLocale localeWithLocaleIdentifier:#"zh_CN"]; // your locale
self.dateTimeFormatter.dateFormat = #"ccc MM-dd mm:ss";
there are three symbols we can use to format day of week:
E
e
c
The following two documents may help you.
https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/DataFormatting/Articles/dfDateFormatting10_4.html
http://www.unicode.org/reports/tr35/tr35-31/tr35-dates.html#Date_Format_Patterns
Demo:
you can test your pattern on this website:
http://nsdateformatter.com/

Resources