I've been a zone leader with DZone since 2008, and I'm crazy about community. Every day I get to work with the best that JavaScript, HTML5, Android and iOS has to offer, creating apps that truly make at difference, as principal front-end architect at Avego. James is a DZone Zone Leader and has posted 639 posts at DZone. You can read more from them at their website. View Full User Profile

Thursday Code Puzzler: How Many Weekends?

09.12.2012
| 4761 views |
  • submit to reddit

Thursday is code puzzler day here at DZone. The idea is simple: solve the coding problem as efficiently as you can, in any language or framework that you find suitable.

Note: Even though there really is nothing stopping you from finding a solution to this on the internet, try to keep honest, and come up with your own answer.  It's all about the participation!

Do you have code puzzlers that you'd like to share with the DZone community?  If so, please submit here. 

How Many Weekends?

Write a function that takes two dates and returns the number of weekends between those dates. If either of the start or end dates is a weekend, you can count that. And whether it's a Saturday or Sunday (doesn't need to include both), it counts.

Catch up on all our previous puzzlers here.

Comments

Neeraj Khapre replied on Thu, 2012/09/13 - 4:49am

public class WeekendCalculater {

	public static void main(String[] args) throws ParseException {
		SimpleDateFormat sdf = new SimpleDateFormat("MM/dd/yyyy");

		Calendar startDate = Calendar.getInstance();
		startDate.setTime(sdf.parse("09/06/2012"));

		Calendar endDate = Calendar.getInstance();
		endDate.setTime(sdf.parse("09/09/2012"));

		System.out.println("Total no. of Weekends are : "
				+ calculateWeekends(startDate, endDate));
	}

	public static int calculateWeekends(Calendar startDate, Calendar endDate) {
		// Return 0 if startDate and endDate are same
		if (startDate.equals(endDate)) {
			return 0;
		}

		int weekend_count = 0;
		int count = 0;

		while (startDate.compareTo(endDate) == -1) {
			startDate.add(Calendar.DAY_OF_MONTH, 1);

			if (startDate.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY
					|| startDate.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY) {
				count++;
				if (count == 2) {
					weekend_count++;
					count = 0;
				}
			}
		}
		return weekend_count;
	}
}

Leandro Santos replied on Thu, 2012/09/13 - 10:32am

Here is the code in ruby:

 

class WeekendsCalculator
  attr_reader :days
  def initialize(start_at,end_at)
    @days = parse_range(start_at,end_at)
  end
  def parse_range(start_at, end_at)
    if start_at.is_a?(String) && end_at.is_a?(String)
      Date.parse(start_at)..Date.parse(end_at)
    elsif start_at.is_a?(Date) && end_at.is_a?(Date)
      start_at..end_at
    else
      raise "Start_at and end_at should be either strings or date objects"
    end
  end
  def weekends
    days.inject(0) do |weekends,day|
      weekends += 1 if day.saturday?
      weekends
    end
  end
end
c = WeekendsCalculator.new('2012-08-01', '2012-09-07')
puts "The number of weekends is #{c.weekends}"

Vijay Nathani replied on Thu, 2012/09/13 - 9:49pm

Groovy solution using open source library jodaTime.

import org.joda.time.*;
class ComputeWeekends {
	private def st, en;
	private int pre;
	private boolean isWeekend(date) { [DateTimeConstants.SATURDAY, DateTimeConstants.SUNDAY].contains(date.dayOfWeek().get())}
	private def gotoMiddleOfWeek(startOrEnd) {
		boolean lastDateWeekend = false
		while (st <= en ) {
			def d = startOrEnd?st:en
		    if (d.dayOfWeek().get() == DateTimeConstants.WEDNESDAY) return
			pre += (isWeekend(d) && !lastDateWeekend)?1:0
			lastDateWeekend = isWeekend(d)
			startOrEnd?(st=st.plusDays(1)):(en=en.minusDays(1))
		}
	}
	def weekendsBetween(start,end) {
		if (start > end) return 0
		(st, en, pre) = [ start, end, 0]
		gotoMiddleOfWeek(true)
		gotoMiddleOfWeek(false)
		Days.daysBetween(st,en).days / DateTimeConstants.DAYS_PER_WEEK + pre 
	}
}
println new ComputeWeekends().weekendsBetween(new DateMidnight(2012, 9, 4), new DateMidnight(2012, 9, 22)) //prints 3

ebenezer raj replied on Thu, 2012/09/13 - 2:04pm

In q { x:x[0]+til 1+x[1]-x[0]; x:x-`week$x; x[where x within (5 6)]:-1; x:?[(prev x)=-1;0;x]; count x[where x=-1] }[(2012.09.01;2012.09.13)] prints out 2

Joe Colburn replied on Thu, 2012/09/13 - 6:43pm

function weekends($date1, $date2) {
    $epoch1 = strtotime($date1);
    $epoch2 = strtotime($date2);
    $weekends = floor((($epoch2 - $epoch1) / 86400) / 7);
    if (substr(date("D", $epoch1), 0, 1) == "S") {
        $weekends++;
    }
    if (substr(date("D", $epoch2), 0, 1) == "S") {
        $weekends++;
    }

    return $weekends;
}

Vijay Nathani replied on Thu, 2012/09/13 - 9:51pm in response to: Joe Colburn

Will this code work for boundary conditions e.g. weekends between 8 and 9-Sep-2012?

Joe Colburn replied on Thu, 2012/09/13 - 11:47pm in response to: Vijay Nathani

Good question... If you mean when the first date is Sep 8 2012 and the second is Sep 9 2012, I believe it will fail, counting it as 2 weekends, but that should be the only failing scenario.  Good catch!

Vijay Nathani replied on Fri, 2012/09/14 - 12:10am in response to: Joe Colburn

Even when both start and end dates are the same weekend date e.g. 8-Sep-2012 , the code will fail.

If start date is after end date, then too the code fails.

If start date is 9-Sep-12 and end date is 16-Sep-12, then too the code fails.

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.