Netflix Interview Question
Senior Software Development EngineersCountry: United States
Interview Type: Phone Interview
public static void main(String args[]){
int moveBy = 30;
Date d = new Date();
Calendar c = Calendar.getInstance();
c.setTime(d);
for(int i=0;i<moveBy;i++){
c.add(c.DAY_OF_WEEK, 1);
while(c.get(c.DAY_OF_WEEK) == c.SATURDAY || c.get(c.DAY_OF_WEEK) == c.SUNDAY){
c.add(c.DAY_OF_WEEK, 1);
}
}
System.out.println("Business day for 5 days from now is "+c.getTime().toString());
}
this needs to be programmed without using existing Java Date and Calendar API..
for finding the business day, it's pretty easy, you can add business day to current day enum value and take a mod of 5, that will give the business day. However calculating date is hard because of weekends, holidays and variable number of days in months considerations.
I wrote a sample program assuming each month has 30 days but I don't think it's pretty consistent with future date.
import java.util.HashMap;
import java.util.Map;
/*
* Calculating day by adding business day to current day value and doing the % 5 to get the final business day. Doesn't take holidays into account.
* For date, first calculating number of weeks involved in business days by dividing it by 5 and then multiply the result with 2 to get total number of weekend days
* Then finalDate = (currentDate + numberoFWeekendDays + numberOfBusinessDays) % 30 -> Assuming every month has 30 days.
* Note: This implementation doesn't take Holidays into account
*
*/
public class FindDayOfWeek {
private Calendar currentDate = new Calendar(3, 8); // Setting the current day and date through constructor
Calendar futureCalendarDate = new Calendar();
public Calendar calculateDay(int n) {
int curDate = currentDate.getDate();
int curDay = currentDate.getDay();
//find number of weekend days included in the given business days
int numberOfWeeks = n / 5;
System.out.println("Number of weeks: " + numberOfWeeks);
int numberOfWeekendDays = numberOfWeeks * 2;
System.out.println("Number of weekend days: " + numberOfWeekendDays);
int tempFutureDate = (curDate + n + numberOfWeekendDays);
System.out.println("Value of temporary future date is: " + tempFutureDate);
//assuming every month has 30 days
int futureDate = tempFutureDate % 30;
System.out.println("Here is the future date: " + futureDate);
futureCalendarDate.setDate(futureDate);
int futureDay = (curDay + n) % 5; // Add number of business day to current day and take the remainder operator of 5
futureCalendarDate.setDay(futureDay);
System.out.println("Future day is: " + futureDay + " : " + futureCalendarDate.dayMap.get(futureDay));
return futureCalendarDate;
}
public static void main(String[] args) {
FindDayOfWeek findDayOfWeek = new FindDayOfWeek();
System.out.println("\nFUTURE DATE IS: " + findDayOfWeek.calculateDay(8));
System.out.println("----------------------");
FindDayOfWeek findDayOfWeek2 = new FindDayOfWeek();
System.out.println("\nFUTURE DATE IS: " + findDayOfWeek2.findFutureBusinessDay(8));
}
// Inner Class which represents a Date Object
private class Calendar {
private int day;
private int date;
private int month;
private int year;
private Map<Integer, String> dayMap = new HashMap<Integer, String>();
public Calendar() {
setDayMap();
}
public Calendar(int day, int date) {
this.day = day;
this.date = date;
setDayMap();
}
// Setting the Day names in the Hashmap
private void setDayMap() {
dayMap.put(1, "Monday");
dayMap.put(2, "Tuesday");
dayMap.put(3, "Wednesday");
dayMap.put(4, "Thursday");
dayMap.put(0, "Friday");
}
/**
* @return the day
*/
public int getDay() {
return day;
}
/**
* @param day the day to set
*/
public void setDay(int day) {
this.day = day;
}
/**
* @return the date
*/
public int getDate() {
return date;
}
/**
* @param date the date to set
*/
public void setDate(int date) {
this.date = date;
}
/**
* @return the month
*/
public int getMonth() {
return month;
}
/**
* @param month the month to set
*/
public void setMonth(int month) {
this.month = month;
}
/**
* @return the year
*/
public int getYear() {
return year;
}
/**
* @param year the year to set
*/
public void setYear(int year) {
this.year = year;
}
@Override
public String toString() {
return dayMap.get(getDay()) + " the " + getDate();
}
}
}
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
public class BusinessDays {
private static final long ONE_DAY = 1000L * 60 * 60 * 24;
private static final SimpleDateFormat FORMAT = new SimpleDateFormat(
"yyyy/MM/dd EEE");
public static Date getDateXBusinessDaysAfterAGivenDate(int numberOfBizDays,
Date refDate) {
// days to first Monday
int daysToFirstMonday = (8 - refDate.getDay()) % 7;
// biz days to first Monday
int bizDaysToFirstMonday = daysToFirstMonday <= 2 ? 0
: daysToFirstMonday - 2;
if (bizDaysToFirstMonday > numberOfBizDays) {
// won't reach Monday, so just add delta
return new Date(refDate.getTime() + numberOfBizDays * ONE_DAY);
} else {
// add weekends to every 5 biz days, and add weekend for the first week
int totalNumberOfDays = numberOfBizDays
+ (daysToFirstMonday - bizDaysToFirstMonday)
+ (numberOfBizDays - bizDaysToFirstMonday) / 5 * 2;
return new Date(refDate.getTime() + totalNumberOfDays * ONE_DAY);
}
}
public static Date getDateXBusinessDaysAfterAGivenDate_naive(
int numberOfBizDays, Date refDate) {
Calendar c = new GregorianCalendar();
c.setTime(refDate);
for (int i = 0; i < numberOfBizDays; i++) {
// skip weekends for free
while (c.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY
|| c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
c.add(Calendar.DATE, 1);
}
c.add(Calendar.DATE, 1);
}
// last skip
while (c.get(Calendar.DAY_OF_WEEK) == Calendar.SATURDAY
|| c.get(Calendar.DAY_OF_WEEK) == Calendar.SUNDAY) {
c.add(Calendar.DATE, 1);
}
return c.getTime();
}
public static void main(String[] args) {
Date refDate = new Date();
for (int i = 0; i < 7; i++) {
refDate = new Date(refDate.getTime() + ONE_DAY);
System.out.println("=======================");
System.out.println("reference date: " + FORMAT.format(refDate));
for (int j = 0; j < 15; j++) {
Date naiveDate = getDateXBusinessDaysAfterAGivenDate_naive(j,
refDate);
Date calcDate = getDateXBusinessDaysAfterAGivenDate(j, refDate);
if (!naiveDate.equals(calcDate)) {
System.out.println("***** WRONG ********");
}
System.out.println("naive \t" + j + " day(s) after: "
+ FORMAT.format(naiveDate));
System.out.println("calc \t" + j + " day(s) after: "
+ FORMAT.format(calcDate));
}
}
}
}
Here is my version of code, this is without using any Java API:
import java.util.HashMap;
import java.util.Map;
/*
* Calculating day by adding business day to current day value and doing the % 5 to get the final business day. Doesn't take holidays into account.
* For date, first calculating number of weeks involved in business days by dividing it by 5 and then multiply the result with 2 to get total number of weekend days
* Then finalDate = (currentDate + numberoFWeekendDays + numberOfBusinessDays) % 30 -> Assuming every month has 30 days.
* Note: This implementation doesn't take Holidays into account
*
*/
public class FindDayOfWeek {
private Calendar currentDate = new Calendar(0, 5); // Setting the current day and date through constructor
Calendar futureCalendarDate = new Calendar();
/*
* Backtrack the current day to immediate last Monday and then find number of weekends days from Monday to the last day of business date range
* To calculate final date, add current date, differential from current date to Monday, number of business days and weekends and take mod of 31
* For Business days, just add number of business day and take mod of 5
* @parameter integer
* @return Calendar
*
*/
public Calendar findFutureBusinessDay(int n) {
int curDay = currentDate.getDay();
int curDate = currentDate.getDate();
System.out.println("Current Day: " + currentDate.dayMap.get(curDay) + " the " + curDate);
System.out.println("Number of business days: " + n);
int futureDay = -1;
int futureDate = -1;
// handling boundary conditions
if(n < 0) {
System.out.println("Invalid number of business days provided, please provide a valid business day..");
futureCalendarDate.setDay(futureDay);
futureCalendarDate.setDate(futureDate);
return futureCalendarDate;
} else if(n == 0) {
futureDay = curDay;
futureDate = curDate;
futureCalendarDate.setDay(futureDay);
futureCalendarDate.setDate(futureDate);
return futureCalendarDate;
}
if(curDay > 0 && curDay < 6) { // this will take care of condition when current day is a weekend day
futureDay = curDay + n;
} else {
futureDay = n;
}
futureDay = futureDay % 5;
if(futureDay == 0) {
futureDay = 5; // if futureDay is zero => this implies it's a Friday so setting this to 5 as per my hash table mapping..
}
//difference between the hash map value of Monday and any other day, done to reset the cuurent day to May for calculation of number of weekends
int bufferDaysToMonday = curDay - 1;
int counter = bufferDaysToMonday + n; //adjusting counter to account for moving the current day to Monday
futureDate = curDate - bufferDaysToMonday; //moving the future date back to the immediate Monday in that week
// Calculating the number of weekend days falling in the given business days starting from Monday
int numberOfWeekendDays = (counter/5) * 2;
futureDate = futureDate + counter + numberOfWeekendDays;
//condition to handle when current date is a Saturday
if(curDay == 6) {
futureDate = futureDate - 1; // if current day is Saturday then subtract by 1 to account for only one weekend day for the current weekend
}
// assuming every month has 31 days
futureDate = futureDate % 31;
futureCalendarDate.setDay(futureDay);
futureCalendarDate.setDate(futureDate);
return futureCalendarDate;
}
public static void main(String[] args) {
FindDayOfWeek findDayOfWeek2 = new FindDayOfWeek();
System.out.println("\nFUTURE DATE IS: " + findDayOfWeek2.findFutureBusinessDay(27));
}
// Inner Class which represents a Date Object
private class Calendar {
private int day;
private int date;
private int month;
private int year;
private Map<Integer, String> dayMap = new HashMap<Integer, String>();
public Calendar() {
setDayMap();
}
public Calendar(int day, int date) {
this.day = day;
this.date = date;
setDayMap();
}
// Setting the Day name mappings in the Hashmap
private void setDayMap() {
dayMap.put(1, "Monday");
dayMap.put(2, "Tuesday");
dayMap.put(3, "Wednesday");
dayMap.put(4, "Thursday");
dayMap.put(5, "Friday");
dayMap.put(6, "Saturday");
dayMap.put(0, "Sunday");
dayMap.put(-1, "Garbage");
}
/**
* @return the day
*/
public int getDay() {
return day;
}
/**
* @param day the day to set
*/
public void setDay(int day) {
this.day = day;
}
/**
* @return the date
*/
public int getDate() {
return date;
}
/**
* @param date the date to set
*/
public void setDate(int date) {
this.date = date;
}
/**
* @return the month
*/
public int getMonth() {
return month;
}
/**
* @param month the month to set
*/
public void setMonth(int month) {
this.month = month;
}
/**
* @return the year
*/
public int getYear() {
return year;
}
/**
* @param year the year to set
*/
public void setYear(int year) {
this.year = year;
}
@Override
public String toString() {
return dayMap.get(getDay()) + " the " + getDate();
}
}
}
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;
/**
* @author nayaksu
*
*/
public class BusinessDate {
private static final Map<Integer, String> weekdays = new HashMap<Integer, String>(5);
private static final Map<Integer, String> weekends = new HashMap<Integer, String>(2);
BusinessDate() {
weekdays.put(1, "MONDAY");
weekdays.put(2, "TUESDAY");
weekdays.put(3, "WEDNESDAY");
weekdays.put(4, "THURSDAY");
weekdays.put(5, "FRIDAY");
weekends.put(6, "SATURDAY");
weekends.put(0, "SUNDAY");
}
/**
* @param args
*/
public static void main(String[] args) {
BusinessDate bd = new BusinessDate();
System.out.println("5 Business days from today is : "+ bd.business_days_from_now(5) );
}
private Date business_days_from_now(int noOfDays) {
Calendar expectedDate = Calendar.getInstance();
for (int i = 1; i <= noOfDays; ) {
expectedDate.add(Calendar.DATE, 1);
if (weekdays.containsKey(expectedDate.getTime().getDay())) {
i++;
}
}
return expectedDate.getTime();
}
}
import java.util.Calendar;
import java.util.Date;
public class Bizdate {
public Date bizDays;
public Bizdate (int nbrBizDaystoAdd){
bizDays= business_days_from_now(nbrBizDaystoAdd);
}
private Date business_days_from_now (int nbrtoAdd){
Calendar c = Calendar.getInstance();
int nbrWeeks = (nbrtoAdd / 5); //derive number of calendar weeks given biz days
int offsetDays = (nbrtoAdd % 5); //derive remainder
int totDays = nbrWeeks * 7 + offsetDays; //total calendar days required
c.add(c.DAY_OF_MONTH, totDays);
//make adjustments if new date falls on weekend
if (c.get(c.DAY_OF_WEEK) == c.SATURDAY){c.add(c.DAY_OF_WEEK, 2);}
if (c.get(c.DAY_OF_WEEK) == c.SUNDAY){c.add(c.DAY_OF_WEEK, 1);}
//generate requested date 'nbrtoAdd' business days from today and return
bizDays = new Date(c.get(c.YEAR) - 1900, c.get(c.MONTH), c.get(c.DATE));
return bizDays;
}
}
//TO TEST
import java.text.SimpleDateFormat;
import test.Bizdate;
public class Test{
public static void main(String[] args){
int nbrBizDays = 25; //set your value here
Bizdate testDate = new Bizdate(nbrBizDays);
SimpleDateFormat dformat = new SimpleDateFormat("MM.dd.yyyy");
String formattedDate = dformat.format(testDate.bizDays);
System.out.println(nbrBizDays + " business days from today would be " + formattedDate);
}
}
import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;
/**
* Created by mzeltser on 5/13/14.
*/
public class BusinessDays {
public static final long SEC_IN_DAY = 60*60*24*1000;
public static Date getDateBusinessDaysFromNow(int days){
Calendar cal = Calendar.getInstance();
// get current date day of the week
int curDay = cal.get(Calendar.DAY_OF_WEEK);
//get total days - business plus weekends
int totalDaysToAdd = days + BusinessDays.getWeekEndDays(curDay,days);
// calculate date from miliseconds
return new Date(System.currentTimeMillis()
+ totalDaysToAdd * BusinessDays.SEC_IN_DAY
);
}
public static int getWeekEndDays(int curDay, int addDays){
// number of full weeks
int weeksToGo = addDays/7;
// number of remaining days after full weeks
int daysToGo = addDays%7;
// each week adds 2 weekend days
int weekEndDays = weeksToGo *2;
// if current day falls on Fri or Sat add 1 or 2 weekends
if (curDay>=6) weekEndDays +=8-curDay;
// if current day plus remaining days crossing to next week add 2 weekend days
if (curDay+daysToGo >= 7) {
weekEndDays+=2;
}
int remainder = (addDays+weekEndDays)%7;
// after adding weekend days and business days if crossing week again add 2 more weekends
if (curDay+remainder >= 7 ) weekEndDays+=2;
return weekEndDays;
}
public static void main(String[] args){
System.out.println(BusinessDays.getDateBusinessDaysFromNow(14));
}
}
JS solution:
var businessDaysFromNow = function (date, numDays) {
var today = date.getDay();
if ((today === 0 || today === 6) && numDays > 0) numDays -= 1;
for (var i = 0; i <= numDays; i++) {
if (today === 6 || today === 0) numDays += 1;
today = today === 6 ? 0 : today + 1;
}
return new Date(date.getTime() + (numDays * 60 * 60 * 24 * 1000));
};
better solution:
var businessDaysFromNow = function (date, numDays) {
var today = date.getDay();
if ((today === 0 || today === 6) && numDays > 0) numDays -= 1;
for (var i = 0; i <= numDays; i++) {
if (today === 6 || today === 0) numDays += 1;
today = today === 6 ? 0 : today + 1;
}
return new Date(date.getTime() + (numDays * 60 * 60 * 24 * 1000));
};
var businessDaysFromNow = function (date, numDays) {
var today = date.getDay();
if ((today === 0 || today === 6) && numDays > 0) numDays -= 1;
for (var i = 0; i <= numDays; i++) {
if (today === 6 || today === 0) numDays += 1;
today = today === 6 ? 0 : today + 1;
}
return new Date(date.getTime() + (numDays * 60 * 60 * 24 * 1000));
};
Does not your numDays keep on increasing in the for loop? The exit variable of the for loop is increasing inside the for loop
public static Date getBusinessDayFromNow(int days) {
if (days < 0) {
throw new RuntimeException("Incorrect value passed. Day cannot be negative.");
}
Date d = new Date();
getToWeek(d, (days / 5) - 1);
int modDays = days % 6;
int daysFromSunday = d.getDay();
d.setTime(d.getTime() + modDays * 24 * 3600 * 1000);
daysFromSunday = d.getDay();
if (daysFromSunday == 0) {
d.setTime(d.getTime() + 1 * 24 * 3600 * 1000);
} else if (daysFromSunday == 6) {
d.setTime(d.getTime() + 2 * 24 * 3600 * 1000);
}
return d;
}
private static void getToWeek(Date d, int w) {
if (w > 0) {
d.setTime(d.getTime() + w * 7 * 24 * 3600 * 1000);
}
}
public static Date getBusinessDayFromNow(int days) {
if (days < 0) {
throw new RuntimeException("Incorrect value passed. Day cannot be negative.");
}
Date d = new Date();
getToWeek(d, (days / 5) - 1);
int modDays = days % 6;
int daysFromSunday = d.getDay();
d.setTime(d.getTime() + modDays * 24 * 3600 * 1000);
daysFromSunday = d.getDay();
if (daysFromSunday == 0) {
d.setTime(d.getTime() + 1 * 24 * 3600 * 1000);
} else if (daysFromSunday == 6) {
d.setTime(d.getTime() + 2 * 24 * 3600 * 1000);
}
return d;
}
private static void getToWeek(Date d, int w) {
if (w > 0) {
d.setTime(d.getTime() + w * 7 * 24 * 3600 * 1000);
}
}
(1)Assign a number to each day of a week, say, Sunday = 0, Monday = 1, ... , Saturday = 6, then we can assume today is X, where 0 <= X <= 6.
- uuuouou January 10, 2014(2)If X is 1,..,5, which means today is Monday,...,Friday, then the Nth business day from now will be (X + N)%5 + 1
(3)If X = 0 or X = 6, which means today is Sunday or Saturday, then the first business day from now will be Monday, just like today is Friday and X = 5.
(4)Let the Nth business day from now be Y, then from (2) and (3) we can conclude that Y = (((X > 0 && X < 6) ? X : 5) + N) % 5 + 1.