Simple Date format gives wrong info from epoch timestamp

梦想的初衷 提交于 2020-05-01 05:07:52

问题


I found that this gives a wrong date. but how i can not solve it. please someone help me. I am new in android Development. Thanks in advance;

String timestamp = "1538970640";

SimpleDateFormat formatter = new SimpleDateFormat("dd MMM 'at' hh:mm a z" );
String dateString = formatter.format(new Date(Long.parseLong(timestamp)));

This returns:

19 Jan at 01:29 AM GMT+06:oo

But it should be:

8 Oct at 9:50 AM GMT+06:00

回答1:


The java.util.Date constructor accepts milliseconds since the Epoch, not seconds:

Allocates a Date object and initializes it to represent the specified number of milliseconds since the standard base time known as "the epoch", namely January 1, 1970, 00:00:00 GMT.

The following code which uses ms is working:

String timestamp = "1538970640000";   // use ms NOT s
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM 'at' hh:mm a z" );
String dateString = formatter.format(new Date(Long.parseLong(timestamp)));

08 Oct at 05:50 AM CEST

Demo

Part of the problem you were facing is that your date format omitted the year component, which was actually coming up as 1970.




回答2:


java.time and ThreeTenABP

I recommend you use java.time, the modern Java date and time API, for your date and time work.

    DateTimeFormatter timestampFormatter = new DateTimeFormatterBuilder()
            .appendValue(ChronoField.INSTANT_SECONDS)
            .toFormatter();
    DateTimeFormatter targetFormatter
            = DateTimeFormatter.ofPattern("d MMM 'at' h:mm a z", Locale.ENGLISH);

    String timestamp = "1538970640";
    ZonedDateTime dateTime = timestampFormatter.parse(timestamp, Instant.FROM)
            .atZone(ZoneId.systemDefault());
    String dateString = dateTime.format(targetFormatter);

    System.out.println(dateString);

Output is (when time zone is set to GMT+06:00, which by the way is not a true time zone):

8 Oct at 9:50 AM GMT+06:00

I am not very happy about converting date and time from one string format to another, though. In your app you should not handle date and time as strings but as proper date and time objects, for example Instant or ZonedDateTime. When you get a string from somewhere (a server?), parse it into a date-time object first thing. Only when you need to give string output, for example to the user, format your date and time into a string in the user’s time zone.

That said, java.time performs your conversion with just two formatters. No need to parse into a low-level long first.

Two more points:

  • Give your output formatter a locale to control the language used. Since AM and PM are hardly used in other languages than English, I figured that Locale.ENGLISH might be appropriate. You decide.
  • Since you want 8 Oct at 9:50 AM GMT+06:00, use just one d for day of month and one h for clock hour. Two digits will still be printed if the numbers go over 9, for example 10 Oct at 11:50 AM GMT+06:00.

What went wrong in your code?

Your number, 1538970640 (10 digits), denotes seconds since the epoch. This is the classical definition of a Unix timestamp. The Date constructor that you used expects milliseconds since the epoch. This is typical for the outdated Java date and time classes and methods. These years milliseconds since the epoch are typically 13 digits. As you can see, the modern Java date and time classes have better support for seconds here.

Question: Doesn’t java.time require Android API level 26?

java.time works nicely on both older and newer Android devices. It just requires at least Java 6.

  • In Java 8 and later and on newer Android devices (from API level 26) the modern API comes built-in. In this case, instead of the constant Instant.FROM use the method references Instant::from.
  • In non-Android Java 6 and 7 get the ThreeTen Backport, the backport of the modern classes (ThreeTen for JSR 310; see the links at the bottom).
  • On (older) Android use the Android edition of ThreeTen Backport. It’s called ThreeTenABP. And make sure you import the date and time classes from org.threeten.bp with subpackages.

Links

  • Oracle tutorial: Date Time explaining how to use java.time.
  • Java Specification Request (JSR) 310, where java.time was first described.
  • ThreeTen Backport project, the backport of java.time to Java 6 and 7 (ThreeTen for JSR-310).
  • ThreeTenABP, Android edition of ThreeTen Backport
  • Question: How to use ThreeTenABP in Android Project, with a very thorough explanation.


来源:https://stackoverflow.com/questions/52714920/simple-date-format-gives-wrong-info-from-epoch-timestamp

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