Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
Currently I failed to convert a day of the year integer to a formatted string / date like mm-dd. I tried some different solution approaches, including most of the solutions which are posted here - without success.
I expect this: Today is the 359 day of the year - and it should be converted to 12-25
NSCalendar *gregorian = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
NSDateComponents* components = [[NSDateComponents alloc] init];
[components setDay:359];
[components setYear:2013];
[components setTimeZone:[NSTimeZone timeZoneForSecondsFromGMT:0]];
NSDate* day359 = [gregorian dateFromComponents:components];
output
2013-12-25 00:00:00 +0000
Really?, even without knowing objective-c it seems quite stright forward:
const JANUARY = 31;
const FEBURARY = JANUARY + 28;
const MARCH = FEBRUARY + 31;
...
const NOVEMBER = OCTOBER + 30;
if( day < JANUARY ) { dd = day; mm = 1; }
else if( day < FEBRUARY ) { dd = day - JANUARY; mm = 2 }
else if( day < MARCH ) { dd = day - FEBRUARY; mm = 3 }
...
else if( day < NOVEMBER ) { dd = day - OCTOBER; mm = 11 }
else { dd == day - NOVEMBER; mm = 12 }
print "$dd/$mm";
Related
Why are the last two lines of the output the same?
Use NSCalendar to calculate the diff between startTime and endTime, find that the diff between #"2008-02-28 00:00:00" and #"2022-02-28 00:00:00" and the diff between #"2008-02-29 00:00:00" and #"2022-02-28 00:00:00" are the same. It looks like a bug of NSCalendar, maybe about leapMonth?
code:
- (void)viewDidLoad
{
[super viewDidLoad];
[self printDiffBetweenStartTime:#"2008-02-27 00:00:00" endTime:#"2022-02-28 00:00:00"];
[self printDiffBetweenStartTime:#"2008-02-28 00:00:00" endTime:#"2022-02-28 00:00:00"];
[self printDiffBetweenStartTime:#"2008-02-29 00:00:00" endTime:#"2022-02-28 00:00:00"];
}
- (void)printDiffBetweenStartTime:(NSString *)startTime endTime:(NSString *)endTime
{
static NSDateFormatter *dateFormatter;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
dateFormatter = [[NSDateFormatter alloc] init];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss";
dateFormatter.calendar = [NSCalendar calendarWithIdentifier:NSCalendarIdentifierGregorian];
});
NSCalendar *calendar = [NSCalendar currentCalendar];
NSDate *startDate = [dateFormatter dateFromString:startTime];
NSDate *endDate = [dateFormatter dateFromString:endTime];
NSCalendarUnit unitFlags = NSCalendarUnitYear | NSCalendarUnitMonth | NSCalendarUnitDay | NSCalendarUnitHour | NSCalendarUnitMinute | NSCalendarUnitSecond;
NSDateComponents *components = [calendar components:unitFlags fromDate:startDate toDate:endDate options:0];
NSLog(#"\"%#\" to \"%#\" : %# year %# month %# day %# hour %# minute %# second", startTime, endTime, #(components.year), #(components.month), #(components.day), #(components.hour), #(components.minute), #(components.second));
}
output:
"2008-02-27 00:00:00" to "2022-02-28 00:00:00" : 14 year 0 month 1 day 0 hour 0 minute 0 second
"2008-02-28 00:00:00" to "2022-02-28 00:00:00" : 14 year 0 month 0 day 0 hour 0 minute 0 second
"2008-02-29 00:00:00" to "2022-02-28 00:00:00" : 14 year 0 month 0 day 0 hour 0 minute 0 second
This is expected. There are many ways to do these period calculations, and the one that NSCalendar uses turns out to not be the one you expected.
The documentation briefly describes what it does:
Some operations can be ambiguous, and the behavior of the computation is calendar-specific, but generally larger components will be computed before smaller components; for example, in the Gregorian calendar a result might be 1 month and 5 days instead of, for example, 0 months and 35 days.
What this means is that it will compute how many years are in between the two dates first, then months, then days, and so on. "Years" is the biggest component you requested.
And NSCalendar finds that adding 14 years to 2008-02-28 makes exactly 2022-02-28. Adding 14 years to 2008-02-29 is also exactly 2022-02-28, because 2022 is not a leap year. Note that "adding a year" does not mean the same as "adding 12 months" or "adding 365 days".
For a difference to appear in this case, you need to compute the days first. One period has 5114 days, and the other has 5113.
A few more examples:
If you instead compute the year, month, day period between 2008-02-28 and 2022-02-01, and the period between 2008-02-29 and 2022-02-01. You wouldn't see a difference, both are 13 years, 11 months, and 4 days. This is because adding 13 years to both 2008-02-29 and 2008-02-28 gets you to 2021-02-28, then adding 11 months is 2022-01-28. 4 days after that is 2022-02-01.
However, if you only compute months and days, the period between 2008-02-28 and 2022-02-01, and the period between 2008-02-29 and 2022-02-01 are different.
The period between 2008-02-28 and 2022-02-01 is 167 months and 4 days. Adding 167 months to 2008-02-28 is 2022-01-28. 4 days after that is 2022-02-01.
The period between 2008-02-29 and 2022-02-01 is 167 months and 3 days. Adding 167 months to 2008-02-29 is 2022-01-29. 3 days after that is 2022-02-01.
Period calculations are weird, aren't they! But they are consistent in a unique way.
I am getting NSDateComponents of date 2018-06-01 00:00:00 +0000 like this
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalendarUnitDay | NSCalendarUnitMonth|NSCalendarUnitYear |NSCalendarUnitHour | NSCalendarUnitMinute fromDate:date];
[components setTimeZone:[NSTimeZone timeZoneWithAbbreviation: #"UTC"]];
NSInteger month =[components month];
When I print the value of components , I get this value.
TimeZone: GMT (GMT) offset 0
Calendar Year: 2018
Month: 5
Leap month: no
Day: 31
Hour: 21
Minute: 0
My expected out put should be
TimeZone: GMT (GMT) offset 0
Calendar Year: 2018
Month: 6
Leap month: no
Day: 1
Hour: 0
Minute: 0
How can I get the value of month correctly?
When you use NSCalendar components:fromDate: the results are based on the calendar's current timezone which defaults to the user's local timezone.
Your attempt to set the resulting components' timeZone doesn't alter the current components. That would only affect how the components would be interpreted if you used the components to create a new NSDate.
Assuming your goal is to get the components of date in UTC time and not in local time, then you need to set the calendar's timeZone before getting the components from date.
NSDate *date = // your date
NSCalendar *calendar = NSCalendar.currentCalendar;
calendar.timeZone = [NSTimeZone timeZoneWithAbbreviation:#"UTC"];
NSDateComponents *components = [calendar components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear | NSCalendarUnitHour | NSCalendarUnitMinute fromDate:date];
NSLog(#"UTC Components: %#", components);
But keep in mind that you must understand which timezone you really want here. Be sure you really want the UTC timezone. Don't use UTC just because it matches the output of NSLog(#"Date: %#", date);. That log shows the date in UTC time.
How do you create your initial date object? When I try that setup everything works as expected:
NSString *dateString = #"2018-06-01 00:00:00 +0000";
NSDateFormatter *dateFormatter = [NSDateFormatter new];
dateFormatter.dateFormat = #"yyyy-MM-dd HH:mm:ss Z";
dateFormatter.locale = [NSLocale localeWithLocaleIdentifier:#"en_US_POSIX"];
dateFormatter.timeZone = [NSTimeZone timeZoneForSecondsFromGMT:0];
NSDate *date = [dateFormatter dateFromString:dateString];
NSCalendar *calendar = NSCalendar.currentCalendar;
NSDateComponents *components = [calendar components:NSCalendarUnitDay | NSCalendarUnitMonth | NSCalendarUnitYear | NSCalendarUnitHour | NSCalendarUnitMinute fromDate:date];
NSLog(#"Before: %#", components);
/*
Before: <NSDateComponents: 0x604000158e10>
Calendar Year: 2018
Month: 6
Leap month: no
Day: 1
Hour: 2
Minute: 0
*/
components.timeZone = [NSTimeZone timeZoneWithAbbreviation:#"UTC"];
NSLog(#"After: %#", components);
/*
After: <NSDateComponents: 0x604000158e10>
TimeZone: GMT (GMT) offset 0
Calendar Year: 2018
Month: 6
Leap month: no
Day: 1
Hour: 2
Minute: 0
*/
You need to get the last month date first.
extension Date {
//it will give the date of last month
var previousMonthDate: Date {
return Calendar.current.date(byAdding: .month, value: -1, to: self)!
}
}
Get the date components from date
let dt = Date()
let components = Calendar.current.dateComponents([.year, .month, .day], from: dt.previousMonthDate)
print(components.day ?? 0)
print(components.month ?? 0)
print(components.year ?? 0)
Suppose my business hours are from 7am to 7pm, then default selection of time date is :
A) During business hours, a hour later than current time
B) After business hour, 7 am the next business day.
How will you calculate value for Minimum and maximum date ??
Sol -A)
NSDate *minDate = [[NSDate date]dateByAddingTimeInterval:60 * 60 *1];
NSDate *maxDate = [[NSDate date]dateByAddingTimeInterval:60 * 60 * 24 * 2];
Is above solution for (A) is correct ?? is there any other way
Can anyone provide solution for (B) ??
Please provide proper programming code in objective C with explanation ??
I found the answer to this, but unfortunately it's using Java. I have two times, formatted as HHmm (no colons). I need to figure out how many 15 minute time segments are in the difference. For example, I have a start time of 1000 and an end time of 1130 (military time).
When I subtract the two dates, I get 130, which is meaningless for computations.
Is there an existing method that will do this for me? (I have spent the last 6 hours trying SO and Google, but found nothing).
UPDATE: I would appreciate it if whoever downvoted me please reverse it. The question is very pertinent and others will find it useful. Thank you.
Parse each time and convert to minutes. So 1000 becomes 10 hours 0 minutes for a total of 600 minutes. 1130 becomes 11 hours 30 minutes for a total of 690 minutes. Subtract the two values for a difference of 90 minutes. Now divide by 15 to get 6.
The following assumes all times are 4 digit military times:
NSString *startTime = #"1000";
NSString *endTime = #"1130";
int startMinues = [[startTime substringToIndex:2] intValue] * 60 + [[startTime substringFromIndex:2] intValue];
int endMinues = [[endTime substringToIndex:2] intValue] * 60 + [[endTime substringFromIndex:2] intValue];
int minutes = endMinutes - startMinutes;
int units = minutes / 15;
This gives whole units of your 15 minute blocks.
Use -[NSCalendar components:fromDate:toDate:options], like this:
NSDateComponents *components = [[NSCalendar currentCalendar] components:NSCalenderUnitMinute fromDate:startDate toDate:endDate options:0];
NSInteger numberOfMinutes = [components minute];
Once you have the number of minutes, it should just be a matter of dividing by 15 to get the number of 15 minute chunks.
Try using NSDateComponents:
NSCalendar *calendar = [[[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar] autorelease];
NSDateComponents *components = [calendar components:NSMinuteCalendarUnit|NSHourCalendarUnit
fromDate:dateA
toDate:dateB
options:0];
int increments = components.hour*4 + components.minute/15;
Format is rather simple:
int HHmm = [date intValue];
int HH = HHmm / 100;
int mm = HHmm % 100;
Diff, for two parsed dates:
int diff = ((HH2 * 60 + mm2) - (HH1 * 60 + mm1)) / 15;
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
Questions asking for code must demonstrate a minimal understanding of the problem being solved. Include attempted solutions, why they didn't work, and the expected results. See also: Stack Overflow question checklist
Closed 9 years ago.
Improve this question
I'm having an array with different times of lessons. Here's an example what kind of information my array contains:
09.00 - 10.00, 11.00 - 12.00, 13.00 - 14.00, 15.00 - 16.00
I'm displaying these lessons in a UIPickerView in order to let the user choose the desired time. But I want the PickerView to automatically preselect the lesson which is closest to the actual time. I would somehow have to compare it to the actual date. Has anybody an idea how to do that?
Thanks in advance!
This will give the current hour:Minutes
NSDateFormatter *dateFormat = [[NSDateFormatter alloc] init];
[dateFormat setDateFormat:#"HH:mm"];
NSString *str = [dateFormat stringFromDate:[NSDate date]];
Then you can find the difference and check for minimum.
Now you can put condition like :
if (hh <= 10 ) { // 09:00 - 10:00 should come }
else if (hh == 10 && mm < 30 ) { // 09:00 - 10:00 should come }
else if (hh == 10 && mm > 30 ) { // 11:00 - 12:00 should come }
else if (hh <= 12 && mm < 30 ) { // 11:00 - 12:00 should come }
else if (hh == 14 && mm < 30 ) { // 13:00 - 14:00 should come }
else if (hh <= 14 && mm > 30 ) { // 13:00 - 14:00 should come }
else if (hh == 14 && mm < 30 ) { // 15:00 - 16:00 should come }
else if (hh <= 14 && mm > 30 ) { // 15:00 - 16:00 should come }
else { // 15:00 - 16:00 should come }