Generate a periodic value based on dates - iphone

I was hoping someone that is good with math and loops could help me out. I'm writing a program in Objective C where I need to come up with a way to do a cycle. If you don't know Objective C I would appreciate any help in pseudo code just to help me figure this out.
What I need is a scale that is based on two dates. I know this will be some sort of loop but not sure how to figure it out.
For instance, lets say that the first date is 5/25/1976 and the second date is 9/25/2009. Every 25 days there will be a "peak" so it's value will be 100. If I divide 23 in half I get 12 (rounded) so it would be the opposite or "valley" so it's numerical value would be 0. In other words on the 23rd day it would be at 100 but then on the 24th day it would start going back down and then bottom out 12 days later and then start the cycle back up and top out again at 23 days.
What I need to be able to do is find the numerical value for any given date in between any two given dates.
Thanks for any help you can offer!

value = 100*cos(2*pi*(numDays/25))
Or something like that.

Calculate the difference in days (optionally in fractional days too) between the starting point and the day you want the value for.
Divide by the cycle period (could be 23 or 25 according to the question).
Take the fractional part.
Apply the correct periodic function - for example, either sin() or cos(), appropriately scaled for the trigonometric functions (multiply the fraction by 2π).
You could simulate the shape by values out of a table describing the values indexed on days into the period (so you would use waveform[Δt mod period] to determine the value).

The NSDate class has a method timeIntervalSinceDate that will give you then number of seconds between two dates. You could calculate the number of days between two dates like this:
- (double) daysBetweenStart:(NSDate*)start end:(NSDate*)end
{
return [start timeIntervalSinceDate:end] / 86400.0; // seconds in a day
}
You could use this to compute a step function based on that:
- (double) someDescriptiveFunctionName:(NSDate*)date fromDate:(NSDate*)start
{
double days = [self daysBetweenStart:start end:date];
if ((int) days % 23 == 0)
return 100.0;
else
return 0.0;
}
This function returns 100.0 if the given date is between 23 and 24 days from the start, and 0.0 otherwise. You could substitute 23 for whatever period you like. I'm not sure if this is what you wanted, so clarify your question if it wasn't.
Disclaimer: This is Cocoa. Hopefully it's the same as iPhone Cocoa?

Related

UTC to GPS time for finding TOW in Simulink

for my project, I need to calculate TOW (Time of week) in Simulink. I know this can be achieved through conversion of UTC time to GPS time.
I have written a simple m-file in Matlab which does the action for me in Matlab as follow:
date_gps_int = 10000*y + 100*m + d
date_gps_str = int2str(date_gps_int)
date_gps_str_to_serial = datenum(date_gps_str,'yyyymmdd')
date_str_format = datestr(date_gps_str_to_serial,'dd-mmmm-yyyy')
Num_Days = daysact('06-jan-1980',date_str_format)
Num_Weeks = Num_Days/7
TOW = Num_Weeks - 1024
My first intention was to use this as a function in simulink. But apparently because of 'datenum' and 'datestr' it is not possible, since simulink does not handle strings.
Now I am wondering if anyone can help me with this issue. Is there any way to calculate TOW from the UTC date in Matlab without using those predefined functions?
I also tried to write an algorithm for calculating number of days since '6 January 1980' and then calculating number of weeks by dividing that by 7. But since I am not very familiar with leap year calculation and I don't really know the formula for these kinds of calculations, my result differs from real TOW.
I would appreciate if anybody can help me on this.
There are three formats handled by Matlab for time: formatted date strings - what datestr outputs -, serial date - scalar double, what datenum outputs - and date vectors (see datevec). Conversion functions work with these three, and the most convenient way to convert individual variables (year, month, etc) to a date is to build a date vector [yyyy mm dd HH MM SS].
date_gps_str_to_serial = datenum([y m d 0 0 0]); % midnight on day y-m-d
date_Jan_6_1980 = datenum([1980 01 06 0 0 0]); % midnight on Jan 6th, 1980
Num_Days = date_gps_str_to_serial - date_Jan_6_1980;
Now, beware of leap seconds...
GPS time is computed form the time elapsed since Jan 6th 1980. Take the number of seconds elapsed since that day, as measured by the satellites' atomic clocks, divide by (24*3600) to get a number of days, the remainder is the time of the day (in seconds since midnight).
But, once in a while, the International Earth Rotation and Reference Systems Service will decide that a day will last one second longer to accommodate for the slowing of Earth rotation. It may happen twice a year, on June 30th or December 31st. The calculation of GPS time is wrong, because it does not take into account that some days last 86401 seconds (so dividing by 24*3600 does not work) and will advance by 1 second with respect to UTC each time this happens. There has been 18 such days since Jan 6th 1980, so one should subtract 18 seconds from GPS time to find UTC time. The next time a leap second may be added is June 2019.

How to calculate fraction in datediff function in Tableau

I am not really an expert in Tableau. I have a need to calculate a timedifference in hours, but also want to see fraction of an hour. I am using Tableau 9.
I used the function
IF DATEDIFF("hour", [CL2_Start_Time_ST], [CL2_End_Time_ST]) > 8 then NULL
ELSE DATEDIFF("hour", [CL2_Start_Time_ST], [CL2_End_Time_ST])
END
If the time difference between CL2_Start_Time_ST and CL2_End_Time_ST is less than 1 hour (for example 30 minutes) the result is 0, but I want to see 0.5 in result.
I dont want to calculate in time difference in minutes since all my other calculations are in hours and hence it is easier to create a relative plot with other calculations.
Please help.
I found the answer to the above question. The simple formula below worked. I was using DIV function and that caused the issue.
IF DATEDIFF("hour", [CL2_Start_Time_ST], [CL2_End_Time_ST]) > 8 then NULL
ELSE (DATEDIFF("minute", [CL2_Start_Time_ST], [CL2_End_Time_ST])) / 60
END

How to do calculation on time values imported from Excel?

I have the following values in Excel:
Bed time 19:34:00
Get up time 07:04:00
Time in bed 11:30:00
Sleep start 19:42:00
Sleep end 07:00:00
I want to import them into MATLAB and do some calculation on these time values such as subtraction. The time values look like this after importing:
0.8153
0.2944
0.4792
0.8208
0.2917
and obviously doing calculation on them would be nonsense. Would any body help me with this issue? I have stuck with it for few days, and no progress yet.
Thanks in advance,
As assylias pointed out, these are fractions of days. You can use the datestr function to convert it to human-readable strings with formatting option conveniently.
e.g.:
datestr(0.2917, 'HH:MM:SS')
ans =
07:00:02
Calculations such as subtractions can be done on the raw values before
conversion.
E.g: get duration of sleep.
start = 0.8208
stop = 0.2917
datestr(stop-start, 'HH:MM')
ans =
11:18
Even works for intervals that span over midnight.

Iterate for loop by hour in MATLAB

I am writing a for loop to average 10 years of hourly measurements made on the hour. The dates of the measurements are recorded as MATLAB datenums.
I am trying to iterate through using 0.0417 as it is the datenum for 1AM 00/00/00 but it is adding in a couple of seconds of error each time I iterate.
Can anyone recommend a better way for me to iterate by hour?
date = a(:,1);
load = a(:,7);
%loop for each hour of the year
for i=0:0.0417:366
%set condition
%condition removes year from current date
c = date(:)-datenum(year(date(:)),0,0)==i;
%evaluate condition on load vector and find mean
X(i,2)=mean(load(c==1));
end
An hour has a duration of 1/24 day, not 0.0417. Use 1/24 and the precision is sufficient high for a year.
For an even higher precision, use something like datenum(y,1,1,1:24*365,0,0) to generate all timestamps.
To avoid error drift entirely, specify the index using integers, and divide the result down inside the loop:
for hour_index=1:365*24
hour_datenum = (hour_index - 1) / 24;
end

How to convert a MATLAB serial date number to a calendar date?

This is not so much a programming question as it is a desire for clarification to understand the way the Matlab serial date number format works. I'm referencing Matlab serial date numbers and I would like to know how to convert them into calendar dates using the simplest means possible. Many of the references out there only instruct how to work with these numbers within Matlab itself, but I want to be able to make sense of these by hand using arithmetic to derive the dates they represent without the use of Matlab (if this is even possible).
From the research I have done already, I do understand that a Matlab timestamp is essentially a count of the number of days since January 1, 0000 and that the floating point numbers appended to it further represent specific hours, minutes, etc. I'm not as clear on how these break down however. The reference information out there is not very informative nor comprehensive and I'm struggling to understand how it works.
Say I have the timestamp 735071.64930556. Could anybody provide me with a formula to be able to derive the calendar date that this represents, or guide me through the process to convert it? From a programming standpoint, my purpose for wanting to understand this is so I can eventually write a converter to be able to handle this format within the application I'm developing. For now though, I simply wish to understand how the process works.
Thanks
Use datevec or datestr:
>> datevec(735071.64930556)
ans =
1.0e+003 *
2.0120 0.0070 0.0210 0.0150 0.0350 0.0000
>> datestr(735071.64930556)
ans =
21-Jul-2012 15:35:00
What makes your question a little bit difficult to answer is mostly the leap year / leap second problem. If you expect date values to exist only over a limited range of values, the problem is somewhat simpler (actually I am not sure how Matlab deals with the "lost days" when the world went from Julian to Gregorian calendars, for example - see http://en.wikipedia.org/wiki/Conversion_between_Julian_and_Gregorian_calendars for a hint of what I am talking about).
The hours-minutes-seconds part is relatively easy. When you have
datevalue = 735071.64930556;
You can compute:
rem = datevalue - floor(datevalue);
hours = floor(24*rem);
rem = 24 * rem - hours;
minutes = floor( 60 * rem );
rem = 60 * rem - minutes;
seconds = 60 * rem;
To get the year / month / day, your best bet is to use some built in function in the language of your choice (for many examples, see http://www.epochconverter.com/epoch/daynumbers.php ), or knock yourself out and create some lookup tables. If you have the date of the first of every month, the lookup would be fast; and from 0 CE until today, that would be only 2013 * 12 entries - not a very large table. Such a table could be created in Matlab and exported...