以所需的时区显示毫秒的正确时间 [英] Showing correct time from Milliseconds with desired TimeZone

查看:144
本文介绍了以所需的时区显示毫秒的正确时间的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个应用程序,该应用程序从 Google TimeZone API 获取数据。
我只是有时间以毫秒为单位在地球上期望的位置。

I'm developing an application which takes data from Google TimeZone API. Simply I have time in milliseconds of desired place on Earth.

例如: 1504760156000 伦敦的日期时间


2017年9月7日星期四09:55:56

Thu Sep 07 2017 09:55:56

当我在UTC的TimeZone +05:00 中时,如果我操作 1504760156000 这毫秒将显示整个日期,如下所示:

As I'm in TimeZone +05:00 from UTC if I manipulate 1504760156000 these milliseconds it will show me whole date time like below:


2017年9月7日星期四09:55:56 GMT + 0500(巴基斯坦标准时间)

Thu Sep 07 2017 09:55:56 GMT+0500 (Pakistan Standard Time)

但我想显示:


2017年9月7日星期四09:55:56 GMT + 0100(英国夏令时)

Thu Sep 07 2017 09:55:56 GMT+0100 (British Summer Time)

问题是:我具有伦敦的正确日期和时间,但是可以显示/更改TimeZone而无需更改时间,因为根据伦敦的说法,时间是正确的。

The problem is: I have correct date and time for London but enable to show/change TimeZone without changing Time because Time is correct according to London.

已更新

收到一些评论后。

假设我在巴基斯坦,时间现在是 1:55 PM 所以我通过我的应用程序询问GOOGLE API,以告诉我现在伦敦几点钟了。 Google API告诉我伦敦的时间是 1504760156000 (上午9:55),如果我将这些毫秒数转换为 Date 它将打印出的对象如下所示:

Suppose I am in Pakistan and Time here is 1:55 PM so I asked GOOGLE API via my application to tell me whats the time in London at moment. Google API tell me time in London is 1504760156000 (9:55 AM) in milliseconds if I convert these milliseconds to Date Object it will print out like below:

Date date =new Date(1504760156000)




2017年9月7日星期四09:55:56 GMT + 0500(巴基斯坦标准时间)

Thu Sep 07 2017 09:55:56 GMT+0500 (Pakistan Standard Time)

它将根据我的本地时区对其进行操作,但是我想要下面的结果

It will manipulate it according to my Local TimeZone but I want results like below


2017年9月7日星期四09:55:56 GMT + 0100(英国夏令时)

Thu Sep 07 2017 09:55:56 GMT+0100 (British Summer Time)

已更新2

我在UTC中准备了以秒为单位的时间戳,因为Google时区API需要以秒为形式的时间戳UTC

I prepared timestamp in seconds in UTC as Google Time Zone API needed timestamp UTC in form of seconds

"https://maps.googleapis.com/maps/api/timezone/json?location="+Latitude +","+Longitude+"&timestamp="+currentTimeUTCinSeonds+"&key="API KEY"

Google API使用以下JSON响应我

Google API respond me with below JSON against London.

{
    "dstOffset" : 3600,   
    "rawOffset" : 0,  
    "status" : "OK",  
    "timeZoneId" : "Europe/London",  
    "timeZoneName" : "British Summer Time"
}

根据文档:


计算本地时间

Calculating the Local Time

给定位置的本地时间是时间戳记
参数以及结果中的dstOffset和rawOffset字段的总和。

The local time of a given location is the sum of the timestamp parameter, and the dstOffset and rawOffset fields from the result.

我总结结果 timestamp + rawoffset + dstoffset * 1000 ='1504760156000'(在我尝试过了)

I Sum up result timestamp+rawoffset+dstoffset*1000='1504760156000' (at moment when I tried it)

项目代码

Long ultimateTime=((Long.parseLong(timeObject1.getDstOffset())*1000)+(Long.parseLong(timeObject1.getRawOffset())*1000)+timestamp*1000);
                    timeObject1.setTimestamp(ultimateTime);  //its Sime POJO object to save current time of queried Location 
                    Date date=new Date(ultimateTime);
                    date1.setText("Date Time : "+date);

我说过我正在本地时区操作结果,因此当时的结果低于我:

As I said I'm manipulating result in Local Time Zone so it gave me below result at that time:


2017年9月7日星期四09:55:56 GMT + 0500(巴基斯坦标准时间)

Thu Sep 07 2017 09:55:56 GMT+0500 (Pakistan Standard Time)

但是我知道API给了我正确的时间。问题是UTC的本地偏移量。我只想将 GMT + 0500 更改为 GMT + 0100

But I knew API gave me correct time. The problem is Local offset from UTC . I just want to change GMT+0500 to GMT+0100

推荐答案

时间戳表示从纪元开始经过的时间的绝对值。例如,您的 currentTimeUTCinSeconds 代表自unix时代以来的秒数(即 1970-01-01T00:00Z ,或1970年1月1日 st 在UTC的午夜)。 Java API通常使用自纪元以来的毫秒数。

Timestamps represent an "absolute" value of a time elapsed since epoch. Your currentTimeUTCinSeconds, for example, represent the number of seconds since unix epoch (which is 1970-01-01T00:00Z, or January 1st 1970 at midnight in UTC). Java API's usually work with the number of milliseconds since epoch.

但是概念是相同的-这些值是绝对的:对于世界上的每个人都是相同的,无论它们在哪里。如果世界上不同地区(在不同时区)的2个人同时获得当前时间戳,那么他们都将获得相同的时间戳。

But the concept is the same - those values are "absolute": they are the same for everyone in the world, no matter where they are. If 2 people in different parts of the world (in different timezones) get the current timestamp at the same time, they'll all get the same number.

变化是什么在不同的时区,相同的数字表示不同的本地日期和时间。

What changes is that, in different timezones, this same number represents a different local date and time.

例如,您使用的时间戳对应于9月7日 th 2017 08:55:56 UTC,该值为1504774556(自纪元以来的秒数)。该数字对应于伦敦的09:55,卡拉奇的13:55,东京的17:55,依此类推。 更改此数字将更改每个人的本地时间-无需进行操作。

For example, the timestamp you're using, that corresponds to Sep 7th 2017 08:55:56 UTC, which value is 1504774556 (the number of seconds since epoch). This same number corresponds to 09:55 in London, 13:55 in Karac 17:55 in Tokyo and so on. Changing this number will change the local times for everyone - there's no need to manipulate it.

如果您想获得<$ c $代表此瞬间的c> java.util.Date ,只需执行以下操作:

If you want to get a java.util.Date that represents this instant, just do:

int currentTimeUTCinSeconds = 1504774556;
// cast to long to not lose precision
Date date = new Date((long) currentTimeUTCinSeconds * 1000);

此日期将保留值1504774556000(历元以来的毫秒数)。此值对应于伦敦的09:55,卡拉奇的13:55和东京的17:55。

This date will keep the value 1504774556000 (the number of milliseconds since epoch). This value corresponds to 09:55 in London, 13:55 in Karachi and 17:55 in Tokyo.

但是打印此日期会将其转换为JVM默认时区( 此处是关于 Date :: toString()方法的行为)。当您执行 Date Time: + date 时,它隐式调用 toString()方法,结果是日期转换为默认时区。

But printing this date will convert it to your JVM default timezone (here is a good explanation about the behaviour of Date::toString() method). When you do "Date Time : "+date, it implicity calls toString() method, and the result is the date converted to your default timezone.

如果您希望使用特定格式和特定​​时区的日期,则需要 SimpleDateFormat 。仅仅打印日期(使用 System.out.println 或通过记录它)是行不通的:您不能更改日期对象本身的格式,因为日期 没有格式

If you want the date in a specific format and in a specific timezone, you'll need a SimpleDateFormat. Just printing the date (with System.out.println or by logging it) won't work: you can't change the format of the date object itself, because a Date has no format.

我也使用 java.util.Locale 以指定月份和星期几必须为英文。如果您未指定语言环境,它将使用系统默认值,并且不能保证始终使用英语(而且即使在运行时也可以更改,因此最好始终指定语言环境):

I also use a java.util.Locale to specify that the month and day of week must be in English. If you don't specify a locale, it'll use the system default, and it's not guaranteed to always be English (and this can be changed, even at runtime, so it's better to always specify a locale):

// use the same format, use English for month and day of week
SimpleDateFormat sdf = new SimpleDateFormat("EEE MMM dd yyyy HH:mm:ss 'GMT'Z (zzzz)", Locale.ENGLISH);
// set the timezone I want
sdf.setTimeZone(TimeZone.getTimeZone("Europe/London"));
// format the date
System.out.println(sdf.format(date));

输出为:


2017年9月7日星期四09:55:56 GMT + 0100(英国夏令时)

Thu Sep 07 2017 09:55:56 GMT+0100 (British Summer Time)

请注意,我不会无需操纵时间戳值。我不使用google API,但我认为他们的解释太混乱了,上面的代码以较少的复杂性实现了相同的结果。

Note that I don't need to manipulate the timestamp value. I don't use the google API, but I think their explanation is too confusing and the code above achieve the same results with less complication.

在您的特定情况下,您可以做到:

In your specific case, you can do:

date1.setText("Date Time : "+sdf.format(date));






Java新的日期/时间API



旧类(日期日历 SimpleDateFormat )具有很多问题设计问题,并且它们已被新的API取代。


Java new Date/Time API

The old classes (Date, Calendar and SimpleDateFormat) have lots of problems and design issues, and they're being replaced by the new APIs.

在Android中,您可以使用 ThreeTen Backport ,这是Java 8的新日期/时间类的绝佳反向端口。要使其正常工作,您还需要 ThreeTenABP (有关如何使用它的更多信息在这里)。

In Android you can use the ThreeTen Backport, a great backport for Java 8's new date/time classes. To make it work, you'll also need the ThreeTenABP (more on how to use it here).

要从时间戳记中获取日期,我使用 org.threeten.bp.Instant org.threeten.bp.ZoneId 将其转换为时区,从而创建 org.threeten.bp.ZonedDateTime 。然后我使用 org.threeten.bp.format.DateTimeFormatter 对其进行格式化:

To get a date from a timestamp, I use a org.threeten.bp.Instant with a org.threeten.bp.ZoneId to convert it to a timezone, creating a org.threeten.bp.ZonedDateTime. Then I use a org.threeten.bp.format.DateTimeFormatter to format it:

int currentTimeUTCinSeconds = 1504774556;
// get the date in London from the timestamp
ZonedDateTime z = Instant.ofEpochSecond(currentTimeUTCinSeconds).atZone(ZoneId.of("Europe/London"));
// format it
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("EEE MMM dd yyyy HH:mm:ss 'GMT'XX (zzzz)", Locale.ENGLISH);
System.out.println(fmt.format(z));

输出是相同的:


2017年9月7日星期四09:55:56 GMT + 0100(英国夏令时)

Thu Sep 07 2017 09:55:56 GMT+0100 (British Summer Time)

,只需这样做:

date1.setText("Date Time : "+fmt.format(z));

这篇关于以所需的时区显示毫秒的正确时间的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆