iOS: display time as am/pm - ios

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

Related

NSDateComponents wrongly adds one extra hour

I'm trying to create a method in Objective-C which would get the total number of minutes from a time value, written in "HHmm" format.
E.g. for "0210" the return value should be 130.
+ (int)totalMinutesFromHHmm:(NSString *)HHmm {
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:#"UTC"];
[dateFormatter setTimeZone:timeZone];
[dateFormatter setDateFormat:#"HHmm"];
NSLocale *enLocale = [[NSLocale alloc] initWithLocaleIdentifier:#"en-GB"];
[dateFormatter setLocale:enLocale];
NSDate *date = [dateFormatter dateFromString:HHmm];
NSCalendar *calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
NSDateComponents *components = [calendar components:( NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond) fromDate:date];
NSInteger hour = [components hour];
NSInteger minute = [components minute];
return (int)(hour * 60 + minute);
}
The problem is the hour component: it's always one hour off.
On this picture the NSDate shows a 09:22 time, but on the picture below you can see the hour component is 10 (the minute component is correctly set to 22).
I looked at other posts ('NSDateComponents on hour off', etc.), but couldn't find a solution that works. Any idea what I'm doing wrong?
Time Zone / locale might not need to come into this. I could be misunderstanding, but it seems like you are just trying to take a string in HHmm format and calculate the total minutes.
If you need to use NSDate still for some reason, this could work:
+ (int)totalMinutesFromHHmm:(NSString*)HHmm
{
NSString* refHHmm = #"0000";
NSDateFormatter* dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"HHmm"];
NSDate* refDate = [dateFormatter dateFromString:refHHmm];
NSDate* date = [dateFormatter dateFromString:HHmm];
int minutes = [date timeIntervalSinceDate:refDate] / 60;
return minutes;
}
Otherwise, this could be a simpler option, since you know you will have a 4-character string representing the hours and minutes:
+ (int)totalMinutesFromHHmm:(NSString*)HHmm
{
int minutes = [[HHmm substringWithRange:NSMakeRange(0, 2)] intValue] * 60;
minutes += [[HHmm substringWithRange:NSMakeRange(2, 2)] intValue];
return minutes;
}

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.

NSDate: Extract Date ONLY

I'm using the code below to extract the date only from NSDate. What am I doing wrong?
NSDate* now = [NSDate date];
NSLog(#"Now Date %#",now);
NSDateFormatter *format = [[NSDateFormatter alloc] init];
format.dateFormat = #"dd-MM-yyyy";
NSString *stringDate = [format stringFromDate:now];
NSDate *todaysDate = [format dateFromString:stringDate];
NSLog(#"Today's Date without Time %#", todaysDate);
Log:
2014-06-21 12:27:23.284 App[69727:f03] Now Date 2014-06-21 19:27:23 +0000
2014-06-21 12:27:23.285 App[69727:f03] Today's Date without Time 2014-06-21 07:00:00 +0000
Why am I getting: 07:00:00 +0000 at the end?
I would like to get an NSDate in the in the following format:
2014-06-21 00:00:00 +0000
Having 0's for time, seconds, etc. is not important.
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"yyyy-MM-dd"];
NSDate *now = [[NSDate alloc] init];
NSString *theDate = [dateFormat stringFromDate:now];
should work
Another solution: using NSCalendar:
NSCalendar *cal = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
[cal setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:1]]; // I'm in Paris (+1)
NSDateComponents *comps = [cal components:NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay fromDate:[NSDate date]];
comps.hour = 0;
comps.minute = 0;
comps.second = 0;
NSDate *newDate = [cal dateFromComponents:comps ];
NSLog(#"date: %#",newDate);
Adjust timezone param, you will receive something like: date: 2014-06-21 00:00:00 +0000
If you don't care about the time, NSDate is not the right storage structure for you. An NSDate represents a specific moment in time - there is no NSDate without a time. What you're seeing is the logged description of an NSDate, which is the full printout in GMT.
If you want to keep track of the year, month and day only, then use NSDateComponents instead, and extract only the components you are interested in. You can then use the components object and pass it around as you like.
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:#"dd-MM-yyyy"];
NSString *strDate = [dateFormatter stringFromDate:[NSDate date]];
With the code above, the NSDate object will HAVE time. But the string will be a date only text.
This is the code using .
#include <time.h>
- (NSDate *)dateFromISO8601String:(NSString *)string {
if (!string) {
return nil;
}
struct tm tm;
time_t t;
strptime([string cStringUsingEncoding:NSUTF8StringEncoding], "%Y-%m-%dT%H:%M:%S%z", &tm);
tm.tm_hour = 0;
tm.tm_min = 0;
tm.tm_sec = 0;
tm.tm_isdst = -1;
t = mktime(&tm);
return [NSDate dateWithTimeIntervalSince1970:t + [[NSTimeZone localTimeZone] secondsFromGMT]];
}
- (NSString *)ISO8601String:(NSDate*)aDate {
struct tm *timeinfo;
char buffer[80];
time_t rawtime = [aDate timeIntervalSince1970] - [[NSTimeZone localTimeZone] secondsFromGMT];
timeinfo = localtime(&rawtime);
strftime(buffer, 80, "%Y-%m-%dT%H:%M:%S%z", timeinfo);
return [NSString stringWithCString:buffer encoding:NSUTF8StringEncoding];
}
NSString *currentDateStr = [self ISO8601String:[NSDate date]];
NSDate *dateWithoutTime = [self dateFromISO8601String:currentDateStr];
NSLog(#"currentDateStr: %#",currentDateStr);
NSLog(#"dateWithoutTime: %#",dateWithoutTime);

NSDate gives wrong year

I am trying to work with NSDate and it is not working for me, I am so confused right now. So the basic thing I want works, but it needs to be the day of today and not from the year 2000.
So what I want is that the Date should be the date of today with the hours that are in my string bU and eU and not the date from the year 2000 with the hours of my string.
Here is a piece of my code:
NSDate *localNotDate;
NSDateFormatter *df = [[NSDateFormatter alloc] init];
[df setTimeZone:[NSTimeZone localTimeZone]];
[df setDateFormat:#"HH:mm"];
NSDate *bU = [df dateFromString:[[[self alarmArray] objectAtIndex:arrayInt] beginUur]]; // This is a 24:00 format string
NSDate *eU = [df dateFromString:[[[self alarmArray] objectAtIndex:arrayInt] eindUur]]; // This is a 24:00 format string
if (intForInsideForLoop == 0) { // Setup NSDate on first loop.
localNotDate = bU; // This gives the date 2000-01-01 08:24
}
if (intForInsideForLoop < timesOnDay) {
localNotDate = [localNotDate dateByAddingTimeInterval:(interval * 60)]; // Adds minutes to the date of today.
NSDateFormatter *dtest = [[NSDateFormatter alloc] init];
[dtest setTimeZone:[NSTimeZone localTimeZone]];
[dtest setDateFormat:#"yyyy-MM-dd HH:mm"];
NSLog(#"%#", [dtest stringFromDate:localNotDate]); // This gives the date 2000-01-01 08:24. it should be like It's Today thursday so 2014-05-08 08:24
}
I have found the answer to my problem with the method Martin has given from the post. This method converts an "Time" string like (18:00) to the date of today at 18:00.
Here it is:
- (NSDate *)todaysDateFromString:(NSString *)time
{
// Split hour/minute into separate strings:
NSArray *array = [time componentsSeparatedByString:#":"];
// Get year/month/day from today:
NSCalendar *cal = [NSCalendar currentCalendar];
NSDateComponents *comp = [cal components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:[NSDate date]];
// Set hour/minute from the given input:
[comp setHour:[array[0] integerValue]];
[comp setMinute:[array[1] integerValue]];
return [cal dateFromComponents:comp];
}

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