简体   繁体   English

在Java中为所有时区保存日期时间

[英]Saving date time for all time zones in java

I have an application in which user creates questions and others can see date time (when the question was created) with it. 我有一个应用程序,用户可以在其中创建问题,其他人可以使用它查看日期时间(创建问题时)。 Now i get the server date time and save it in db but the problem is app is used by someone who live in a country with a 6-7 hour gap. 现在我获取服务器日期时间并将其保存在db中,但问题是居住在有6-7小时间隔的国家/地区的人使用了app。 Well a small example would be that i live in some country and i create question at time 7:00pm but time in USA is 11am (just a guess). 很好的一个小例子是,我住在某个国家,我在晚上7:00提出问题,但在美国的时间是上午11点(只是一个猜测)。 So user immediately retrieves question but for him question time should be 11am and not 7pm. 因此,用户可以立即检索问题,但是对他来说,问题时间应该是上午11点而不是晚上7点。 So how can i save date time so it would be same for all time zones . 所以我该如何保存日期时间,以便所有时区都一样。 I m kinda confused so i need a little help . 我有点困惑,所以我需要一点帮助。 I know it's related to UTC date time but can someone elaborate this a bit more :) . 我知道这与UTC日期时间有关,但是有人可以详细说明一下:)。 Thank u 感谢你

So how can i save date time so it would be same for all time zones 所以我该如何保存日期时间,以便所有时区都相同

You should use UTC to store your dates, so if someone is using your app in +1 timezone, you need to convert it to UTC first. 您应该使用UTC存储日期,因此,如果有人在+1时区使用您的应用,则需要先将其转换为UTC。 Timezone should only be used to display the time to the users. 时区仅应用于向用户显示时间。

Store into your database the difference, measured in milliseconds, between the current time and the epoch of midnight, January 1, 1970 UTC. 存储到数据库中的差异,以毫秒为单位,当前时间和与时代午夜,1970年1月1日UTC。 that you can get by calling System.currentTimeMillis() . 可以通过调用System.currentTimeMillis()

Once you have it you can provide the time in any Time Zone that you want, here is a simple code snippet that shows the time in all the time zones available on my machine. 有了它后,就可以在所需的任何时区中提供时间,这是一个简单的代码段,显示了我的机器上所有可用时区的时间

This code uses the java.time framework built into Java 8 and later. 此代码使用Java 8及更高版本中内置的java.time框架。 Much of this functionality has also been back-ported to Java 6 & 7 and to Android . 许多功能也已反向移植到Java 6和7以及Android中

long time = System.currentTimeMillis();
Instant instant = Instant.ofEpochMilli(time);
ZoneId.getAvailableZoneIds().stream().forEach(id -> {
        ZoneId zId = ZoneId.of(id);
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant, zId);
        System.out.printf(
            "The current time in %s is %s%n",  
            zId, localDateTime.format(DateTimeFormatter.ISO_DATE_TIME)
        );
    }
);

Here is the equivalent for older versions of Java: 这与旧版Java是等效的:

long time = System.currentTimeMillis();
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(time);
for (String id : TimeZone.getAvailableIDs()) {
    SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
    formatter.setTimeZone(TimeZone.getTimeZone(id));
    System.out.printf(
        "The current time in %s is %s%n",  id, formatter.format(cal.getTime())
    );
}

Response Update: 回应更新:

As you want to keep the original TimeZone , you will also have to store the time zone Id into your database in the pseudo standard format GMT+/-mm:ss. 当您想要保留原始的TimeZone ,还必须以伪标准格式GMT +/- mm:ss将时区ID存储到数据库中。

For this, first you need to get the delta compared to UTC time (in the code snippet below tz is my current TimeZone): 为此,首先需要获取与UTC时间相比的增量(在tz下面的代码段中是我当前的TimeZone):

int offsetFromUTC = tz.getOffset(time);

Then from this you can convert this delta in milliseconds into the expected time zone id which can be done like this: 然后,您可以将以毫秒为单位的此增量转换为预期的时区ID,可以这样进行:

String timeZoneId = String.format(
    "GMT%+02d:%02d", offsetFromUTC / (60 * 60 * 1000), offsetFromUTC / (60 * 1000) % 60
);

The value of timeZoneId is the second value that you have to store into the database. timeZoneId的值是您必须存储到数据库中的第二个值。 With these two values you can display the time in any expected format, for example: 使用这两个值,可以以任何期望的格式显示时间,例如:

Calendar cal = Calendar.getInstance();
// Here I use the time retrieved from the DB
cal.setTimeInMillis(time);
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
// Here I use the time zone id retrieved from the DB
TimeZone tz = TimeZone.getTimeZone(timeZoneId);
formatter.setTimeZone(tz);
System.out.printf("The current time in %s is %s%n",  id, formatter.format(cal.getTime()));

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

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