使用java.util.Date在Java中进行不同的时间转换

huangapple go评论68阅读模式
英文:

Different time conversion by using java.util.Date in Java

问题

以下是翻译好的部分:

我正在使用以下代码,通过在Java中使用java.util.Date类进行从时代到时间的转换。

Long scheduledTime = 1602258300000L;
Date date = new Date(scheduledTime);
System.out.println("Date obj :" + date);

在两个不同的时区服务器上运行相同代码时,以下是输出:

在东部夏令时(EDT)服务器上 -

Date obj :Fri Oct 09 11:45:00 EDT 2020

在印度标准时间(IST)服务器上 -

Date obj :Fri Oct 09 21:15:00 IST 2020

为什么会发生这种情况?我只传递了毫秒。这些数据应该在所有服务器上都被视为21:15。为什么Date类会改变数据?

请分享一段示例代码,以获取与服务器的时区无关的相同时间数据。

英文:

I am using the below code for epoch to time conversion by using java.util.Date class in Java.

Long scheduledTime = 1602258300000L;
Date date = new Date(scheduledTime);
System.out.println("Date obj :" + date);

Below are the outputs while running the same code on two different timezone server :

On EDT server-

Date obj :Fri Oct 09 11:45:00 EDT 2020

On IST server -

Date obj :Fri Oct 09 21:15:00 IST 2020

Why does this happen? I am only passing milliseconds. This data is supposed to be treated as 21:15 on all servers. Why does Date class change the data?

Please share a sample piece of code for getting the same time data regardless of the timezone of the server.

答案1

得分: 11

A Date object represents a specific instant in time, represented by a given number of milliseconds since the Unix epoch.

The toString() method converts that instant in time into a local time based on the default time zone. It's not that the Date value itself "has" a time zone - it's just toString() that uses the default one.

> This data is supposed to be treated as 21:15 on all servers.

That suggests you want to use the Indian time zone in all servers, at least when converting the instant in time for display. Without knowing anything more about your application, that's all we can say... other than "don't use java.util.Date or java.util.Calendar; use the java.time classes instead". They're much better designed, and you're less likely to run into problems like this.

英文:

A Date object represents a specific instant in time, represented by a given number of milliseconds since the Unix epoch.

The toString() method converts that instant in time into a local time based on the default time zone. It's not that the Date value itself "has" a time zone - it's just toString() that uses the default one.

> This data is supposed to be treated as 21:15 on all servers.

That suggests you want to use the Indian time zone in all servers, at least when converting the instant in time for display. Without knowing anything more about your application, that's all we can say... other than "don't use java.util.Date or java.util.Calendar; use the java.time classes instead". They're much better designed, and you're less likely to run into problems like this.

答案2

得分: 4

java.time

我建议您使用现代的 Java 日期和时间 API,即 java.time,来处理您的日期和时间工作。

long scheduledTime = 1_602_258_300_000L;
Instant pointInTime = Instant.ofEpochMilli(scheduledTime);
System.out.println(pointInTime);

这段代码的输出将在所有服务器和所有时区中都相同:

> 2020-10-09T15:45:00Z

由于您想要 21:15,需要指定印度的时区:

ZoneId serverTimeZone = ZoneId.of("Asia/Kolkata");
ZonedDateTime dateTime = pointInTime.atZone(serverTimeZone);
System.out.println(dateTime);

这段代码的输出将是:

> 2020-10-09T21:15+05:30[Asia/Kolkata]

发生了什么问题?

纪元是一个与时区无关的时间点。因此,毫秒数也表示一个时间点。在您的情况下,那个时间点是 2020 年 10 月 9 日星期五 15:45:00 UTC。在那个时间点,印度的时间是 21:15,在北美东海岸是 11:45。过时的 Date 类有一个令人困惑的特点:一方面,它只表示一个时间点;另一方面,它的 toString 方法获取了 JVM 的时区设置,并将其用于呈现要返回的字符串,从而让您错误地认为在不同的时区中会得到不同的 Date 对象,但实际上它们是相等的。

链接

英文:

java.time

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

	long scheduledTime = 1_602_258_300_000L;
	Instant pointInTime = Instant.ofEpochMilli(scheduledTime);
	System.out.println(pointInTime);

Output from this snippet will be the same on all servers in all time zones:

> 2020-10-09T15:45:00Z

Since you want 21:15, specify the time zone for India:

	ZoneId serverTimeZone = ZoneId.of("Asia/Kolkata");
	ZonedDateTime dateTime = pointInTime.atZone(serverTimeZone);
	System.out.println(dateTime);

> 2020-10-09T21:15+05:30[Asia/Kolkata]

What went wrong?

The epoch is one point in time independent of time zone. so a count of milliseconds also denotes one point in time. In your case that point in time is Friday 9. October 2020 15:45:00 UTC. And at that point in time it was 21:15 in India and 11:45 on the East coast of North America. It’s a confusing trait of the outdated Date class that on one hand it represents just a point in time, on the other hand its toString method grabs the time zone setting of the JVM and uses it for rendering the string to be returned, thus giving you the false impression that you get different Date objects in different time zones when in fact they are equal.

答案3

得分: 1

// 引用其他人的建议,你现在应该使用 `java.time` 包来处理时间。如果你查看 `java.util.Date` 的 `toString()` 方法的文档,它会将 Date 对象转换为以下形式的字符串:
// >EEE MMM d m dd hh:mm:ss zzz yyyy

// 就像以下代码在后台运行一样:

public String toString(){
    Date date=this;
    SimpleDateFormat simpleDateFormat=new SimpleDateFormat(
             "EEE MMM d m dd hh:mm:ss zzz yyyy");
    simpleDateFormat.setTimeZone(TimeZone.getDefault());  // 这一行很重要。
    return simpleDateFormat.format(date);
}

// 现在,如果你想要为特定时区格式化你的 Date 对象,你可以做同样的操作,包括设置时区:

Long scheduledTime = 1602258300000L;
Date date = new Date(scheduledTime);
SimpleDateFormat simpleDateFormat=new SimpleDateFormat(
             "EEE MMM d m dd hh:mm:ss zzz yyyy");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("IST")); 
String dateStr = simpleDateFormat.format(date);
System.out.println("Date obj :" + dateStr);
英文:

As pointed by others you should now use the java.time package for working with time. If you look at the documentation of the toString() method of java.util.Date, it says that it coverts the Date object to a String of form:
>EEE MMM d m dd hh:mm:ss zzz yyyy

It is like the following code is running in the background:

public String toString(){
    Date date=this;
    SimpleDateFormat simpleDateFormat=new SimpleDateFormat(
             "EEE MMM d m dd hh:mm:ss zzz yyyy");
    simpleDateFormat.setTimeZone(TimeZone.getDefault());  //This line is important.
    return simpleDateFormat.format(date);
}

Now, if you wanna format your Date object for a certain timezone you can do the same including setting the timezone:

Long scheduledTime = 1602258300000L;
Date date = new Date(scheduledTime);
SimpleDateFormat simpleDateFormat=new SimpleDateFormat(
             "EEE MMM d m dd hh:mm:ss zzz yyyy");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("IST")); 
String dateStr = simpleDateFormat.format(date);
System.out.println("Date obj :" + dateStr);

huangapple
  • 本文由 发表于 2020年10月9日 22:34:31
  • 转载请务必保留本文链接:https://go.coder-hub.com/64282121.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定