我正在实施用于格式化插入到数据库中的时间戳的功能。 对于此任务,现有解决方案使用SimpleDateFormat
。
由于SimpleDateFormat
不是线程安全的我将实现转换为java.time的使用。使用DateTimeFormatter设置“早期”日期的格式化时间戳
在这个过程中,我碰到了一些奇怪的行为,其中格式呈现不同的结果。 下面的示例显示在使用java.time
和1500-01-01 00:00:00
时如何使用SimpleDateFormat
格式化为"1500-01-10 00:12:12"
。
我不能承认为什么我们在使用java.time
时需要9天休息。 12:12
也来自哪里。
使用'1500-01-01 00:00:00'
将数据插入数据库。
使用数据库格式功能DATE_FORMAT
呈现 预期输出。
public static void main(String[] args) {
// The following ts value is obtained by debugging the Timestamp
// instance when reading data from MYSQL.
long ts = -14830995600000l;
String TSPATTERN = "yyyy-MM-dd HH:mm:ss";
Timestamp timestamp = new Timestamp(ts);
System.out.println(" ZoneId: " + ZoneId.systemDefault());
System.out.println("timestamp.toString() " + timestamp);
// java.time
DateTimeFormatter f = DateTimeFormatter.ofPattern(TSPATTERN).withZone(ZoneId.systemDefault());
String withJavaTime = f.format(timestamp.toInstant());
// Using SimpleDate format
SimpleDateFormat fdf = (SimpleDateFormat) SimpleDateFormat.getDateInstance();
fdf.applyPattern(TSPATTERN);
String withSDF = fdf.format(ts);
System.out.println(" With java.time: " + withJavaTime);
System.out.println("With SimpleDateFormat: " + withSDF);
// Running the above will print the following output
// Where does the 12:12 come from? and the 9 days?
// With java.time: 1500-01-10 00:12:12
// With SimpleDateFormat: 1500-01-01 00:00:00
}
我还可以看到一个发散的输出从数据库函数DATE_FORMAT比较时和JSR 310能这样不采取考虑ZoneOffsetTransition在JSR 310做数据库解释 ?
例如,格式化对应于“1899-12-31 01:00:00”的时间戳,使用JSR 310给出“1899-12-31 01:00:14”。 列出ZoneOffsetTransition为我的(ZoneId Europe /斯德哥尔摩)给出以下(不完整的清单),这可能解释为 14分钟。 Transition [Overlap at 1879-01-01T00:00 + 01:12:12 to +01:00:14] Transition [Overlap at 1900-01-01T00:00 + 01:00:14 to +01:00]
我试图找到一种方法来格式化时间戳,告诉JSR 310跳过使用这些数据,但目前为止没有成功。
感谢您的回答。我想可以归结为在处理1582以前的数据时不要使用JSR 310. 我们正在实现的功能是数据库数据的一般列表。我想在大多数情况下,用户希望 在SQL和工具中输入时看到相同的数据。即使数据库中的实际时间戳在这种情况下也是错误的。 – user1239974