GWT doesn't yet emulate Java's Calendar class, so you're stuck writing your own code if you need to perform date manipulations, like rounding a date to the nearest month or truncating the time portion. There are some gotchas here, like handling daylight savings time and leap years correctly, so the naive implementations of adding/subtracting milliseconds directly won't always work as expected.
Here's a class I wrote to help perform the date manipulations I need. If you're using JavaScript directly instead of GWT, the port is straightforward.
import java.util.Date;
/**
* Built-in date range provider for various predefined date categories.
* <p/>
* Justification for use of deprecated methods on {@link Date}:
* <br />
* This class uses deprecated methods of the Date class since it must be able to run on the client side
* and GWT hasn't emulated the {@link Calendar} class.
*/
public class CalendarUtils
{
private static final long MS_PER_SEC = 1000;
private static final long MS_PER_MIN = MS_PER_SEC * 60;
private static final long MS_PER_HOUR = MS_PER_MIN * 60;
private static final long MS_PER_DAY = MS_PER_HOUR * 24;
private CalendarUtils()
{
}
public static Date truncateToTime(Date date)
{
long time = date.getTime();
return new Date(time - truncateToDay(date).getTime());
}
public static Date truncateToDay(Date date)
{
return new Date(date.getYear(), date.getMonth(), date.getDate());
}
public static Date truncateToMonth(Date date)
{
return addDays(truncateToDay(date), 1 - date.getDate());
}
public static Date truncateToYear(Date date)
{
date = truncateToMonth(date);
date.setMonth(0);
return date;
}
public static Date addDays(Date date, int days)
{
Date newDate = new Date(date.getTime());
newDate.setDate(date.getDate() + days);
return newDate;
}
public static Date addMonths(Date date, int months)
{
for (; months < 0; months++)
{
Date roundedPriorMonth = addDays(truncateToMonth(date), -1);
date = addDays(date, -getDaysInMonth(roundedPriorMonth));
}
for (; months > 0; months--)
{
date = addDays(date, getDaysInMonth(date));
}
return date;
}
public static int getDaysInMonth(Date date)
{
return getDaysInMonth(date.getYear() + 1900, date.getMonth());
}
public static int getDaysInMonth(int year, int month)
{
switch (month)
{
case 1:
return (((year % 4) == 0 && (year % 100) != 0) || (year % 400) == 0) ? 29 : 28;
case 3:
case 5:
case 8:
case 10:
return 30;
default:
return 31;
}
}
/**
* Determines the number of days between two dates, always rounding up so a difference of 1 day 1 second
* yield a return value of 2.
*/
public static int dayDiff(Date endDate, Date startDate)
{
return (int)Math.ceil(((double)endDate.getTime() - startDate.getTime()) / MS_PER_DAY);
}
}