Today is 18/12/2013.
I was testing this program where I wanted get another date by adding/substracting a number of milliseconds from System.currentMillis()
. It works well when I shift the date in decembre but it doesn't work correctly for some similar values. For example the following code gives me 2013 12 20
as the result! I wonder, no I still wonder how it could be possible! or I'm making a mistake?
public class CreateDirFiles {
public static final String PLOG_DIR = "ProductLog";
private SimpleDateFormat dateFormatter = new SimpleDateFormat();
public CreateDirFiles() {
}
public void createDayDir(Date date){
dateFormatter.applyPattern("YYYY");
String year = dateFormatter.format(date);
dateFormatter.applyPattern("MM");
String month = dateFormatter.format(date);
dateFormatter.applyPattern("dd");
String day = dateFormatter.format(date);
System.out.printf("%s %s %s\n", year, month, day);
}
public static void main(String... args){
CreateDirFiles dfc = new CreateDirFiles();
dfc.createDayDir(new Date(System.currentTimeMillis() -
((long)( 48 * 24 * 3600 * 1000)) ));
}
}
This is the problem:
((long)( 48 * 24 * 3600 * 1000))
That's doing all the arithmetic in 32 bits, and then converting the (now truncated, as the result is too large for an int
) result to a long
. You want:
48L * 24 * 3600 * 1000
where the L
suffix means that it'll use a long for the value 48.
However, you really don't want to do this at all - you want to use Joda Time which is a much nicer API for date/time work. You really don't want to have to mess around with the low level stuff at all.
LocalDate date = ...;
LocalDate twoDaysLater = date.minusDays(48);
If you really want to stick with the built-in API, then use Calendar
. At the very least use the TimeUnit
enum, which will allow:
long millisFor48Days = TimeUnit.DAYS.toMillis(48);
You also need to consider the time zone - while "today" may be the 18th of December for you, it isn't elsewhere in the world.