自纪元以来将时间戳转换为毫秒

时间:2013-08-17 09:14:37

标签: java timestamp jodatime simpledateformat epoch

目前我正在逐行读取数据文件。每行都有一个时间戳,格式为 dd / MM / yyyy HH:mm:ss“ 自纪元以来,我需要将其转换为毫秒。我试过两种方式

1>使用标准库

timestamp  = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss", Locale.ENGLISH).parse(ddMMyyyy + " " + HHmmss);
return timestamp.getTime();

2 - ;这是使用Joda-Time Library

jiffy = format.parseMillis(ddMMyyyy + " " + HHmmss);

在分析之后,我发现方法一非常昂贵,而方法二比第一方便宜但价格昂贵。第一个占用Aprox 1600ms的CPU时间,第二个占用1100ms的CPU时间。

问题 -

1>有没有更好的图书馆哪个不那么贵?

2 - ;如果没有标准库,有人可以指向转换逻辑吗?我试过谷歌搜索但没有成功。这个网站上的公式很少,但它们不起作用或者让它们调用它们就不够简单了。

由于

**

添加有关问题的更多详细信息

**

ok ..在这里添加更多细节。 测试运行是1000万条记录。每行都有时间戳,自纪元以来需要转换为毫秒。

以下是我尝试的三个版本的代码。

1>使用Joda-Time - 迄今为止最好的结果,但不能接受。在时间转换中花费了26.9%的时间。

long jiffy = 0;
public double getTime( String ddMMyyyy, String HHmmss) throws ParseException
{       
    jiffy = format.parseMillis(ddMMyyyy + " " + HHmmss);
    return jiffy/1000;
}

这是分析 http://postimg.org/image/bvrt3esgr/

2 - ;使用SimpleTimeFormat java类。 如果我再次使用同一个对象,那么执行此任务需要36.1%。

private long timestamp;
public static final SimpleDateFormat SDF = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss",Locale.ENGLISH);
long jiffy = 0;

public double getTime( String ddMMyyyy, String HHmmss) throws ParseException
{
    timestamp = SDF.parse(ddMMyyyy + " " + HHmmss).getTime();
    return timestamp;
}

这是个人资料 http://postimg.org/image/72iua8x9j/ 3 GT;使用SimpleTimeFormat java类。 如果创建新对象,则执行此任务需要51.6%。

public long getTimei( String ddMMyyyy, String HHmmss) throws ParseException
{
    timestamp  = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss", Locale.ENGLISH).parse(ddMMyyyy + " " + HHmmss);
    return timestamp.getTime();
}

这是个人资料 postimg.org/image/rnp2m1c2r /

现在我的问题仍然相同???

1>有没有更好的图书馆哪个不那么贵?

2 - ;如果没有标准库,有人可以指向转换逻辑吗?我试过谷歌搜索但没有成功。这个网站上的公式很少,但它们不起作用或者让它们调用它们就不够简单了。

2 个答案:

答案 0 :(得分:4)

  

有没有更好的图书馆不是那么贵?

你很可能每次都不应该创建一个新的SimpleDateFormat而你忘记首先预热代码。我建议你在忽略前10,000次运行后至少运行2秒钟。

或者可能是你将(ns)纳秒与(ms)毫秒混淆了。

public static final SimpleDateFormat SDF = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss", Locale.ENGLISH);
static {
    SDF.setTimeZone(TimeZone.getTimeZone("GMT"));
}

public static void main(String[] args) throws Exception {
    String dateTime = SDF.format(new Date());

    long start = 0;
    int warmup = 10000;
    int runs = 1000000;
    for (int i = -warmup; i < runs; i++) {
        if (i == 0)
            start = System.nanoTime();
        long time = SDF.parse(dateTime).getTime();
        if (time < 0) throw new AssertionError();
    }
    long time = System.nanoTime() - start;
    System.out.printf("The average time to parse the current time was %,d nano-seconds%n", time / runs);
}

打印

The average time to parse the current time was 1,250 nano-seconds

如果1250纳秒不够快,你可以编写自己的解析器。我见过的最快的是100纳秒。

答案 1 :(得分:0)

java.time

处理此类时间转换的现代方法是使用java.time框架。我不知道它在执行速度或垃圾生成方面的表现如何,但它应该被考虑在内。

java.time框架内置于Java 8及更高版本中。这些类取代了旧的麻烦日期时间类,例如java.util.Date.Calendar和&amp; java.text.SimpleDateFormatJoda-Time团队还建议迁移到java.time。

要了解详情,请参阅Oracle Tutorial。并搜索Stack Overflow以获取许多示例和解释。

大部分java.time功能都被反向移植到Java 6&amp; ThreeTen-Backport中的7,并在ThreeTenABP中进一步适应Android。

示例代码

您的问题无法解决时区问题。因此,我假设您的输入字符串适用于UTC,并使用Instant类。对于其他时区,请搜索ZonedDateTime的堆栈溢出。

Instant类表示UTC时间轴上的一个时刻,分辨率高达纳秒。它的toEpochMilli方法生成一个long整数(64位),计算自UTC 1970年第一个时刻以来的毫秒数。请注意,此方法可能会丢失数据,因为当截断到毫秒时,任何纳秒都会被删除。

DateTimeFormatter formatter = DateTimeFormatter.ofPattern( "dd/MM/uuuu HH:mm:ss" );
Instant instant = Instant.parse( yourInputStringGoesHere , formatter );
long millisecondsSinceEpochOf1970 = instant.toEpochMilli();