Java Converting date to epoch value produces false output

孤人 提交于 2019-12-23 18:57:36

问题


I am trying to convert the below date time string object into a unix epoch timestamp value. However, when i run the program i notice that it generates an epoch value of 1404461110000 which when i check on my ubuntu unix machine is Wed Aug 7 18:06:40 However in reality i am passing July 04 2014-07-04 04:05:10. I have a time zone of America/Toronto on my ubuntu machine but I don't think it should matter here ?

Java code:

            long epoch = 0;
            String str = "2014-07-04 04:05:10";   // UTC

            DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            Date datenew = df.parse(str);
            epoch = datenew.getTime();

            System.out.println(epoch); // prints 1404461110000

Ubuntu Linux 14.04

date -d@1404461110000

displays= Wed Aug 7 18:06:40 EDT 46475


回答1:


The issue is that you're not dealing with a unix timestamp when calling getTime() in Java. Unix timestamps are expressed in seconds since the epoch, while the values you're getting from Java are milliseconds since the epoch (Jan 01 1970), hence the difference.

It would have to be:

epoch = datenew.getTime() / 1000;

This should get you at least a couple of 10000 years closer. If you still see a difference after that, it's timezone-related, and can be accommodated for by specifying the timezone on your DateFormat instance.




回答2:


You need to tell Java that the timestamp is UTC, not just add a comment about it.

long epoch = 0;
String str = "2014-07-04 04:05:10";   // UTC

DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("UTC")); // assume UTC
Date datenew = df.parse(str);
epoch = datenew.getTime();

System.out.println(epoch);



回答3:


Joda-Time

FYI, here is the same kind of code but done in Joda-Time 2.4. The new java.time package in Java 8 (inspired by Joda-Time) could be used in a similar manner.

The java.util.Date and .Calendar classes are notoriously troublesome. Avoid them. Use either of the two libraries mentioned above.

Example Code

Your input string is close to standard ISO 8601 format, but not quite, missing the T in the middle and an offset from UTC. Joda-Time has a built-in formatter for parsing/generating in ISO 8601. So rather than define our own formatter, let's tweak the input String a bit, inserting the T.

String inputRaw = "2014-07-04 04:05:10";   // UTC
String input = inputRaw.replace( " ", "T" ); // Convert to standard ISO 8601 format.

Then we will tell the DateTime constructor to parse the String as being in UTC (zero offset). Unlike java.util.Date, a DateTime knows its own assigned time zone.

DateTime dateTimeUtc = new DateTime( input, DateTimeZone.UTC );

Easy to adjust to Toronto time, for fun or for debugging/sanity-check.

DateTime dateTimeToronto = dateTimeUtc.withZone( DateTimeZone.forID( "America/Toronto" ) );

Like java.util.Date, Joda-Time internally tracks time as a number of milliseconds since the Unix epoch (beginning of 1970) in UTC. That means using a 64-bit long rather than the usual 32-bit int. (By the way, java.time tracks nanoseconds.) So if we need seconds-since-unix-epoch, divide by one thousand.

long millisecondsSinceEpoch = dateTimeUtc.getMillis();  // Use a "long", not "int".
long secondsSinceEpoch = ( millisecondsSinceEpoch / 1000L );

Dump to console.

System.out.println( "input: " + input );
System.out.println( "dateTimeUtc: " + dateTimeUtc );
System.out.println( "dateTimeToronto: " + dateTimeToronto );
System.out.println( "millisecondsSinceEpoch: " + millisecondsSinceEpoch );
System.out.println( "secondsSinceEpoch: " + secondsSinceEpoch );

When run.

input: 2014-07-04T04:05:10
dateTimeUtc: 2014-07-04T04:05:10.000Z
dateTimeToronto: 2014-07-04T00:05:10.000-04:00
millisecondsSinceEpoch: 1404446710000
secondsSinceEpoch: 1404446710


来源:https://stackoverflow.com/questions/25277127/java-converting-date-to-epoch-value-produces-false-output

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!