Detect which lesson is closest to now [closed] - ios

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 }

Related

Is it NSCalendar bug?

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.

Calculating Coordinated Mars Time v2.0

This is the follow up of a previous question of mine.
In a nutshell, I am trying to follow this tutorial step-by-step: https://jtauber.github.io/mars-clock/ to get to Coordinated Mars Time, but I got stuck right before the end. My code works fine up until the end (some values are more accurate than in the tutorial because I went back to the source from NASA: https://www.giss.nasa.gov/tools/mars24/help/algorithm.html ):
double millis = ( [[NSDate date] timeIntervalSince1970] * 1000 );
NSLog(#"millis: %f", millis);
double JDUT = ( 2440587.5 + (millis / 86400000) );
NSLog(#"JDUT: %f", JDUT);
double JDTT = ( JDUT + (37 +32.184) / 86400);
NSLog(#"JDTT: %f", JDTT);
double J2000Epoch = ( JDTT - 2451545.0 );
NSLog(#"J2000Epoch: %f", J2000Epoch);
double MSD = ( (( J2000Epoch - 4.5 ) / 1.0274912517) + 44796.0 - 0.0009626 );
NSLog(#"MSD: %f", MSD);
The only step remaining is actually calculating Coordinated Mars Time, using this equation:
MTC = mod24 { 24 h × MSD }
The problem is that I have no idea how. I tried to use modf( (double), (double *) ) but no idea how it actually works. I tried it the way below, but it gave me an incorrect answer (obviously as I have really no idea what I am doing). :(
double MSD24 = (24 * MSD);
double MCT = modf(24, &MSD24);
NSLog(#"MCT: %f", MCT); // Result: 0.000000
Any help would be much appreciated. Thank you very much!
p.s.: Notice that I use Objective-C; I do not understand swift unfortunately! :(
Carrying on from the code you gave, I tried:
CGFloat MTC = fmod(24 * MSD, 24);
and got
// 19.798515
which was right according to the web page you cited at the moment I tried it.
The sort of thing his page actually shows, e.g. "19:49:38" or whatever (at the time I tried it), is merely a string representation of that number, treating it as a number of hours and just dividing it up into minutes and seconds in the usual way. Which, I suppose, brings us to the second part of your question, i.e. how to convert a number of hours into an hours-minutes-seconds representation? But that is a simple matter, dealt with many times here. See NSNumber of seconds to Hours, minutes, seconds for example.
So, carrying on once again, I tried this:
CGFloat secs = MTC*3600;
NSDate* d = [NSDate dateWithTimeIntervalSince1970:secs];
NSDateFormatter* df = [NSDateFormatter new];
df.dateFormat = #"HH:mm:ss";
df.timeZone = [NSTimeZone timeZoneWithAbbreviation:#"GMT"];
NSString* result = [df stringFromDate:d];
NSLog(#"%#", result); // 20:10:20
...which is exactly the same as his web page was showing at that moment.
And here's a Swift version for those who would like to know what the "mean time" is on Mars right now:
let millis = Date().timeIntervalSince1970 * 1000
let JDUT = 2440587.5 + (millis / 86400000)
let JDTT = JDUT + (37 + 32.184) / 86400
let J2000Epoch = ( JDTT - 2451545 )
let MSD = (( J2000Epoch - 4.5 ) / 1.0274912517) + 44796.0 - 0.0009626
let MTC = (24 * MSD).truncatingRemainder(dividingBy: 24)
let d = Date(timeIntervalSince1970: MTC*3600)
let df = DateFormatter()
df.dateFormat = "HH:mm:ss"
df.timeZone = TimeZone(abbreviation: "GMT")!
df.string(from:d)

Convert day of the year to date [closed]

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

How to format time durations in Groovy?

I need to show time elapsed. I have the dates in following format.
Date1 = Thu May 23 10:10:10 EDT 2013
Date2 = Tue May 21 10:10:10 EDT 2013
I currently did TimeDuration duration=TimeCategory.minus(now,LaunchTime)
And my output shows something like 2 days, 23 minutes, 25.154 seconds
What I want to show instead of 2 days, 23 minutes, 25.154 seconds is something like 48:23:25(in hours and minutes).
You can do something like this to create a new TimeDuration with the days turned into hours:
import groovy.time.TimeDuration
import groovy.time.TimeCategory
date1 = Date.parseToStringDate( 'Thu May 23 10:10:10 EDT 2013' )
date2 = Date.parseToStringDate( 'Tue May 21 12:14:10 EDT 2013' )
// Normalize method to return a new TimeDuration
TimeDuration normalize( TimeDuration tc ) {
new TimeDuration( ( tc.days != 0 ? tc.days * 24 : 0 ) + tc.hours,
tc.minutes, tc.seconds, tc.millis )
}
// Then use the category to subtract the dates, and call normalize
TimeDuration normalized = use( groovy.time.TimeCategory ) {
normalize( date1 - date2 )
}
println normalized

How can I determine how many months, weeks and days have elapsed between two dates?

INFORMIX-SQL 7.32 (SE) Perform screen:
Let's say I have a start date of FEB-15-2010 and an end date of MAY-27-2010. I can calculate the number of elapsed days with 'let elapsed_days = end_date - start_date', but how can I convert these number of days into 3 months, 1 week and 5 days?
A raw calculation I've seen used, rounding every month to 31 days, since if you take the number of days in each month, add them up and divide them by 12 gives you 30.5 days average
per month, then taking elapsed days and dividing it by 31 produces 3.31 months, but this method is unacceptable for my needs.
This could probably stand some more rigorous testing, and there is certainly scope to tidy up the output (ie remove "0 months" substrings), but I think it gets you most of the way there...
CREATE PROCEDURE informix.datediff(d1 DATE, d2 DATE) RETURNING VARCHAR(255);
DEFINE yrcount, mthcount, wkcount, daycount INTEGER;
DEFINE dx DATE;
LET mthcount = ((YEAR(d2) - YEAR(d1)) * 12) + MONTH(d2) - MONTH(d1);
IF DAY(d1) <= DAY(d2) THEN
LET daycount = DAY(d2) - DAY(d1);
ELSE
LET dx = MDY(MONTH(d1),1,YEAR(d1))+1 UNITS MONTH;
LET daycount = dx - d1; -- elapsed days from last month
LET daycount = daycount + DAY(d2) - 1; -- elapsed days from this month
END IF;
LET yrcount = mthcount / 12;
LET mthcount = MOD(mthcount,12);
LET wkcount = daycount / 7;
LET daycount = MOD(daycount,7);
RETURN d1 || " - " || d2 || ": " || yrcount || " years, " || mthcount
|| " months, " || wkcount || " weeks and " || daycount || " days ";
END PROCEDURE;
ie:
execute procedure datediff(TODAY, "19/03/2011");
(expression) 21/06/2010 - 19/03/2011: 0 years, 9 months, 4 weeks and 0 days
execute procedure datediff(TODAY, "22/03/2011");
(expression) 21/06/2010 - 22/03/2011: 0 years, 9 months, 0 weeks and 1 days
execute procedure datediff("08/02/2010", "08/05/2011");
(expression) 08/02/2010 - 08/05/2011: 1 years, 3 months, 0 weeks and 0 days
execute procedure datediff("31/03/2010", TODAY);
(expression) 31/03/2010 - 21/06/2010: 0 years, 3 months, 3 weeks and 0 days
execute procedure datediff(TODAY-3, TODAY);
(expression) 18/06/2010 - 21/06/2010: 0 years, 0 months, 0 weeks and 3 days
execute procedure datediff(TODAY-33, TODAY);
(expression) 19/05/2010 - 21/06/2010: 0 years, 1 months, 0 weeks and 2 days

Resources