Programming

Java에서 Long을 Date로 변환하면 1970이 반환됩니다.

procodes 2020. 8. 15. 14:28
반응형

Java에서 Long을 Date로 변환하면 1970이 반환됩니다.


웹 서비스에서 다운로드 한 긴 값 (예 : 1220227200, 1220832000, 1221436800 ...)이있는 목록이 있습니다. 날짜로 변환해야합니다. 안타깝게도이 방법은 다음과 같습니다.

Date d = new Date(1220227200);

1970 년 1 월 1 일을 반환합니다. 누구든지 올바르게 변환하는 다른 방법을 알고 있습니까?


Date생성자 (링크를 클릭!)와 같은 시간 허용 long에서 밀리 초 단위 가 아닌 초. 1000을 곱하고 long.

Date d = new Date(1220227200L * 1000);

여기에 표시됩니다.

2008 년 8 월 31 일 일요일 20:00:00 GMT-04 : 00


tl; dr

Instant.ofEpochSecond( 1_220_227_200L )

데이터 파악

사람들은 시대 이후로 시간을 추적 할 때 다양한 정밀도를 숫자로 사용합니다 . 따라서 에포크 이후 카운트로 해석 될 일부 숫자를 얻으려면 다음을 결정해야합니다.

  • 어떤 시대?
    많은 epochs 날짜 가 다양한 시스템에서 사용되었습니다. 일반적으로 사용되는 POSIX / Unix 시간 은 UTC로 1970 년의 첫 번째 순간입니다. 그러나이 시대를 가정 해서는 안됩니다 .
  • 무슨 정밀도? 에포크 이후로
    초, 밀리 초 , 마이크로 초 또는 나노초를 말하고 있습니까?
  • 어떤 시간대?
    일반적으로 epoch가 UTC / GMT 시간대이므로, 즉 시간대 오프셋이 전혀 없기 때문에 카운트 입니다. 그러나 때로는 경험이 없거나 날짜 시간에 무지한 프로그래머를 포함 할 때 암시 된 시간대가있을 수 있습니다.

귀하의 경우 다른 사람들이 언급했듯이 Unix 시대 이후로 몇 초가 주어진 것 같습니다. 그러나 밀리 초를 예상하는 생성자에 해당 초를 전달합니다. 따라서 해결책은 1,000을 곱하는 것입니다.

교훈:

  • 수신 된 데이터의 의미를 결정하고 가정하지 마십시오.
  • 문서를 읽으십시오 .

전체 초, 밀리 초, 마이크로 초 및 나노초를 포함하여 날짜-시간 시스템의 다양한 해상도를 보여주는 그래프입니다.

귀하의 데이터

데이터가 몇 초 안에있는 것 같습니다. 1970 년 초를 가정하고 UTC 시간대를 가정하면 1,220,227,2002008 년 9 월 1 일의 첫 번째 순간입니다.

Joda-Time

Java와 함께 번들로 제공되는 java.util.Date 및 .Calendar 클래스는 문제가있는 것으로 악명이 높습니다. 그들을 피하십시오. 대신 Joda-Time 라이브러리 또는 Java 8에 번들로 제공되는 새로운 java.time 패키지 (Joda-Time에서 영감을 얻음)를 사용하십시오.

Note that unlike j.u.Date, a DateTime in Joda-Time truly knows its own assigned time zone. So in the example Joda-Time 2.4 code seen below, note that we first parse the milliseconds using the default assumption of UTC. Then, secondly, we assign a time zone of Paris to adjust. Same moment in the timeline of the Universe, but different wall-clock time. For demonstration, we adjust again, to UTC. Almost always better to explicitly specify your desired/expected time zone rather than rely on an implicit default (often the cause of trouble in date-time work).

We need milliseconds to construct a DateTime. So take your input of seconds, and multiply by a thousand. Note that the result must be a 64-bit long as we would overflow a 32-bit int.

long input = 1_220_227_200L;  // Note the "L" appended to long integer literals.
long milliseconds = ( input * 1_000L ); // Use a "long", not the usual "int". Note the appended "L".

Feed that count of milliseconds to constructor. That particular constructor assumes the count is from the Unix epoch of 1970. So adjust time zone as desired, after construction.

Use proper time zone names, a combination of continent and city/region. Never use 3 or 4 letter codes such as EST as they are neither standardized not unique.

DateTime dateTimeParis = new DateTime( milliseconds ).withZone( DateTimeZone.forID( "Europe/Paris" ) );

For demonstration, adjust the time zone again.

DateTime dateTimeUtc = dateTimeParis.withZone( DateTimeZone.UTC );
DateTime dateTimeMontréal = dateTimeParis.withZone( DateTimeZone.forID( "America/Montreal" ) );

Dump to console. Note how the date is different in Montréal, as the new day has begun in Europe but not yet in America.

System.out.println( "dateTimeParis: " + dateTimeParis );
System.out.println( "dateTimeUTC: " + dateTimeUtc );
System.out.println( "dateTimeMontréal: " + dateTimeMontréal );

When run.

dateTimeParis: 2008-09-01T02:00:00.000+02:00
dateTimeUTC: 2008-09-01T00:00:00.000Z
dateTimeMontréal: 2008-08-31T20:00:00.000-04:00

java.time

The makers of Joda-Time have asked us to migrate to its replacement, the java.time framework as soon as is convenient. While Joda-Time continues to be actively supported, all future development will be done on the java.time classes and their extensions in the ThreeTen-Extra project.

The java-time framework is defined by JSR 310 and built into Java 8 and later. The java.time classes have been back-ported to Java 6 & 7 on the ThreeTen-Backport project and to Android in the ThreeTenABP project.

An Instant is a moment on the timeline in UTC with a resolution of nanoseconds. Its epoch is the first moment of 1970 in UTC.

Instant instant = Instant.ofEpochSecond( 1_220_227_200L );

Apply an offset-from-UTC ZoneOffset to get an OffsetDateTime.

Better yet, if known, apply a time zone ZoneId to get a ZonedDateTime.

ZoneId zoneId = ZoneId.of( "America/Montreal" );
ZonedDateTime zdt = ZonedDateTime.ofInstant( instant , zoneId );

It looks like your longs are seconds, and not milliseconds. Date constructor takes time as millis, so

Date d = new Date(timeInSeconds * 1000);

Only set the time in mills on Calendar object

Calendar c = Calendar.getInstance();
c.setTimeInMillis(1385355600000l);
System.out.println(c.get(Calendar.YEAR));
System.out.println(c.get(Calendar.MONTH));
System.out.println(c.get(Calendar.DAY_OF_MONTH));
// get Date
System.out.println(c.getTime());

Those are probably timestamps in seconds and not in milliseconds which is required for the java new Date(long) constructor. Just multiply them by 1000 and you should be allright.


The long values, most likely, correspond to Epoch timestamps, and the values are:

1220227200 = Mon, 01 Sep 2008 00:00:00 GMT

1220832000 = Mon, 08 Sep 2008 00:00:00 GMT

1221436800 = Mon, 15 Sep 2008 00:00:00 GMT

One can convert these long values to java.util.Date, taking into account the fact java.util.Date uses millisecs – as previously hinted, but with some flaw - like this:

// note: enforcing long literals (L), without it the values would just be wrong.
Date date = new Date(1220227200L * 1000L); 

Now, to display the date correctly, one can use java.text.DateFormat as illustrated hereafter:

DateFormat df = DateFormat.getDateTimeInstance(DateFormat.FULL, DateFormat.FULL);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("Wrong date time value: " + date);
System.out.println("Correct date time value: " + df.format(date));

Below are the results of displaying the converted long value to java.util.Date without using and using the DateFormat:

Date wrong (off by 2 hours): Mon Sep 01 02:00:00 CEST 2008
Correct date : Monday, 1 September 2008 00:00:00 o'clock UTC

Try this:

Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(1220227200 * 1000);
System.out.println(cal.getTime());

1220227200 corresponds to Jan 15 1980 (and indeed new Date(1220227200).toString() returns "Thu Jan 15 03:57:07 CET 1970"). If you pass a long value to a date, that is before 01/01/1970 it will in fact return a date of 01/01/1970. Make sure that your values are not in this situation (lower than 82800000).


New Date(number) returns a date that's number milliseconds after 1 Jan 1970. Odds are you date format isn't showing hours, minutes, and seconds for you to see that it's just a little bit after 1 Jan 1970.

You need to parse the date according to the correct parsing routing. I don't know what a 1220227200 is, but if it's seconds after 1 JAN 1970, then multiply it to yield milliseconds. If it is not, then convert it in some manner to milliseconds after 1970 (if you want to continue to use java.util.Date).


Works for me. You probably want to multiplz it with 1000, since what you get are the seconds from 1970 and you have to pass the milliseconds from jan 1 1970


Try this with adjusting the date format.

long longtime = 1212580300;
SimpleDateFormat dateFormat = new SimpleDateFormat("MMddyyHHmm");
Date date = (Date) dateFormat.parseObject(longtime + "");
System.out.println(date);

Note: Check for 24 hours or 12 hours cycle.

참고 URL : https://stackoverflow.com/questions/7487460/converting-long-to-date-in-java-returns-1970

반응형