A big part of the ugly code was related to date/time processing. Fortunately, I know Matt Johnson (find him on GitHub, Twitter, and Pluralsight).
I pinged him on Twitter, and he responded with with a Pull Request on the GitHub repo (which I merged in this morning). This was more than I was expecting, and it is greatly appreciated. Let's see how the code got better.
This code is currently on the "sunset" branch. Once I get the rest of the functionality in place, I'll merge this in with "master". The repo is jeremybytes/house-control on GitHub.
A Simple Change
The first change was pretty simple: just a format string when we're building the URL query string.
Having the format string for the date field is much cleaner than having the separate fields. (I'm kind of hoping that I would have made this change myself after looking at the code a bit more.)
But the other changes are things I would not have made on my own.
Better DateTime Parsing
As a reminder, we make a call to a service that returns the "sunset" time for a particular date and location. The time is returned as UTC, so when I use my location (in Southern California), the sunset time is something like "1:06:09 AM". We need to get this into local time somehow.
Yesterday, I described this code (so I won't do it again). I'll just leave it here as a reminder:
This takes the "1:06:09 AM" and turns it into "Jan 14, 2015 5:06:09 PM (Local)". It feels a bit cobbled together. And this is where Matt made things much better:
This condenses the 2 lines of code into a single line, and he left me a comment in GitHub to describe how this works:
When I wrote the original code, I looked at the overloads for the "DateTime.Parse" method, but I skimmed over the "DateTimeStyles" option because I wrongly assumed it wasn't what I needed. So this code has the same effect of specifying "UTC" for the incoming value and having the output still be "Local" time.
Better DateTime Creation
After getting this local time, I needed to replace the date portion with the value that was passed in to the method. The original code works, but it's pretty verbose:
Matt did a much better job with this:
This is much easier to read.
A Few Assumptions
Matt also made some notes when he submitted the pull request:
The assumption is that we want to use the computer's local time zone. And this is correct for what we have right now. I have an open issue to switch to UTC (or as I should have learned from Matt by now: DateTimeOffset).
I really don't have an answer to the second part of the assumption -- whether the service is expecting local date or UTC date as an input. Quite honestly, I'm not really worried about this. Generally sunset moves a few minutes a day (with the exception of switches to/from Daylight Saving Time), so I'm not worried whether the value is for "today" or "yesterday".
The Updated Method
You can see the pull request and comments on GitHub. And it's really easy to see the differences in the file as well. GitHub is pretty cool.
Here's the updated method:
There's still a lot to do to make things more readable, but the DateTime portions are looking pretty good right now.
More About Matt
Since I've been writing about the importance of talking to other developers, I should tell you how I met Matt. Quite honestly, I'm not quite sure how long I've known him. We first met at the Desert Code Camp in the Phoenix area several years back. (The first time I went out there was 2010, so it was sometime after that.)
Matt lived in the Phoenix area at the time, and we had some good conversations about date/time and RavenDB. I've been out there 10-12 times, so we've had a lot of chances to talk over the years. I've also attended his presentations during that time. He has since moved to the Redmond area to work for Microsoft. And I got to talk to him in person a few months back when I was up there for the Microsoft MVP Summit.
Based on our conversations, I know that he's worked *a lot* with the problems that come up when dealing with date/time -- whether related to time zones, DST adjustments, or keeping up with changing international time rules. And several months ago, he released a 6 hour course on Pluralsight: Date and Time Fundamentals.
It's great to have lots of friends in the developer community. Everyone has different experience with different technologies. When we build up our network, we usually end up with someone (and often several someones) we can contact for whatever problem we run into.
And the reverse is true. I have folks hit me up for help in areas that I know about. Just this week, one of my friends asked for assistance dealing with Tasks, asynchronous methods, and cancellation tokens (which was quite timely based on my current series of articles).
When we share our experience and knowledge with each other, our community grows stronger, and we all benefit with better code.