Google

Jan 7, 2013

Working with Java Calendar and Dates - coding Q&A



Q. Can you write a Java program to return the next week day for a given date?
A.

package com.myapp.accounting.util;

import java.util.Calendar;
import java.util.Date;

public class CashforecastingUtil {
 
 public static Date getNextWeekday(Date inputDate) {
  Calendar cal = Calendar.getInstance();
  cal.setTime(inputDate);
  int dayOfWeek = cal.get(Calendar.DAY_OF_WEEK);
  switch (dayOfWeek) {
  case Calendar.FRIDAY:
   cal.add(Calendar.DAY_OF_WEEK, 3);
   break;
  case Calendar.SATURDAY:
   cal.add(Calendar.DAY_OF_WEEK, 2);
   break;
  default:
   cal.add(Calendar.DAY_OF_WEEK, 1);
   break;
  }
  
  return cal.getTime();
 }

}


The unit test class will be something like


import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;

import junit.framework.Assert;

import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


public class CAshforecastingUtilTest {
 
 private final static Logger logger = LoggerFactory.getLogger(CAshforecastingUtilTest.class);
 
 
 @Test
 public void testGetNextWeekday() {
  SimpleDateFormat sdf = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss");
  Calendar cal = Calendar.getInstance();
  cal.set(2012,Calendar.DECEMBER,5);
  
  Date nextCalcWkday = CashforecastingUtil.getNextWeekday(cal.getTime());
  logger.info(sdf.format(nextCalcWkday));
  cal.set(2012,Calendar.DECEMBER,6);
  logger.info(sdf.format(cal.getTime()));
  Assert.assertTrue("Dates don't match-1", cal.getTime().equals(nextCalcWkday));
  
  nextCalcWkday = CashforecastingUtil.getNextWeekday(cal.getTime());
  cal.set(2012,Calendar.DECEMBER,7);
  Assert.assertTrue("Dates don't match-2", cal.getTime().equals(nextCalcWkday));
  
  nextCalcWkday = CashforecastingUtil.getNextWeekday(cal.getTime());
  cal.set(2012,Calendar.DECEMBER,10);
  Assert.assertTrue("Dates don't match-3", cal.getTime().equals(nextCalcWkday));
  
  cal.set(2012,Calendar.DECEMBER,8);
  nextCalcWkday = CashforecastingUtil.getNextWeekday(cal.getTime());
  cal.set(2012,Calendar.DECEMBER,10);
  Assert.assertTrue("Dates don't match-4", cal.getTime().equals(nextCalcWkday));
  
  cal.set(2012,Calendar.DECEMBER,9);
  nextCalcWkday = CashforecastingUtil.getNextWeekday(cal.getTime());
  cal.set(2012,Calendar.DECEMBER,10);
  Assert.assertTrue("Dates don't match-5", cal.getTime().equals(nextCalcWkday));
  
  nextCalcWkday = CashforecastingUtil.getNextWeekday(cal.getTime());
  cal.set(2012,Calendar.DECEMBER,11);
  Assert.assertTrue("Dates don't match-6", cal.getTime().equals(nextCalcWkday));
  
  nextCalcWkday = CashforecastingUtil.getNextWeekday(cal.getTime());
  cal.set(2012,Calendar.DECEMBER,12);
  Assert.assertTrue("Dates don't match-7", cal.getTime().equals(nextCalcWkday));
  
  nextCalcWkday = CashforecastingUtil.getNextWeekday(cal.getTime());
  cal.set(2012,Calendar.DECEMBER,13);
  Assert.assertTrue("Dates don't match-8", cal.getTime().equals(nextCalcWkday));
 }

}

Note that the Calendar.DECEMBER is used instead of 12 for the month as the months are zero based. So, it is 11 for Decemebr. If you have to perform lots of date manipulation, then use the Joda library, which is more intuitive and easier to work with. 

Q. Why are there two Date classes in Java -- one in java.util package and another in java.sql package?

A java.util.Date represents date and time of a day, whereas java.sql.Date only represents a date without the time. java.sql.Time, only represents a time of day, and java.sql.Timestamp represents both date and time

Q. Can you write a function to compare two given dates and return the difference between the two dates in number of days?
A. This where the new Joda date library introduced in java 7 shines.

Step 1: Write the function that takes two dates and return the difference in days. The assumption is to ignore the time and reset both times to midnight.

package com.myapp.util;

import java.util.Calendar;
import java.util.Date;

import org.joda.time.DateTime;
import org.joda.time.Days;


public class MyAppUtil {
 
  
 /**
  * returns the number of days between two given dates
  * @param currentDate
  * @param curOrFutureDate
  * @return
  */
 public static int diffDays(Date currentDate, Date curOrFutureDate) {
  if(currentDate == null || curOrFutureDate == null){
   throw new IllegalArgumentException("Dates to be compared cannot be null! date1=" + currentDate + ", date2=" + curOrFutureDate );
  }
  
  if(curOrFutureDate.before(currentDate)) {
   throw new IllegalArgumentException("The curOrFutureDate cannot be bfore currentDate. date1=" + currentDate + ", date2=" + curOrFutureDate );
  }
  
  currentDate = resetTimeToMidnight(currentDate);
  curOrFutureDate = resetTimeToMidnight(curOrFutureDate);
  
  return Days.daysBetween(new DateTime(currentDate), new DateTime(curOrFutureDate)).getDays();
 }
 
 
 private static Date resetTimeToMidnight(Date inputDate){
  Calendar cal = Calendar.getInstance();
  cal.setTime(inputDate);
  cal.set(Calendar.HOUR_OF_DAY, 00);
  cal.set(Calendar.MINUTE, 00);
  cal.set(Calendar.SECOND, 00);
  cal.set(Calendar.MILLISECOND, 00);
  return cal.getTime();
 }

}



Step 2:

package com.myapp.util;

import java.util.Calendar;
import java.util.Date;

import junit.framework.Assert;

import org.junit.Test;

public class MyAppUtilTest {
 
 
 @Test
 public void testDiffDays() {
  Date now = new Date();
  
  Calendar cal = Calendar.getInstance();
  cal.setTime(now);
  
  cal.add(Calendar.DAY_OF_MONTH, -1);
  cal.set(Calendar.HOUR_OF_DAY, 00);
  Date yesterday = cal.getTime();
  
  cal.add(Calendar.DAY_OF_MONTH, -2);
  cal.set(Calendar.HOUR_OF_DAY, 5);
  Date _3daysAgo = cal.getTime();
  
  cal.add(Calendar.DAY_OF_MONTH, -4);
  cal.set(Calendar.HOUR_OF_DAY, 15);
  Date _7daysAgo = cal.getTime();
  
  Assert.assertEquals(0, MyAppUtil.diffDays(now, now));
  Assert.assertEquals(1, MyAppUtil.diffDays(yesterday,now));
  Assert.assertEquals(3, MyAppUtil.diffDays(_3daysAgo,now));
  Assert.assertEquals(7, MyAppUtil.diffDays(_7daysAgo,now));
  Assert.assertEquals(4, MyAppUtil.diffDays(_7daysAgo,_3daysAgo));
 }
 
 
 @Test(expected=IllegalArgumentException.class)
 public void testNegative1DiffDays() {
  Date now = new Date();
  
  Calendar cal = Calendar.getInstance();
  cal.setTime(now);
  
  cal.add(Calendar.DAY_OF_MONTH, -1);
  cal.set(Calendar.HOUR_OF_DAY, 00);
  Date yesterday = cal.getTime();
  
  Assert.assertEquals(1, MyAppUtil.diffDays(now,yesterday));
 }
 
 @Test(expected=IllegalArgumentException.class)
 public void testNegative2DiffDays() {
  Date now = new Date();
  
  Assert.assertEquals(1, MyAppUtil.diffDays(now,null));
 }

}


Note: Working with dates can be tricky and you will need to consider things like:

1. Time zones. 2. Day light savings.

Labels: ,

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home