简体   繁体   English

将人类日期(当地时间GMT)转​​换为日期

[英]Convert Human Date (Local Time GMT) to date

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: 我正在服务器上工作,并且服务器向我发送格林尼治标准时间本地日期的日期,如Fri Jun 22 09:29:29 NPT 2018以字符串格式,并将其转换为日期,如下所示:

SimpleDateFormat simpleDateFormat=new SimpleDateFormat("EEE MMM dd HH:mm:ss zzz yyyy",Locale.English);
Date newDate=simpleDateFormat.parse("Fri Jun 22 09:29:29 NPT 2018");
TimeAgo ta=new TimeAgo();
Log.d(TAG,""+ta.timeAgo(newDate));

What I need is take out the Time in Ago like 5 hours ago for that I use the one github project on which returns TimeAgo on passing date . 我需要的是像5 hours ago前一样取出Time in Ago,因为我使用了一个github项目,该项目在传递日期时返回TimeAgo

I have already look at this answer but didn't solve my problem. 我已经看过这个答案,但没有解决我的问题。

Exception: Err java.text.ParseException: Unparseable date: "Fri Jun 22 09:29:29 NPT 2018" (at offset 20) Err java.text.ParseException: Unparseable date: "Fri Jun 22 09:29:29 NPT 2018" (at offset 20) 异常:Err java.text.ParseException:不可解析的日期:“星期五6月22日09:29:29 NPT 2018”(偏移20)Err java.text.ParseException:无法解析的日期:“星期五6月22日09:29:29 NPT 2018 ”(偏移量为20)

The Date class is predominantly deprecated, so I would suggest not to use that. Date类主要被弃用,因此我建议不要使用它。

Perhaps consider using something like the ZonedDateTime class for your problem. 也许考虑使用类似于ZonedDateTime类的方法来解决您的问题。

If you're just looking for 5 hours before the String sent over to you, you could use something like: 如果您只是在将String发送给您之前等待5个小时,则可以使用以下方法:

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));

NPT is not recognized as a time zone abbreviation NPT不被视为时区缩写

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). 问题是您的日期时间字符串(显然是Date.toString()的输出Date.toString()的解析(不是随后对TimeAgo使用,您可能没有在问题中使用它来使它更清楚)。 The unparseable part is at index 20, that is where it says NPT , which I take to mean Nepal Time. 不可分割的部分在索引20处,即NPT ,我指的是尼泊尔时间。 So SimpleDateFormat on your Android device or emulator doesn't recognize NPT as a time zone abbreviation. 因此,Android设备或仿真器上的SimpleDateFormat无法将NPT识别为时区缩写。

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. 我不是Android开发人员,也不知道Android从何处获取其区域设置数据。 A fast web search mentioned ICU and CLDR. 快速网络搜索提到了ICU和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 1.使用ThreeTenABP和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. 我同意您的回答,即类DateSimpleDateFormat已过时,最好使用现代Java日期和时间API java.time Can you do that on Android prior to Android O? 您可以在Android O之前的Android上执行此操作吗? Yes, most of java.time has been backported. 是的,大多数java.time已被java.time移植。 The Android edition of the backport is called ThreeTenABP. backport的Android版本称为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. 我已经使用相同的反向端口进行了测试,但没有测试过Android版本。 I got: 我有:

2018-06-22T09:29:29+05:45[Asia/Kathmandu] 2018-06-22T09:29:29 + 05:45 [亚洲/加德满都]

I suspect that ThreeTenABP uses the same locale data, though, and if so, this doesn't solve your problem. 我怀疑ThreeTenABP使用相同的语言环境数据,如果这样的话,这不能解决您的问题。

2. Set the time zone on the formatter 2.在格式化程序上设置时区

    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. 如果您坚持使用SimpleDateFormat ,则可以尝试使用类似的技巧。 I get the same output as above. 我得到与上述相同的输出。

3. Handle NPT as literal text 3.将NPT作为文字处理

This is a hack: require that the three letters NPT occur in the string without interpreting them as a time zone. 这是一个hack:要求字符串中出现三个字母NPT ,而不将它们解释为时区。 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. 我们还需要设置时区,因为现在这是Java唯一可以获取时区的地方。

But TimeAgo requires a Date 但是TimeAgo需要一个日期

To obtain an old-fashioned Date object for TimeAgo , convert like this: 要获取TimeAgo的老式Date对象,请TimeAgo转换:

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

Links 链接

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM