Archive

Posts Tagged ‘C#’

PayDay: Time Frequencies

July 29th, 2010 Eric Murano Comments off

This the first of many posts about the implementation of PayDay, the software that I’m writing to help me with my personal finances.  I’ve been working on the project for a couple of months and one of the first things that I worked on was frequencies for recurring income and expenses.

One of the fundamental concepts in PayDay is the idea of a recurring income or expense.  I need to represent, for example, a monthly income, a weekly train ticket or a fortnightly gym membership.  These bills or income occur every so often, but the every-so-often is different for each one.

Not only that but a recurring item (from now on whenever I say ‘item’ I mean income or expense) has its own start date.  Two monthly items, while they occur as often as each other, might start on different days of the month.  My car loan comes out on the 16th but I’m paid on the 14th, for example.  Also frequencies aren’t always as simple as daily, weekly or monthly because you might want to represent things like ‘every second Tuesday’ or ‘the 14th of the month unless it’s on a weekend then the last Friday before the 14th’.

To implement the functionality of frequencies I considered creating an enum (enumerated type) with all possible types of frequencies.  The problem with this approach is that there are an infinite number of possible frequencies that you can have for a recurring event.  Most things fit into the common frequencies like weekly and monthly, but there are other events whose occurrences have to be specifically determined.  Take, for example, the schedule for being paid monthly.  Most employers will pay on the 14th or 15th of the month except if that date occurs on a weekend or a Monday, in which case the employee will be paid on the Friday so that they have money for that weekend.

Now I can’t think up all possible types of frequencies, yet I want to be able to support new types of frequencies without too much modification.  I could, theoretically, make a frequency engine that you supply parameters and rules to define your frequency but that’s too much work for people who aren’t developers.  Imagine PayDay asking you to “define the parameters of the frequency of this expense” … yeah I wouldn’t use software that asked me to do that!

I need to implement a few common ones and get on with the rest of the application.  I do, though, want to be able to introduce new frequencies later on but also I’d like anyone that writes software that uses the PayDay library to be able to invent their own frequencies without having to touch the PayDay library’s source code.

To accommodate this I created an interface that any class that wants to offer frequency information needs to implement.  I called it ITimeFrequency and it had two methods to implement:


/// Given a date when the event happens,
/// return the date of the next occurrence
DateTime NextOccurence(DateTime occurrence);

/// Given a date when the event happens,
/// return the date of the previous occurrence
DateTime PreviousOccurence(DateTime occurrence);

I really wanted to keep the interface lean. There originally was another method in the interface that returns all the dates of occurrences between a start and end date, but all concrete classes implementing the interface would have the same code for that method I decided to put that method into a static class called TimeFrequency:


public static List<DateTime> OccurrencesInDateRange(
    ITimeFrequency freq,
    DateTime fromDate,
    DateTime toDate
)

So whenever you call TimeFrequency.OccurencesInDateRange(), it’s calling NextOccurence of the ITimeFrequency passed to it to figure out the dates of the occurrencies

I created concrete classes that implement the ITimeFrequency interface: daily, weekly, monthly, yearly and fortnightly.

The general idea with all this is that if you have an event that occurs regularly, you can figure out when that event occurs from when it started onwards. So if I have a weekly event that started on the 26th of July, 2010, I know that the next occurrence will be 2nd of August, 2010 and the next occurrence is the 9th of August and so on. The NextOccurrence() method defined in the ITimeFrequency interface is what calculates what the date of the next occurrence will be. Though the application will not try to calculate occurrences that occur too far into the future, it will calculate all occurrences that occur in the date range that the user is viewing.

After the ITimeFrequency interface and it’s concrete classes was written I hit a snag with the monthly frequency. The issue was that calendar months have different numbers of days, 28, 29, 30 and 31. If something starts on the 31st the next month, unless it’s August, will have less days in it and therefore the next occurrence needs to be the last day of the month; except when the subsequent occurrence is calculated it will not be on the 31st, it will be on either the 30th, 29th or 28th, depending on the month.

Here’s an example: I have a monthly event that starts on the 31st of August. The second occurrence will be the 30th of September. This is because the monthly frequency knows that there is no 31st of September so it chooses the 30th, which is September’s last day. The third occurrence is then calculated but because NextOccurrence() only goes off the date of the previous occurrence, 30th of September in this case, it doesn’t know that the event really should occur on the 31st of October and it erroneously chooses the 30th of October.

What ends up happening is the day the occurrences are meant to happen on eventually go to the 28th. Once the occurrences hit February on a non-leap year that’s it.

So the monthly frequency really needed to have an occurrence day.  The day of the month when an occurrence should happen if the month has that many days. If it doesn’t then the last day of the month is selected. The occurrence day is supplied in the constructor of the monthly frequency object.

Giving the month frequency an occurrence day introduced another issue. If you create a monthly frequency with an occurrence day, then you call it’s NextOccurrence() method with a date that has a day that is different to the monthly frequency’s occurrence day, the method not return a date that is one month after, it will return the next time the occurrence day occurs.

For example: I create a monthly frequency with an occurrence day of the 12th. I then call its NextOccurrence() method with a parameter of the 15th of July, the answer will not be the 15th of August, it will be the 12th of August. Now this is exactly how NextOccurrence() should work. It has given you the correct answer; the next occurrence of the 12th after the 15th of July is the 12th of August, but if I have a recurring item that starts on the 15th yet I’ve declared that it occurs on the 12th, I need a way to tell the user that the dates and frequency they’ve chosen are inconsistent.  To do this the code that calls NextOccurrence() needs to call another method that checks to see if the start date is counted as an occurrence.

/// Is the given date a valid occurrence
bool IsValidOccurence(DateTime occurrence)

Now it’s possible for the recurring item code to check to see if an item’s start date should be counted as an occurrence.

I’ve really tried to make the frequency code open for all kinds of frequencies. The only restriction I have is that the smallest unit of time frequencies can work with is a day. For this application I didn’t want to have sub-day frequencies like hourly and every-minute.

My next post about PayDay I’ll talk about how I’ve dealt with representing money.

PayDay: My new development project

July 8th, 2010 Eric Murano 1 comment

Note: I originally called the project ‘PayCycle’ but since this is the name of an existing commercial product from Australia.

In my last post I wrote about how I’m managing my finances by using some simple maths in Microsoft Excel.  As a way to learn C# and .Net I’ve started writing the logic of the spreadsheets into a simple desktop application.  I’ll also be extending the features of the application to help with forecasting how much non-fixed cost bills will cost in the future.  Things like car repairs and how much you spend on lunch at work.

I’m calling the software PayCycle since the central idea is your pay cycle and how your budgeting revolves around how much and how often you’re paid. Since finding out there is already a product out there called PayCycle I’ve decided to name the software ‘PayDay’.

I could keep using my Excel files to organise my budget if I didn’t have the urge to have a software project to tinker with in my spare time.  The project deals with money (which I’ve found is more involved than just using numeric data types), with time periods and frequencies (yearly, monthly etc) in what appears to be straight forward from the 10,000 foot view but ongoing work will reveal the devils in the detail.

The project will initially deliver a desktop application that uses WPF for the user interface, WiX for the installation project and NUnit for unit testing. I’ll be using both SharpDevelop and Visual C# Express as IDEs.  SharpDevelop because it has integrated NUnit support along with WiX integration.  Visual C# Express because is has WYSIWYG for WPF.  I would have used Visual Studio as it does everything I need but I can’t afford the license fee right now so.

SharpDevelop will contain the library project which is where the business logic of the software will be.  This is the project with the unit tests.  The windows application project will be in Visual C# Express and it will reference the built DLL file that the library project produces.  Hopefully there will be no surprises with debugging!

Once the desktop application is up and running I’ll look into writing a web based version.  With this intention in mind I’ll be very careful with how I write the core of the software.  I can not have any business logic in the WPF project. One of the lucky benefits of having two different IDEs is that there’s a clear delineation between the ‘display’ and the ‘logic/model’.

I’ll post new articles about my progress.  I’ll write about design decisions and problems I encounter.  I’ve already started programming so there are already things about money, currency and time frequencies that I’d like to share.

My next post will a little boring; it’s a walk through of the spread sheets I use for personal budgeting.  It will give you an understanding about what I’m trying to achieve with the software.