2017-10-06 873 views
3

我正在实施用于格式化插入到数据库中的时间戳的功能。 对于此任务,现有解决方案使用SimpleDateFormat
由于SimpleDateFormat不是线程安全的我将实现转换为java.time的使用。使用DateTimeFormatter设置“早期”日期的格式化时间戳

在这个过程中,我碰到了一些奇怪的行为,其中格式呈现不同的结果。 下面的示例显示在使用java.time1500-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跳过使用这些数据,但目前为止没有成功。

+0

感谢您的回答。我想可以归结为在处理1582以前的数据时不要使用JSR 310. 我们正在实现的功能是数据库数据的一般列表。我想在大多数情况下,用户希望 在SQL和工具中输入时看到相同的数据。即使数据库中的实际时间戳在这种情况下也是错误的。 – user1239974

回答

0

代替SimpleDateFormat,您可以使用线程安全的FastDateFormat。

+2

这个问题不是关于'SimpleDateFormat'的替代方法 - 它还提到代码正在迁移到'java.time' API(它比'FastDateFormat'更新并且也是线程安全的),所以这个答案真的没有解决问题中提到的问题。 – 2017-10-06 14:20:40