Category Archives: CodeProject

Date Counting

Ok so I kind of left my previous post a bit incomplete. I did so because there was that bit of date calculation that I wasn’t yet done resolving.

Remember this bit of code:

    int castedInterval = (int)interval;
    int minutes = (castedInterval / 60) % 60;

Ok so I will be honest I wasn’t that proud of the date calculations. Especially when you take into consideration that the full implementation looked something like:

-(NSString*) stringFromTimeInterval:(NSTimeInterval) interval
{
    int castedInterval = (int)interval;
    int years = (castedInterval / (((3600 * 24)*7)*52));
    int weeks = (castedInterval / ((3600 * 24)*7));
    int days = (castedInterval / (3600 * 24));
    int hours = (castedInterval / 3600);
    int minutes = (castedInterval / 60) % 60;
    int seconds = castedInterval % 60;

    if (hours >= 24){
        hours = hours - (days * 24);
    }

    if (days >= 7){
        days = days - (weeks * 7);
    }

    if(weeks >= 52) {
        weeks = weeks - (years * 52);
    }
    // removed other code
}

I shivered every time I read that code especially that god awful mess for determining the number of years. I looked at it a few times and thought to myself ok I could probably clean that up really nice with some constants or some defines.

Ok who am I kidding it still would look crap!

Regardless of it solving the problem I still hate ugly code. Mostly because I hear myself saying what I say to so many other software developers.

In five years when you and I are no longer working here we will be judged by the code we leave behind. For that future developer lets try and make his job easier.

Quick jump to my favorite research tool and five minutes later I come up with NSCalendar and NSDateComponents. You can get more information about them here and here.

The cool thing with NSCalendar is that it has a calculations method called components that allows me to pass in 2 NSDate objects to calculate the difference. It then returns back a NSDateComponents which I can then query to get the information I am looking for.

The following is the result:

-(NSString*) stringFromTimeInterval:(NSDate *) fromDate toDate:(NSDate *)toDate interval:(NSTimeInterval) interval
{
    NSCalendar *calender = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar];
    NSUInteger flags =  NSYearCalendarUnit | NSMonthCalendarUnit | NSWeekCalendarUnit | NSDayCalendarUnit | NSHourCalendarUnit | NSMinuteCalendarUnit | NSSecondCalendarUnit;
    
    NSDateComponents *dateComponents = [calender components:flags fromDate:[NSDate date] toDate:[self.dueDatePicker date] options:0];
    
    int years = [dateComponents year];
    int months = [dateComponents month];
    int weeks = [dateComponents week];
    int days = [dateComponents day];
    int hours = [dateComponents hour];
    int minutes = [dateComponents minute];
    int seconds = [dateComponents second];

    NSString* result = [[NSString alloc] init];
    if (years > 0) {
        result = (years > 1) ? [result stringByAppendingString:[NSString stringWithFormat:@"%d Years ", years]] : [result stringByAppendingString:[NSString stringWithFormat:@"%d Year ", years]];
    }
    
    if (months > 0) {
        result = (months > 1) ? [result stringByAppendingString:[NSString stringWithFormat:@"%d Months ", months]] : [result stringByAppendingString:[NSString stringWithFormat:@"%d Month ", months]];
    }
    
    if (weeks > 0) {
        result = (weeks > 1) ? [result stringByAppendingString:[NSString stringWithFormat:@"%d Weeks ", weeks]] : [result stringByAppendingString:[NSString stringWithFormat:@"%d Week ", weeks]];
    }
    
    if (days > 0) {
        result = (days > 1) ? [result stringByAppendingString:[NSString stringWithFormat:@"%d Days ", days]] : [result stringByAppendingString:[NSString stringWithFormat:@"%d Day ", days]];
    }
    
    if (hours > 0) {
        result = (hours > 1) ? [result stringByAppendingString:[NSString stringWithFormat:@"%d Hours ", hours]] : [result stringByAppendingString:[NSString stringWithFormat:@"%d Hour ", hours]];
    }
    
    if (minutes > 0) {
        result = (minutes > 1) ? [result stringByAppendingString:[NSString stringWithFormat:@"%d Minutes ", minutes]] : [result stringByAppendingString:[NSString stringWithFormat:@"%d Minute ", minutes]];
    }
    
    if ((years == 0) && (months == 0) && (weeks == 0)) {
        result = [result stringByAppendingString:[NSString stringWithFormat:@"%02d Seconds", seconds]];
    }
    
    return result;
}

I am still passing in NSTimeInterval because I am debating whether I want to include the calculation of milliseconds. I couldn’t find milliseconds as a component so the following bit of code should work if I want:

    NSTimeInterval actualTimer = interval;
    int castedInterval = (int)actualTimer;
    int millSeconds = ((double)actualTimer - castedInterval) / .01;

Happy coding everyone.

Ternary, tertiary, terinary …

What really is the correct spelling for this conditional operator?

Regardless of spelling I have never been that much a fan of its use. Most times that I have seen them used it was done so (in my opinion) to inflate the ego of the original programmer. We all have seen that code that solved what was most likely an easy problem but whose solution was done with complicated code.

My all time favorite of course is in conditional returns that always seem to resemble:

-(Boolean)crazyFunction{
    Boolean response = YES;

    // do some code processing...

    return (YES == response) ? YES : NO;
}

Before you jump to the end and flame the comments section please understand that I am not trying to discourage developers from ever using them. I believe at times they can come in rather handy when it comes to minimizing code so that it’s readability is maintained.

So now that I have given background to my opinions let me cover an example of how I used this in something that I am currently working on.

Problem – variable string building

I wanted to build a human readable string that actively demonstrates the difference between two different times.

Rules

  • It will display nothing when the difference is zero (0).
  • When the value is greater than 1 it will display a plural word.
  • When the value is equal to 1 it will display a singular version.

Fairly simple piece of code:

-(NSString*) stringFromTimeInterval:(NSTimeInterval) interval
{
    int castedInterval = (int)interval;
    int minutes = (castedInterval / 60) % 60;

    NSString* result = [[NSString alloc] init];
    if (minutes > 0) {
        if (minutes > 1) {
            result = [result stringByAppendingString:[NSString stringWithFormat:@"%d Minutes", minutes]];
        }
        else {
            result = [result stringByAppendingString:[NSString stringWithFormat:@"%d Minute", minutes]];
        }
    }

    return result;
}

If I was just doing one element of time this wouldn’t be that bad (my opinion). However, in my scenario I actually want to solve for years, weeks, days, hours and minutes. Which grows this small bit of code into something that just becomes unreadable and unmanageable.

To simplify and clean things up a bit I went with the following approach:

-(NSString*) stringFromTimeInterval:(NSTimeInterval) interval
{
    int castedInterval = (int)interval;
    int minutes = (castedInterval / 60) % 60;

    NSString* result = [[NSString alloc] init];
    if (minutes > 0) {
        result = (minutes > 1) ? [result stringByAppendingString:[NSString stringWithFormat:@"%d Minutes ", minutes]] : [result stringByAppendingString:[NSString stringWithFormat:@"%d Minute ", minutes]];
    }

    return result;
}

For each time element this saved me about 5 lines of code. I could have written the whole construction by embedding the current ternary operation inside of another however I felt by doing so I would have sacrificed readability of the code.

So when choosing to use a ternary operation make sure you remember the following:

With great power comes great responsibility – Uncle Ben

PS – Sprinkle in some comments.

Wednesday fun (maybe not)

All work and no play makes Jack Dennis a dull null boy.


rock picture

So one of the wonderful things about living here is that regardless the season we always have something great to do outside. During this time of year we go on a hike each Wednesday with a group of friends. Usually a great time to unwind and not have to think about anything work.

The trick or struggle always for me is to not think about anything work related and to just relax and enjoy the surroundings. I always enjoy spending the time outdoors whether on my bike, camping with family or on a hike like tonight. However without fail I am always working out a problem in my head at some point.

So I am proud to say that I actually made it through the hike without thinking about any problems I am currently working on. Breakthrough!!!

Tonight I created a new problem and worked on it during the hike. How is that for progress?

Recently I saw a demo on AngularJS and I was thinking on my hike how hard would it be to redo a jQuery plugin I did for displaying a twitter? The following is what I came up with:

Twitter Feed

  • {{tweet.text}}

For now I was thinking of something really simple. Once I got it pulling data from twitter and displaying something I knew that the rest would come easy.

So before I get deep into the code of AngularJs let me give a sample of the jQuery plugin I had done awhile back.

(function($){
    $.fn.minTweet = function(options) {
        var defaults = {
            tweets: 5,
            before: "
  • ", after: "
  • ", click: function() {}, onComplete: function() {} }; var tweetDeck = this; var options = $.extend(defaults, options); var tweetStack = new Array(); var init = function() { tweetDeck.each(function() { var obj = $(this); $.getJSON('http://api.twitter.com/1/statuses/user_timeline.json?callback=?&screen_name='+options.username+'&count='+options.tweets, function(data) { $.each(data, function(i, tweet) { tweetStack[i] = tweet; if(tweet.text !== undefined) { $(options.before+twitterTime(tweet.created_at)+options.after).appendTo($(obj)).attr('title', tweet.text).attr('id', i).bind('click.minTweet', twitterClick); } }); options.onComplete(); } ); }); }; var twitterClick = function() { if(tweetStack[$(this).attr('id')]) { options.click(tweetStack[$(this).attr('id')]); } }; var twitterTime = function(dts) { var now = new Date(); var then = new Date(dts); var diff = now - then; var second = 1000, minute = second * 60, hour = minute * 60, day = hour * 24, week = day * 7; if (isNaN(diff) || diff < 0) { return "Unkown"; // return blank string if unknown } else if (diff < minute) { return Math.floor(diff / second) + " seconds ago"; } else if (diff < minute * 2) { return "1 minute ago"; } else if (diff < hour) { return Math.floor(diff / minute) + " minutes ago"; } else if (diff < hour * 2) { return "1 hour ago"; } else if (diff < day) { return Math.floor(diff / hour) + " hours ago"; } else if (diff > day && diff < day * 2) { return "yesterday"; } else if (diff < week) { return Math.floor(diff / day) + " days ago"; } else if (diff > week && (diff < (week + day))) { return "a week ago"; } else { return Math.floor(diff / day) + " days ago"; } }; init(); }; })(jQuery);

    Probably not one of my greatest achievements but at the time of it's creation it was simple and served to solve a problem that I was working on at the time. Granted a majority of the code is that twitterTime() function it always bothered me that I should have been able to make it simpler.

    So would AngularJs save me or would my idea burn? Here is the javascript that I came up with.

    function twitterFeed($scope, $http) {
        var url = 'https://api.twitter.com/1/statuses/user_timeline.json?callback=?&screen_name=dniswhite&count=1';
        $http.jsonp(url).success(function(data,status){
            $scope.tweets = data;
        }).error(function(data) {
            $scope.tweets = "Request failed";
        });          
    }
    

    For now I hardcoded the name of the twitter feed being retrieved to mine. As I went to test it I could see that the error() function was being called. What could be wrong with my perfectly small piece of code?

    Fire off my old jQuery plugin and sure enough it's no longer working. Did I ever deploy this code and if so what site did I deploy it on? Somewhere out there is a site with a broken twitter feed.

    Take out the url from the code and lets give this a test.

    {"errors": [{"message": "The Twitter REST API v1 is no longer active. Please migrate to API v1.1. https://dev.twitter.com/docs/api/1.1/overview.", "code": 68}]}
    

    So it appears that for now I am temporarily stuck and I will need to resolve the new API (this requires OAuth). I hate to end blogs without resolution so instead let me say "Stay Tuned"

    Maybe it wasn't such a breakthrough to not think about problems during tonights hike.