Java SimpleDateFormat 添加随机零

Posted

技术标签:

【中文标题】Java SimpleDateFormat 添加随机零【英文标题】:Java SimpleDateFormat adds random zeroes 【发布时间】:2016-04-12 12:27:58 【问题描述】:

我有一个 android 应用程序,它以每秒数百行的速度输出 csv。每行都有一个时间戳,基本上是这样生成的:

String formatTimeStamp (Calendar cal)

    SimpleDateFormat timeFormatISO = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss")
    return timeFormatISO.format(cal.getTime());

一些时间戳(可能是千分之一)有意想不到的零,看起来像这样:

2016-04-12T09:0011:30

2016-04-12T0009:0011:30

2016-04-0012T09:11:30

这些事件似乎完全是任意的,至少 我没有看到他们背后的任何模式。有时两条错误的行之间有几千行,有时只有一条。

日期格式仅在代码中的一处定义。

编辑:

Here

是我上次运行的错误时间戳,仅供您查看。关于它们,我唯一注意到的是,日期元素前面总是有两个前导零,但从不在年份前面。

编辑 2:

问题已解决!结果证明 SimpleDateFormat 不是线程安全的,如果使用不当,会对字符串产生奇怪的影响。我不知道多线程会是一个问题,所以我没有在最初的问题中指出它。很抱歉造成混乱。

【问题讨论】:

您确定问题不是来自写入文件吗? SimpleDateFormat 经过明确的测试和证明。我还会在 IO 例程中进行调查。 不,我不确定。但我的 IO 例程也没有什么特别之处。我只是有一个 FileOutputStream,我在其中 .write(myString.getBytes()); 您可以尝试使用 log4j 或 System.out.println 将此字符串打印到日志文件。如果这工作正常,那么您将简单地意识到 SimpleDateFormat 不是问题。 @karpfen 你是从 csv 程序中复制粘贴的吗?如果是,那么程序就是问题。 【参考方案1】:

“原来 SimpleDateFormat 不是线程安全的,如果使用不当,会对字符串产生奇怪的影响。”

您在问题中向我们展示的代码是线程安全的,除非cal 的值是以非安全方式处理的。

SimpleDateFormat 实例是线程受限的;即没有其他线程可以看到它。因此,它的线程安全与否无关紧要。

我的猜测是,在您的实际代码中,您有多个线程试图共享一个 SimpleDateFormat 实例。 javadoc 说:

"建议为每个线程创建单独的格式实例。如果多个线程同时访问一个格式,必须对外同步。"

【讨论】:

是的,这正是问题所在。我没有在我的问题中包含这个,因为我想提供一个最小的例子并且认为它是无关紧要的。 @karpfen - 好吧,这是个坏主意。最小的例子是好的,但它们必须是实际显示问题行为的例子。【参考方案2】:

您需要在输入字符串中指定时区。 例如 : timeFormatISO.setTimeZone(TimeZone.getTimeZone("GMT"));

【讨论】:

以上是关于Java SimpleDateFormat 添加随机零的主要内容,如果未能解决你的问题,请参考以下文章

Java学习笔记4.6.2 格式化 - SimpleDateFormat类

为啥 Java 的 SimpleDateFormat 不是线程安全的? [复制]

Java多线程:SimpleDateFormat

java-SimpleDateFormat类

Java的SimpleDateFormat类

Java多线程SimpleDateFormat