-
Bug
-
Resolution: Not an Issue
-
P4
-
8, 11, 17, 21, 22, 23
-
generic
-
linux_ubuntu
ADDITIONAL SYSTEM INFORMATION :
$ java -version
openjdk version "21.0.2" 2024-01-16
OpenJDK Runtime Environment (build 21.0.2+13-Ubuntu-122.04.1)
OpenJDK 64-Bit Server VM (build 21.0.2+13-Ubuntu-122.04.1, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
If the argument of Files.setLastModifiedTime(file.toPath(), FileTime.fromMillis(millis)) is negative and contains milliseconds, the file becomes the timestamp "Jan 1 1970", i.e. filetime is asumed as `0L`
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Calendar cal = Calendar.getInstance();
cal.set(1960, 10-1, 12, 13, 25, 00);
long millis = cal.getTimeInMillis();
Files.setLastModifiedTime(file.toPath(), FileTime.fromMillis(millis));
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The timestamp of the file should be "Oct 12 1960 13:25:00".
ACTUAL -
The timestamp of the file is "Jan 1 1970 00:00:00".
---------- BEGIN SOURCE ----------
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.time.*;
import java.util.*;
public class FileTimesFromCalendar {
static long getCalendarMillis(int year) {
Calendar cal = Calendar.getInstance();
cal.set(year, 10-1, 12, 13, 25, 00);
return cal.getTimeInMillis();
}
static long getDateMillis(int year) {
return switch (year) {
case 1960 -> Date.parse("12 Oct 1960 13:25:00");
case 1980 -> Date.parse("12 Oct 1980 13:25:00");
default -> (new Date()).getTime();
};
}
static long getInstantMillis(int year) {
Instant instant = ZonedDateTime.of(year, 10, 12, 13, 25, 00, 0, ZoneId.of("CET")).toInstant();
return instant.toEpochMilli();
}
static void touch(long millis) throws IOException {
final File parent = new File("log/FileTimes"), file;
parent.mkdirs();
try (FileOutputStream out = new FileOutputStream(file = new File(parent, "FileTime"))) {
out.close();
Files.setLastModifiedTime(file.toPath(), FileTime.fromMillis(millis));
System.out.println("Date of file: "+new Date(file.lastModified()));
}
}
static void touch(Instant instant) throws IOException {
final File parent = new File("log/FileTimes"), file;
parent.mkdirs();
try (FileOutputStream out = new FileOutputStream(file = new File(parent, "FileTime"))) {
out.close();
Files.setLastModifiedTime(file.toPath(), FileTime.from(instant));
System.out.println("Date of file: "+new Date(file.lastModified()));
}
}
public static void main(String[] args) throws IOException, InterruptedException {
for (int i=0; i<3; i++) {
System.out.println("Negative Millis ...");
long millis = getDateMillis(1960);
System.out.println("Millies from Date: "+millis);
touch(millis);
millis = getCalendarMillis(1960);
System.out.println("Millies from Calendar: "+millis);
touch(millis);
long rmillis = millis / 1000 * 1000 - 1000;
System.out.println("Millies from Cal rounded down: "+rmillis);
touch(rmillis);
rmillis = Math.floorDiv(millis, 1000) * 1000;
System.out.println("Millies from floorDiv(Cal): "+rmillis);
touch(rmillis);
millis = getInstantMillis(1960);
System.out.println("Millies from Instant: "+millis);
touch(millis);
Instant instant = Instant.ofEpochSecond(-290950500L, 12345678L);
System.out.println("Millies from Instant with nanos: "+instant.toEpochMilli());
touch(instant.toEpochMilli());
System.out.println("touch from Instant directly: "+instant);
touch(instant);
System.out.println("Positive Millis ...");
millis = getDateMillis(1980);
System.out.println("Millies from Date: "+millis);
touch(millis);
millis = getCalendarMillis(1980);
System.out.println("Millies from Calendar: "+millis);
touch(millis);
rmillis = millis / 1000 * 1000;
System.out.println("Millies from Cal rounded down: "+rmillis);
touch(rmillis);
rmillis = Math.floorDiv(millis, 1000) * 1000;
System.out.println("Millies from floorDiv(Cal): "+rmillis);
touch(rmillis);
millis = getInstantMillis(1980);
System.out.println("Millies from Instant: "+millis);
touch(rmillis);
Thread.sleep(250);
System.out.println();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
// round down *absolutely* – for positive and negative values – to seconds with:
millis = Math.floorDiv(millis, 1000) * 1000;
FREQUENCY : always
$ java -version
openjdk version "21.0.2" 2024-01-16
OpenJDK Runtime Environment (build 21.0.2+13-Ubuntu-122.04.1)
OpenJDK 64-Bit Server VM (build 21.0.2+13-Ubuntu-122.04.1, mixed mode, sharing)
A DESCRIPTION OF THE PROBLEM :
If the argument of Files.setLastModifiedTime(file.toPath(), FileTime.fromMillis(millis)) is negative and contains milliseconds, the file becomes the timestamp "Jan 1 1970", i.e. filetime is asumed as `0L`
STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Calendar cal = Calendar.getInstance();
cal.set(1960, 10-1, 12, 13, 25, 00);
long millis = cal.getTimeInMillis();
Files.setLastModifiedTime(file.toPath(), FileTime.fromMillis(millis));
EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The timestamp of the file should be "Oct 12 1960 13:25:00".
ACTUAL -
The timestamp of the file is "Jan 1 1970 00:00:00".
---------- BEGIN SOURCE ----------
import java.io.*;
import java.nio.file.*;
import java.nio.file.attribute.*;
import java.time.*;
import java.util.*;
public class FileTimesFromCalendar {
static long getCalendarMillis(int year) {
Calendar cal = Calendar.getInstance();
cal.set(year, 10-1, 12, 13, 25, 00);
return cal.getTimeInMillis();
}
static long getDateMillis(int year) {
return switch (year) {
case 1960 -> Date.parse("12 Oct 1960 13:25:00");
case 1980 -> Date.parse("12 Oct 1980 13:25:00");
default -> (new Date()).getTime();
};
}
static long getInstantMillis(int year) {
Instant instant = ZonedDateTime.of(year, 10, 12, 13, 25, 00, 0, ZoneId.of("CET")).toInstant();
return instant.toEpochMilli();
}
static void touch(long millis) throws IOException {
final File parent = new File("log/FileTimes"), file;
parent.mkdirs();
try (FileOutputStream out = new FileOutputStream(file = new File(parent, "FileTime"))) {
out.close();
Files.setLastModifiedTime(file.toPath(), FileTime.fromMillis(millis));
System.out.println("Date of file: "+new Date(file.lastModified()));
}
}
static void touch(Instant instant) throws IOException {
final File parent = new File("log/FileTimes"), file;
parent.mkdirs();
try (FileOutputStream out = new FileOutputStream(file = new File(parent, "FileTime"))) {
out.close();
Files.setLastModifiedTime(file.toPath(), FileTime.from(instant));
System.out.println("Date of file: "+new Date(file.lastModified()));
}
}
public static void main(String[] args) throws IOException, InterruptedException {
for (int i=0; i<3; i++) {
System.out.println("Negative Millis ...");
long millis = getDateMillis(1960);
System.out.println("Millies from Date: "+millis);
touch(millis);
millis = getCalendarMillis(1960);
System.out.println("Millies from Calendar: "+millis);
touch(millis);
long rmillis = millis / 1000 * 1000 - 1000;
System.out.println("Millies from Cal rounded down: "+rmillis);
touch(rmillis);
rmillis = Math.floorDiv(millis, 1000) * 1000;
System.out.println("Millies from floorDiv(Cal): "+rmillis);
touch(rmillis);
millis = getInstantMillis(1960);
System.out.println("Millies from Instant: "+millis);
touch(millis);
Instant instant = Instant.ofEpochSecond(-290950500L, 12345678L);
System.out.println("Millies from Instant with nanos: "+instant.toEpochMilli());
touch(instant.toEpochMilli());
System.out.println("touch from Instant directly: "+instant);
touch(instant);
System.out.println("Positive Millis ...");
millis = getDateMillis(1980);
System.out.println("Millies from Date: "+millis);
touch(millis);
millis = getCalendarMillis(1980);
System.out.println("Millies from Calendar: "+millis);
touch(millis);
rmillis = millis / 1000 * 1000;
System.out.println("Millies from Cal rounded down: "+rmillis);
touch(rmillis);
rmillis = Math.floorDiv(millis, 1000) * 1000;
System.out.println("Millies from floorDiv(Cal): "+rmillis);
touch(rmillis);
millis = getInstantMillis(1980);
System.out.println("Millies from Instant: "+millis);
touch(rmillis);
Thread.sleep(250);
System.out.println();
}
}
}
---------- END SOURCE ----------
CUSTOMER SUBMITTED WORKAROUND :
// round down *absolutely* – for positive and negative values – to seconds with:
millis = Math.floorDiv(millis, 1000) * 1000;
FREQUENCY : always