I am fairly new to programming, and I am have a difficult time with finishing a function to use in my homework assignment. Below I have the code for a function that is intended to take the month entered subtract 1 from it, and add the number of days that are entered. Returning the total number of day. For example, if m=4, days= 3, then it would go through the for loop and add 31+28+31+4. I would greatly appreciate your help. Thank you for your time!
function bday=daysinmonth(m, d)
array=[31 28 31 30 31 30 31 31 30 31 30 31];
for i=1:m-1
md=sum(array(i))
end
%sum=md+d
end
The array holding the number of days for each months is a good starting point. Then I don't understand why you iterate up to the month. What you are looking for is the sum up to the current month, so something like:
md=sum(array(1:m-1));
And yes, then you can add the current day to the accumulated days from previous months with
sum=md+d;
You also want to make sure, that you return the this number with
function sum=daysinmonth(m, d)
Related
I would like to ask how to create the sequence formula in order to repeate a date 10 times and do it for the whole year.
For example starting from 01/01/2022 to copy this date 10x then for 02/01/2022 to copy it 10x and so on. I started to use following formula for sequence:
=DATE(SEQUENCE(10,1,Year(B1),Month(B1),day(B1))
where B1 is 01/01/2022 and day and month are copied 10 times but the year is changing. Is there a way to do it to have the year same as well?
Thanks in advance.
You can take advantage of the fact that a date in excel is, conveniently, an integer number, and do it like that:
=INT((ROW(B1)-1)/10) + $B$1
That'll repeat the date entered in B1 10 times and than switch to next day, using the row number as a guide (so if you are not on the first row, you may need to add + X to the formula, where x is the row offset).
(Actual raw integer shown in D column for illustration, repeating every 3 rows instead of 10 to keep the screenshot smaller)
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.
i would like to simulate random timestamp data.
100 records in a day for one year.
How am I am able to do that?
when i set a:2013.01.01D00:00:00.000000000
100?a
the randomize data doesn't stay in a day.
thanks for your input
I am not sure, if this can be done easily. But you may generate 100 random timestamps for every day of 2013 in the next way
daysInYear: 365;
year: 2013.01.01D00:00:00.000000000;
//array of 365 elements, where every element represents corresponding date of year
dates: year + 01D * til daysInYear;
//array of 365 elements, where every element is an array of 100 random timestamps [0 .. 1D)
randomNanos: cut[100; (100 * daysInYear)?1D];
//array of 365 elements, where each element is an array of 100 random dateTimes for given day
result: dates + randomNanos;
//put all the dates in single array
raze result
The short version which does the same is below:
raze (2013.01.01D+01D * til 365) + cut[100; (100*365)?1D]
In order to simulate data for a single day, it's possible to generate random times (as floats less than one) and add them to the day you would like to generate data for. In this case:
D:2016.03.01;
D+100?1f
Will return 100 random times on 2016.03.01. If you want to generate data within a time range you can restrict the size of the float to something less than 1, or greater than a certain minimum value.
If you want to handle leap years... Not sure of a better way at the minute other than adding the max number of days onto the start of the year and asking whether it's the 31st. Adding on 366, it can either be 31st or 1st. If it's the 31st good, otherwise drop off the last date.
/e.g.
q)last 2015.01.01+til 365
2015.12.31
q)last 2016.01.01+til 365
2016.12.30 /we are a day short
q)
/return the dates and the number of days based on whether its a leap year
q)dd:$[31i~`dd$last d:2016.01.01+til 366;(366;d);(365;-1_d)]
q)/returns (366;2016.01.01 2016.01.02...)
q)/the actual logic below is pretty much the same as the other answer
q)raze{[n;dy;dt] dt+n cut(n*dy)?.z.N}[100;].dd
2016.01.01D16:06:53.957527121 2016.01.01D10:55:10.892935198 2016.01.01D15:36:..
I want to create a list of dates that go until the end of February. However, since the end of February changes from 28 to 29 depending on whether there's a leap year, I'm having trouble with how to consider both options.
Here's what I have so far:
date = datenum(years(i),12,01):1:datenum(years(i)+1,02,29);
This case, when run on a year that is not a leap year, ends up counting March 1st instead of ending on Feb. 28th.
Here's a little hack I came up with. You can check whether a year is a leap year quite easily by calculating the number of days between February 28 and March 1, like so:
datenum(years(i), 3, 1) - datenum(years(i), 2, 28)
Checking whether it's larger than 1 would indicate leap year. This 1 or 0 logical MATLAB convention leads to the second part of the hack: this is exactly the number of days you need to add to Feb 28: 0 if not leap year, 1 if leap year. Here, therefore, is the full hack:
date = datenum(years(i),12,01):datenum(years(i)+1,02, ...
28 + ((datenum(years(i)+1,3,1) - datenum(years(i)+1,2,28))>1) );
UPDATE / IMPROVEMENT:
Answer already accepted, but I came up with an even better solution. I didn't realize that datenum simply counts days. In this case, we can simply say that the last day of February is the day before March 1. This yields the following drastic simplification:
date = datenum(years(i),12,01):1:(datenum(years(i)+1,3,1)-1);
Datenum, for good or ill, takes negative and zero numbers. So the last day of February can be written:
datenum(2015, 3, 0)
With a comment explaining this madness, of course.
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?