Right now we are using the Winnovative PDF Converter software to create some reports. It’s a great tool that allows us to create a page in HTML then when we want to print it we just change it slightly to pull off the elements that should not be in the report.
Category: Tools
moment.js Tips n Tricks: Add Business Days
I needed a really quick and dirty way to add business days to a date. We are currently using moment.js to handle our date functionality. Here is the script I used:
public addBusinessDays(date, daysToAdd) {
var cnt = 0;
var tmpDate = moment(date);
while (cnt < daysToAdd) {
tmpDate = tmpDate.add('days', 1);
if (tmpDate.weekday() != moment().day("Sunday").weekday() && tmpDate.weekday() != moment().day("Saturday").weekday()) {
cnt = cnt + 1;
}
}
return tmpDate;
}
Updated:
Here is another way to handle the same thing that works better for large numbers. Full credit for this code goes to leonardosantos, I am reposting it so that I have a copy.
https://github.com/leonardosantos/momentjs-business/blob/master/momentjs-business.js
/**
* momentjs-business.js
* businessDiff (mStartDate)
* businessAdd (numberOfDays)
*/
(function () {
var moment;
moment = (typeof require !== "undefined" && require !== null) &&
!require.amd ? require("moment") : this.moment;
moment.fn.businessDiff = function (start) {
start = moment(start);
var end = this.clone();
var start_offset = start.day() - 7;
var end_offset = end.day();
var end_sunday = end.clone().subtract('d', end_offset);
var start_sunday = start.clone().subtract('d', start_offset);
var weeks = end_sunday.diff(start_sunday, 'days') / 7;
start_offset = Math.abs(start_offset);
if(start_offset == 7)
start_offset = 5;
else if(start_offset == 1)
start_offset = 0;
else
start_offset -= 2;
if(end_offset == 6)
end_offset--;
return weeks * 5 + start_offset + end_offset;
};
moment.fn.businessAdd = function (days) {
var d = this.clone().add('d', Math.floor(days / 5) * 7);
var remaining = days % 5;
while(remaining){
d.add('d', 1);
if(d.day() !== 0 && d.day() !== 6)
remaining--;
}
return d;
};
}).call(this);
SQL Tips n Tricks: Show events by time of day
Sometime times I get a request for data from a user that is actually fun to write. Today was one like that. The request from the user was to look at a series of event that occurred in the last week. It needed to be organized by day of week and time of day, by the half hour. Now that it is done I see a series of user reports in my future that takes this data and presents it for user review.
Here is what the data looks like after it is run:
| Num Files | Hour Of Day | Monday | Tuesday | Wednesday | Thursday | Friday | Saturday | Sunday |
| 23 | 6:00 | 6 | 2 | 4 | 7 | 2 | 1 | 1 |
| 80 | 6:30 | 12 | 17 | 19 | 17 | 10 | 5 | 0 |
| 616 | 7:00 | 86 | 132 | 129 | 137 | 115 | 17 | 0 |
| 1006 | 7:30 | 130 | 214 | 183 | 239 | 177 | 63 | 0 |
| 1963 | 8:00 | 285 | 374 | 449 | 390 | 389 | 76 | 0 |
| 2613 | 8:30 | 391 | 523 | 557 | 488 | 547 | 107 | 0 |
| 3529 | 9:00 | 588 | 750 | 690 | 744 | 648 | 109 | 0 |
| 3670 | 9:30 | 692 | 787 | 701 | 701 | 663 | 126 | 0 |
| 4214 | 10:00 | 699 | 944 | 851 | 847 | 738 | 133 | 2 |
| 4753 | 10:30 | 835 | 1004 | 902 | 955 | 938 | 118 | 1 |
| 4850 | 11:00 | 885 | 976 | 1019 | 917 | 954 | 96 | 3 |
| 4549 | 11:30 | 826 | 920 | 913 | 927 | 883 | 76 | 4 |
| 4504 | 12:00 | 821 | 866 | 869 | 1077 | 796 | 72 | 3 |
| 3792 | 12:30 | 694 | 757 | 793 | 765 | 705 | 75 | 3 |
| 4170 | 13:00 | 738 | 898 | 838 | 874 | 776 | 42 | 4 |
| 4333 | 13:30 | 908 | 891 | 868 | 814 | 801 | 49 | 2 |
| 4234 | 14:00 | 856 | 866 | 774 | 880 | 800 | 54 | 4 |
| 3948 | 14:30 | 733 | 833 | 787 | 788 | 767 | 36 | 4 |
| 4721 | 15:00 | 860 | 930 | 1121 | 890 | 882 | 36 | 2 |
| 5089 | 15:30 | 1111 | 1013 | 977 | 985 | 967 | 30 | 6 |
| 4773 | 16:00 | 962 | 974 | 937 | 874 | 1005 | 20 | 1 |
| 4753 | 16:30 | 944 | 971 | 986 | 865 | 947 | 38 | 2 |
| 4516 | 17:00 | 958 | 932 | 908 | 855 | 844 | 14 | 5 |
| 3519 | 17:30 | 716 | 727 | 696 | 687 | 679 | 13 | 1 |
| 2761 | 18:00 | 497 | 558 | 560 | 600 | 538 | 6 | 2 |
| 2129 | 18:30 | 447 | 446 | 424 | 432 | 377 | 3 | 0 |
| 852 | 19:00 | 183 | 180 | 184 | 150 | 151 | 4 | 0 |
| 53 | 19:30 | 9 | 8 | 15 | 7 | 8 | 6 | 0 |
| 24 | 20:00 | 9 | 1 | 8 | 0 | 2 | 1 | 3 |
| 6 | 20:30 | 0 | 0 | 0 | 0 | 1 | 0 | 5 |
| 19 | 21:00 | 2 | 4 | 4 | 6 | 2 | 0 | 1 |
| 4 | 21:30 | 1 | 0 | 1 | 0 | 0 | 0 | 2 |
Here is the SQL used to create it:
SELECT COUNT(Audit_Row_Id) AS NumberFilesRun
, RIGHT('00' + CAST(DATEPART(HOUR, FI.Audit_Create_Date) AS NVARCHAR(2)), 2)
+ ':'
+ (CASE WHEN DATEPART(MINUTE, FI.Audit_Create_Date) < 30 THEN '00' ELSE '30' END)
AS HourOfDay
, SUM(CASE WHEN datename(dw,Audit_Create_Date) = 'Monday' THEN 1 ELSE 0 END) AS Monday
, SUM(CASE WHEN datename(dw,Audit_Create_Date) = 'Tuesday' THEN 1 ELSE 0 END) AS Tuesday
, SUM(CASE WHEN datename(dw,Audit_Create_Date) = 'Wednesday' THEN 1 ELSE 0 END) AS Wednesday
, SUM(CASE WHEN datename(dw,Audit_Create_Date) = 'Thursday' THEN 1 ELSE 0 END) AS Thursday
, SUM(CASE WHEN datename(dw,Audit_Create_Date) = 'Friday' THEN 1 ELSE 0 END) AS Friday
, SUM(CASE WHEN datename(dw,Audit_Create_Date) = 'Saturday' THEN 1 ELSE 0 END) AS Saturday
, SUM(CASE WHEN datename(dw,Audit_Create_Date) = 'Sunday' THEN 1 ELSE 0 END) AS Sunday
FROM Audit_File_Information FI
WHERE Audit_Create_User = 'UniqueUserName'
AND Audit_Create_Date BETWEEN DATEADD(week, -2, GETDATE()) AND DATEADD(week, -1, GETDATE())
GROUP BY RIGHT('00'
+ CAST(DATEPART(HOUR, FI.Audit_Create_Date) AS NVARCHAR(2)), 2)
+ ':'
+ (CASE WHEN DATEPART(MINUTE, FI.Audit_Create_Date) < 30 THEN '00' ELSE '30' END)
ORDER BY 2
C# Tips n Tricks: ToTitleCase()
This is yet another simple tool that makes my life easier on occasion. All it does is capitalize every word in the string.
public static string ToTitleCase(this string str)
{
return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(str.ToLower());
}
C# Tips n Tricks: ToStringOrEmpty()
Here is another one of those extension methods that I carry with me from job to job. It’s a super simple one that just makes sense. So many times I am working with variables that need to be displayed as empty strings when they are null. The following code gets tiresome when generating dozens of strings in a row.
var displayString = value == null ? String.Empty : value.ToString();
Instead I added the following extension method for strings. Technically it works for any object that has ToString() implemented.
It means that I can simply show the following code which is much simpler and nicer and cleans my code up tremendously.
public static string ToStringOrEmpty(this object value)
{
return ((object)value ?? String.Empty).ToString();
}
Update: A former co-worker sent me this CodeProject Article: Chained null checks and the Maybe monad that takes this concept a bit further with a fairly complex set of extensions that allow cleaning up null checks even more. I’ll have to dig into it deeper.
Web Dev Tips n Tricks: Quick way to re-size windows for testing
I came across the Sizer App today which is wonderful. It installs a drop down list that appears when you right click on the bottom right hand corner of a window. It is a quick and easy way to re-size your window to whatever default you need to test in.