2

I'm reading JSON from a third party URL. In that JSON data I found this timestamp starttime: 1522899000000 (on 4/5/2018 -> 5th April 2018)...I thought that it is Unix timestamp and tried to convert but it said Year 1912 :-). What timestamp is this? I'm reading this JSON from my Java app. How do I convert it to Java datetime?

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
Junior Dev
  • 23
  • 3
  • Divide it by 1000... (it's in ms) to get a Unix timestamp, that gives `2018-04-05 03:30:00 UTC` :-) Number of seconds since 1970. Or use it as it is in Java[script]. – Déjà vu Apr 05 '18 at 04:43
  • `date --date='@1522899000'` – Scary Wombat Apr 05 '18 at 04:44
  • I think it's Unix but in milliseconds so divide it by 1k and try it ? – d-coder Apr 05 '18 at 04:44
  • Tried to convert how? Please edit the question to include some code – OneCricketeer Apr 05 '18 at 04:47
  • Worked...thx. I tried to convert it using PHP since it is quick echo $time = date("m/d/Y h:i:s A T", $jsontimestamp); I should have checked directly in Java :-) – Junior Dev Apr 05 '18 at 04:56
  • While dividing by 1000 will work, no need to do the math explicitly at such a low level. You’ll get more readable code from leaving the math to standard library classes. Ring Ø and @d-coder – Ole V.V. Apr 06 '18 at 07:49

2 Answers2

3

try this timestamp in 10 digit

 import java.text.DateFormat;
 import java.text.SimpleDateFormat;
 import java.util.Date;
 public class HelloWorld{

//1522899000
public static void main(String[] args) throws Exception {

    Date d = new Date((long)1522899000*1000);
    DateFormat f = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.mmm'Z'");
    System.out.println(f.format(d));
 }
}

OP

2018-04-05T03:30:00.030Z
Night Programmer
  • 341
  • 5
  • 25
  • 1
    FYI, the troublesome old date-time classes such as [`java.util.Date`](https://docs.oracle.com/javase/10/docs/api/java/util/Date.html), [`java.util.Calendar`](https://docs.oracle.com/javase/10/docs/api/java/util/Calendar.html), and `java.text.SimpleDateFormat` are now [legacy](https://en.wikipedia.org/wiki/Legacy_system), supplanted by the [*java.time*](https://docs.oracle.com/javase/10/docs/api/java/time/package-summary.html) classes built into Java 8 and later. See [*Tutorial* by Oracle](https://docs.oracle.com/javase/tutorial/datetime/TOC.html). – Basil Bourque Apr 06 '18 at 05:33
  • 1
    `….030Z`? Why the fraction of a second? – Basil Bourque Apr 06 '18 at 05:39
  • 1
    Please don’t teach the young ones to use the long outdated and notoriously troublesome `SimpleDateFormat` class. At least not as the first option. And not without any reservation. Today we have so much better in [`java.time`, the modern Java date and time API](https://docs.oracle.com/javase/tutorial/datetime/). – Ole V.V. Apr 06 '18 at 07:45
  • 1
    This code does NOT work properly because receivers of output string will interprete it in UTC but it was generated for the system timezone of the current JVM, very bad. – Meno Hochschild Apr 06 '18 at 08:40
  • Expected output: `2018-04-05T03:30:00Z`. Observed output on my computer: `2018-04-05T05:30:00.030Z`. The hours are 5 instead of 3, and 30 milliseconds have been added, apparently out of nowhere. Of course these bugs can be fixed, but it will be much simpler to switch to the `java.time` solution shown in the other answer. – Ole V.V. Apr 06 '18 at 09:18
  • 1
    1- you used `.mmm` for the fraction of seconds, but `m` is for the **minutes**. For fraction of seconds, you must use `.SSS`. 2- `'Z'` (inside quotes) prints a literal Z (the letter Z itself), but the Z in the end means the date/time is in UTC and it shouldn't be added like this - more than that, the formatter will use JVM default timezone, but it'll print the Z, giving an incorrect UTC value depending on JVM config (as noted by Meno's comment above). You should use `new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSX");` and then set it to UTC with `f.setTimeZone(TimeZone.getTimeZone("UTC"));` – carlBjqsd Apr 11 '18 at 17:49
3

tl;dr

Apparently, 1522899000000 is a count of milliseconds since the epoch reference of 1970-01-01T00:00:00Z, first moment of 1970 in UTC.

Instant.ofEpochMilli( 1_522_899_000_000L )

2018-04-05T03:30:00Z

java.time

The modern approach uses the java.time classes that supplant the troublesome old legacy classes (Date, Calendar, SimpleDateFormat).

Your input seems to be a count of milliseconds since the epoch of 1970-01-01T00:00Z. Sometimes known as Unix time, though not definitively.

Instant

So parse as an Instant. The Instant class represents a moment on the timeline in UTC with a resolution of nanoseconds (up to nine (9) digits of a decimal fraction).

long input = 1_522_899_000_000L ;
Instant instant = Instant.ofEpochMilli( input );

instant.toString(): 2018-04-05T03:30:00Z

If your input is textual, parse as a number with Long.parse.

long input = Long.parseLong( "1522899000000" ) ;
Instant instant = Instant.ofEpochMilli( input );

ZonedDateTime

An Instant is always in UTC, by definition. If you want to see that same moment through the wall-clock time used by people of a certain region (a time zone), apply a ZoneId to get a ZonedDateTime object.

Specify a proper time zone name in the format of continent/region, such as America/Montreal, Africa/Casablanca, or Pacific/Auckland. Never use the 3-4 letter pseudo-zones such as EST or IST as they are not true time zones, not standardized, and not even unique(!).

ZoneId z = ZoneId.of( "Pacific/Auckland" ) ;
ZonedDateTime zdt = instant.atZone( z ) ;

zdt.toString(): 2018-04-05T15:30+12:00[Pacific/Auckland]

DateTimeFormatter

The strings generated above are in standard ISO 8601 format. For other formats, search Stack Overflow for the DateTimeFormatter class.


About java.time

The java.time framework is built into Java 8 and later. These classes supplant the troublesome old legacy date-time classes such as java.util.Date, Calendar, & SimpleDateFormat.

The Joda-Time project, now in maintenance mode, advises migration to the java.time classes.

To learn more, see the Oracle Tutorial. And search Stack Overflow for many examples and explanations. Specification is JSR 310.

You may exchange java.time objects directly with your database. Use a JDBC driver compliant with JDBC 4.2 or later. No need for strings, no need for java.sql.* classes.

Where to obtain the java.time classes?

The ThreeTen-Extra project extends java.time with additional classes. This project is a proving ground for possible future additions to java.time. You may find some useful classes here such as Interval, YearWeek, YearQuarter, and more.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154