Convert Human Date (Local Time GMT) to date

后端 未结 2 790
生来不讨喜
生来不讨喜 2021-01-29 08:49

I am working on server and server is sending me date on GMT Local Date like Fri Jun 22 09:29:29 NPT 2018 on String format and I convert it into Date like below:

相关标签:
2条回答
  • 2021-01-29 09:43

    NPT is not recognized as a time zone abbreviation

    The parsing of your date-time string (apparently the output from Date.toString()) is the problem (not the subsequent use of TimeAgo, which you could have left out from the question to make it clearer). The unparseable part is at index 20, that is where it says NPT, which I take to mean Nepal Time. So SimpleDateFormat on your Android device or emulator doesn’t recognize NPT as a time zone abbreviation.

    Time zone abbreviations come as part of the locale data. I am not an Android developer and don’t know from where Android gets its locale data. A fast web search mentioned ICU and CLDR. You can search more thoroughly and no doubt find information I didn’t find.

    I am presenting three suggestions for you to try. I admit at once that the first two are unlikely to solve your problem, but I nevertheless find them worth trying. And I promise that the third will work if the first two don’t.

    1. Use ThreeTenABP and java.time

    I agree with the answer by notyou that the classes Date and SimpleDateFormat are outmoded and that it’s better to use java.time, the modern Java date and time API. Can you do that on Android prior to Android O? Yes, most of java.time has been backported. The Android edition of the backport is called ThreeTenABP. Use the links at the bottom. Then try:

        DateTimeFormatter formatter 
                = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ROOT);
        ZonedDateTime newDateTime
                = ZonedDateTime.parse("Fri Jun 22 09:29:29 NPT 2018", formatter);
        System.out.println(newDateTime);
    

    Make sure you use the imports for the backport:

    import org.threeten.bp.ZonedDateTime;
    import org.threeten.bp.format.DateTimeFormatter;
    

    I have tested with the same backport, only not the Android edition. I got:

    2018-06-22T09:29:29+05:45[Asia/Kathmandu]

    I suspect that ThreeTenABP uses the same locale data, though, and if so, this doesn’t solve your problem.

    2. Set the time zone on the formatter

        DateTimeFormatter formatter = DateTimeFormatter
                .ofPattern("EEE MMM dd HH:mm:ss zzz yyyy", Locale.ROOT)
                .withZone(ZoneId.of("Asia/Kathmandu"));
    

    If it works, I find it straightforward and clean. If you insist on using SimpleDateFormat, you can try a similar trick with it. I get the same output as above.

    3. Handle NPT as literal text

    This is a hack: require that the three letters NPT occur in the string without interpreting them as a time zone. This eliminates the need for the abbreviation to be recognized as a time zone, so will work.

        DateTimeFormatter formatter = DateTimeFormatter
                .ofPattern("EEE MMM dd HH:mm:ss 'NPT' yyyy", Locale.ROOT)
                .withZone(ZoneId.of("Asia/Kathmandu"));
    

    We also need to set the time zone since this is now the only place Java can get the time zone from.

    But TimeAgo requires a Date

    To obtain an old-fashioned Date object for TimeAgo, convert like this:

        Date newDate = DateTimeUtils.toDate(newDateTime.toInstant());
    

    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.timeto 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.
    0 讨论(0)
  • 2021-01-29 09:50

    The Date class is predominantly deprecated, so I would suggest not to use that.

    Perhaps consider using something like the ZonedDateTime class for your problem.

    If you're just looking for 5 hours before the String sent over to you, you could use something like:

    String time = "Fri Jun 22 09:29:29 NPT 2018";
    DateTimeFormatter format = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss zzz uuuu");
    ZonedDateTime zdt = ZonedDateTime.parse(time, format);
    System.out.println(zdt.minusHours(5));
    
    0 讨论(0)
提交回复
热议问题