We can use fbusdate to get the first business day of a month:
Date = fbusdate(Year, Month);
However, how do we get the first business day of a week?
As an example, during the week that I'm posting this, Monday 09/07/2017 was a holiday in the US:
isbusday(736942) % = 0
How do I determine that the first business day for this week would be the next day 736943?
I'm not aware of a builtin function that returns the first working day of a week, but you can obtain it by requesting the next working day after Sunday:
busdate(736941); % 736941 = Sunday 09/03/2017
Your desired fbusdateweek function can be done in one line using just the function weekday to get the first Sunday of the week then busdate to get the next business day after that:
dn = 736942; % Date number for any day in a week
Date = busdate(dn-weekday(dn)+1);
Note: busdate uses the function holidays by default to get all holidays and special nontrading days for the New York Stock Exchange. If necessary, you can define an alternate set of holidays for busdate to use as follows:
holidayArray = ...; % Some set of date numbers, vectors, or datetimes
Date = busdate(dn-weekday(dn)+1, 1, holidayArray);
This way you can define a set of localized holidays.
Solved it. Here is a function that is based on the answer of #m7913d:
function Busday = fbusdateweek(date)
% Return the first business day after Sunday
% 'date' is a datenum input
dperiod = date-6:date;
sundays = weekday(dperiod)==1;
sunday = find(sundays==1,1,'first');
datesunday = dperiod(sunday);
% -->
Busday = busdate(datesunday);
end
Related
How can I in a smart way get the first business day of a month after the weekend?
To get the first business day of the month (given dateInput), we can do:
firstBusdayMonth = fbusdate(year(dateInput),month(dateInput));
As an example, for November, using the above function will return Thursday November 1 as the first business day. However, the first business day of the month after the first weekend is Monday November 5. How can I get this latter date?
Notes:
The weekend does not have to be in the same month.
If the Monday is not a working day, then I would like it to return the next business day
This function will do the trick. Here is the logic:
Create a datetime array for all days in the given month.
Get the day numbers.
Create a logical array, true from the first Monday onwards (so after the first weekend, accounting for the last day of the previous month being a Sunday).
Create another logical array using isbusday to exclude Mondays which aren't working days.
Finding the first day number where these two logical arrays are true, therefore the first business day after the weekend.
Code:
function d = fbusdateAferWE( y, m )
% Inputs: y = year, m = month
% Outputs: day of the month, first business day after weekend
% Create array of days for the given month
dates = datetime( y, m, 1 ):days(1):datetime( y, m, eomday( y, m ) );
% Get the weekday numbers to find first Monday, 1 = Sunday
dayNum = weekday( dates );
% Create the logical array to determine days from first Monday
afterFirstWeekend = ( cumsum(dayNum==2) > 0 ).';
% Get first day which is afterFirstWeekend and a business day.
d = find( afterFirstWeekend & isbusday( dates ), 1 );
end
You could probably speed this up (although it will be pretty rapid already) by not looking at the whole month, but say just 2 weeks. I used eomday to get the last day of the month, which means I don't have to make assumptions about a low number of holiday days in the first week or anything.
Edit: Working with datenum speeds it up by half (C/O JohnAndrews):
function d = fbusdateAferWE( y, m )
% Inputs: y = year, m = month
% Outputs: day of the month, first business day after weekend
% Create array of days for (first 2 weeks of) the given month
dates = datenum(datetime(y,m,1)):datenum(datetime(y,m,eomday(y,m)))-14;
% Get the weekday numbers to find first Monday, 1 = Sunday
dayNum = weekday( dates );
% Create the logical array to determine days from first Monday
afterFirstWeekend = ( cumsum(dayNum==2) > 0 ).';
% Get first day which is afterFirstWeekend and a business day.
d = find( afterFirstWeekend & isbusday( dates ), 1 );
end
I would add something like this after your statement:
[DayNumber, DayName] = weekday(firstBusdayMonth);
if DayNumber > 2
day = 10 - DayNumber;
else
This works because 'weekday' will return a number between 1 (Sunday) and 7 (Saturday).
The fbusdate() function will never return a 1 or 7, so we can ignore those cases.
If weekday(fbusdate()) == 2, the first is on a Monday and the firstBusdayMonth variable doesn't need to be changed.
If weekday(firstBusdayMonth) returns between 2 and 6, we need to skip to the next week, so we subtract the weekday value from 10 to find the next Monday.
It might not be the most elegant solution, but should work.
I want to write a matlab code to get which day is the first day of year and also get n and display which is the nth day of that year.
And also i don't know why it can not compare a(for example sat) and w(i)
(W=[sat,sun,....,fri]
Please help me I really can't make it work!
This is what I have done so far:
First=input('sat,sun,...,fri');
day=('a number between 1and 365');
day=mod(day,7);
w=[sat,sun,....,fri];
for i=1:7
if first==w(i)
disp(mod(i+day,7))
end
end
Note the syntax in the code below. I noticed you had quite a lot of errors in your syntax. Also, I recommend you use datenumand datestr as in the code below. Run help datenum and help datestr to get more information about the functions.
% User selects a year as a double
year = input('Select a year: ');
% the first day of that year as a value
date = datenum([num2str(year),'-01-01']);
% Get the name of the first day and diplay it
first = datestr(date,'dddd');
disp(['The first day of ', num2str(year), ' was a ', first])
% get nth day from user
day = input('Choose a number between 1 and 365: ');
% Add this value to the value of 1st jan on the selected year
newDate = date + day-1;
% Turn this date into a string and display it
nth = datestr(newDate,'dddd-dd-mmmm');
disp(['Day ', num2str(day),' of ', num2str(year), ' was ', nth])
Is it possible to create a vector automatically or progressively with dates. I want to ask the user about the starting date and the final date and I'd to fill a vector with the dates and the ones between both.
so abstractly:
"what is the first date?" '...' firstDate = '...' --> "what is the final date?" '...' finalDate='...'
and following, I'd like to fill in a vector all of the dates between firstDate and finalDate. is this possible in Matlab, and how? Is there a function to use?
You can use linspace after the user input:
%// prompt and user input
prompt1 = 'What is the first date? (yyyy-MM-dd)\n';
prompt2 = 'What is the last date? (yyyy-MM-dd)\n';
startDate = datenum(input(prompt1,'s'),'yyyy-mm-dd')
endDate = datenum(input(prompt2,'s'),'yyyy-mm-dd')
% number of days
numdays = endDate-startDate
% array of dates
alldays = linspace(startDate,endDate,numdays)
DateString = datestr(alldays, 'mm/dd/yyyy')
For the input 1989-07-01 and 1989-07-07 it will return:
DateString =
07/01/1989
07/02/1989
07/03/1989
07/04/1989
07/05/1989
07/07/1989
Dates can be called using datevec, datestr, datenum etc. datenum will be your best bet, since you can then create your vector using
DateVector = datenum(firstDate):datenum(finalDate);
This will create a vector containing dates per day. The way back is to say datestr(DateVector)
I have a dataset for which I have extracted the date at which an event occurred. The date is in the format of MMDDYY although MatLab does not show leading zeros so often it's MDDYY.
Is there a method to find the mean or median (I could use either) date? median works fine when there is an odd number of days but for even numbers I believe it is averaging the two middle ones which doesn't produce sensible values. I've been trying to convert the dates to a MatLab format with regexp and put it back together but I haven't gotten it to work. Thanks
dates=[32381 41081 40581 32381 32981 41081 40981 40581];
You can use datenum to convert dates to a serial date number (1 at 01/01/0000, 2 at 02/01/0000, 367 at 01/01/0001, etc.):
strDate='27112011';
numDate = datenum(strDate,'ddmmyyyy')
Any arithmetic operation can then be performed on these date numbers, like taking a mean or median:
mean(numDates)
median(numDates)
The only problem here, is that you don't have your dates in a string type, but as numbers. Luckily datenum also accepts numeric input, but you'll have to give the day, month and year separated in a vector:
numDate = datenum([year month day])
or as rows in a matrix if you have multiple timestamps.
So for your specified example data:
dates=[32381 41081 40581 32381 32981 41081 40981 40581];
years = mod(dates,100);
dates = (dates-years)./100;
days = mod(dates,100);
months = (dates-days)./100;
years = years + 1900; % set the years to the 20th century
numDates = datenum([years(:) months(:) days(:)]);
fprintf('The mean date is %s\n', datestr(mean(numDates)));
fprintf('The median date is %s\n', datestr(median(numDates)));
In this example I converted the resulting mean and median back to a readable date format using datestr, which takes the serial date number as input.
Try this:
dates=[32381 41081 40581 32381 32981 41081 40981 40581];
d=zeros(1,length(dates));
for i=1:length(dates)
d(i)=datenum(num2str(dates(i)),'ddmmyy');
end
m=mean(d);
m_str=datestr(m,'dd.mm.yy')
I hope this info to be useful, regards
Store the dates as YYMMDD, rather than as MMDDYY. This has the useful side effect that the numeric order of the dates is also the chronological order.
Here is the pseudo-code for a function that you could write.
foreach date:
year = date % 100
date = (date - year) / 100
day = date % 100
date = (date - day) / 100
month = date
newdate = year * 100 * 100 + month * 100 + day
end for
Once you have the dates in YYMMDD format, then find the median (numerically), and this is also the median chronologically.
You see above how to present dates as numbers.
I will add no your issue of finding median of the list. The default matlab median function will average the two middle values when there are an even number of values.
But you can do it yourself! Try this:
dates; % is your array of dates in numeric form
sdates = sort(dates);
mediandate = sdates(round((length(sdates)+1)/2));
This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Calculate date from week number
Given Year, Month,Day and the Week number, is it possible to get the Date?
e.g. Year = 2010
Month =Jan
Day = Sun
WeekNumber = 3
output : 2010-01-10
I am trying it in c#
Thanks
I would make it like this:
int Year = 2010;
int Month = 1; //Jan=1, Feb=2, ...
int Day = 0; //Sun=0, Mon=1, ...
int WeekNumber = 3; // greater than 0
DateTime dateValue = new DateTime(Year, Month, 1);
int firstDay = (int)dateValue.DayOfWeek;
dateValue = dateValue.AddDays(Day - firstDay + (WeekNumber - 1) * 7);
I don't think there's something for such date calculations in plain .NET BCL. But there are libraries that can help you, see i.e. Fluent DateTime. Using this library, you can try something like that:
var firstWeekInYearBeginning = new DateTime(2010, 1, 2).Previous(DayOfWeek.Monday); // note 2 to not miss a week if the year begins on Monday
var expectedDate = 3.Weeks().From(firstWeekInYearBeginning);
Based on the APIs here, don't this its possible to initialize a DateTime Object from the information given. You would need to develop an algorithm to get the exact date of the year. A simple strategy would be to get the first Day of the month and based on that, find first Monday of the month. This is the start of WeekNumber 1 for that month, and you can locate your required Week by simpl loop and locate the exact date. You would then know the calendar date you are interested in.
BTW: I am assuming WeekNumber of a year/month starts from the first Monday of that Year/Month. Someone please correct me if I am wrong.
Maybe you should check out System.Globalization.Calendar class. It might be useful.