Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Calendar.getInstance().getTime()返回“中的日期”;格林尼治标准时间;而不是默认时区_Java_Calendar_Gettime - Fatal编程技术网

Java Calendar.getInstance().getTime()返回“中的日期”;格林尼治标准时间;而不是默认时区

Java Calendar.getInstance().getTime()返回“中的日期”;格林尼治标准时间;而不是默认时区,java,calendar,gettime,Java,Calendar,Gettime,输出: 2017年9月12日星期二12:36:24 2007年1月1日星期一12:36:24 但是,当我在不同的环境中使用相同的代码时,输出更改如下: 输出: 2017年9月12日星期二12:36:24 2007年1月1日星期一12:36:24 GMT 仅供参考,我试图打印日历实例的时区,在设置值之前和之后,两者都在“IST”中 我想知道这件事的根本原因 您需要设置时区,您将获得所需的结果 TimeZone.setDefault(TimeZone.getTimeZone(“IST”) 这是一个工

输出:

2017年9月12日星期二12:36:24

2007年1月1日星期一12:36:24

但是,当我在不同的环境中使用相同的代码时,输出更改如下:

输出:

2017年9月12日星期二12:36:24

2007年1月1日星期一12:36:24 GMT

仅供参考,我试图打印日历实例的时区,在设置值之前和之后,两者都在“IST”中


我想知道这件事的根本原因

您需要设置时区,您将获得所需的结果

TimeZone.setDefault(TimeZone.getTimeZone(“IST”)

这是一个工作代码

Calendar c = Calendar.getInstance();
System.out.println(c.getTime());
c.set(2007, 0, 1);
System.out.println(c.getTime());
根据“通常情况下,您可以使用getDefault获得时区,它根据程序运行的时区创建时区。例如,对于在日本运行的程序,getDefault根据日本标准时间创建时区对象。”


因此,当您在不同的时区运行时,它将用作默认时区。希望你现在明白了。我附上医生。请阅读。

谈论这种有趣的行为:

Calendar类的源代码:

import java.util.Calendar;
import java.util.TimeZone;  
public class Cal {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        TimeZone.setDefault(TimeZone.getTimeZone("IST")); // Add this before print
        Calendar c = Calendar.getInstance();    
        System.out.println(c.getTime());
        c.set(2007, 0, 1);
        System.out.println(c.getTime());
    }

}
这导致了set方法:

public final void set(int year, int month, int date)
{
    set(YEAR, year);
    set(MONTH, month);
    set(DATE, date);
}

这里有趣的部分是computeFields()方法,它有两个实现(一个用于Gregorian,一个用于Japenese calendar)。这些方法相当复杂,但据我所知,这是您的日历实例在您的用例中可能更改时区的唯一地方。

您问题的第二个输出是运行爱尔兰时间(欧洲/都柏林)的JVM上的正确和预期行为。2017年9月12日,爱尔兰进入夏季时间(DST)。虽然没有明确的文档记录,
Date.toString()
(在打印从
c.getTime()
获得的
Date
时隐式调用该函数)打印JVM时区中的日期和时间,该时区在9月份呈现为爱尔兰夏季的IST

当您在
日历
对象上使用爱尔兰时间设置日期时,将保留一天中的小时数;在你的情况下,你得到2007年1月1日12:36:24爱尔兰标准时间。现在想象一下,如果爱尔兰夏季时间和爱尔兰标准时间都被视为IST,那会有多混乱。你将无法分辨。相反,由于爱尔兰标准时间与格林尼治标准时间一致,因此当日期不在一年中的夏季(一月不是)时,这就是
Date.toString()
打印的内容

我的猜测是,您的第一个输出来自一个在印度运行的JVM。它也被渲染为IST,由于印度不使用夏季时间,所以相同的缩写被命名为summer和winter

java.time 在理解您观察到的行为的解释之前,我发表了一篇关于过时和现代Java日期和时间类的评论。不过,我仍然不认为这一评论有什么不妥。这是代码的现代等价物:

public void set(int field, int value)
{
    // If the fields are partially normalized, calculate all the
    // fields before changing any fields.
    if (areFieldsSet && !areAllFieldsSet) {
        computeFields();
    }
    internalSet(field, value);
    isTimeSet = false;
    areFieldsSet = false;
    isSet[field] = true;
    stamp[field] = nextStamp++;
    if (nextStamp == Integer.MAX_VALUE) {
        adjustStamp();
    }
}
它打印

    ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Europe/Dublin"));
    System.out.println(zdt);
    zdt = zdt.with(LocalDate.of(2007, Month.JANUARY, 1));
    System.out.println(zdt);
如果要使用JVM的时区设置,请使用
ZoneId.systemDefault()
而不是
ZoneId.of(“欧洲/都柏林”)
。正如名称所述,
Date
与之相反,
ZonedDateTime
包含时区。它更多地对应于旧的
日历
类。如您所见,其
toString
方法以明确的地区/城市格式打印UTC的偏移量(
Z
表示零偏移量)和时区名称。我相信这会减少混乱的空间。如果要以特定格式打印日期,请使用
DateTimeFormatter

附录:代码的示例输出 为完整起见,以下是运行不同时区时代码的输出,这些时区可能呈现为IST:

  • 欧洲/都柏林(同意您的第二次输出)

  • 亚洲/特拉维夫

    Tue Sep 12 11:19:28 IST 2017
    Mon Jan 01 11:19:28 GMT 2007
    
  • 亚洲/加尔各答(同意您的第一个输出)


则另一台机器上的默认时区不同。检查系统的时区配置。日期没有时区,如果要更改日历的时区,您需要使用日历的时区。设置时区(时区)。如果对你有帮助的话。我完全肯定,并反复核对了各种情况。无法透露在哪里,但我仍然看不到相同的行为。i、 例如,在同一个*JVM上运行的两个不同java类中getTime()的两个不同输出感谢您的响应。在第一种情况下,我没有设置时区。但是,我仍然可以在默认时区打印date对象。我需要知道为什么这两种情况不同。我希望能够找到差异的根本原因。我有这种方法作为解决此问题的备份解决方案。但是,我实际上想知道这一切的根本原因。再次感谢您的快速响应:)是的,您可以更改JVM的默认时区。从而破坏了您自己的程序和JVM中运行的其他程序的功能。注意,谢谢你的建议,先生@OleV.V。让我试试这个。@UDID恐怕我们彼此没有正确地理解对方。这个想法是你的,你写了
TimeZone.setDefault(TimeZone.getTimeZone(“IST”)。我警告你,这很有趣,但并不相关。
Calendar
对象包含一个时区,但是由
getTime()
返回的
Date
对象不包含相同的时区-仅仅因为它根本不包含任何时区。@OleV.V。也许我遗漏了什么:在两个print语句之间的某个地方,时区发生了变化(至少输出显示了类似的情况)。发生了三件事:1。调用日历的set(int,int,int)方法2。调用calendars getTime()方法3。对日期的toString()方法的隐式调用。我写道,时区的内部状态可以通过第一次通话来改变。或者我是。如果我们假设
日历的内部时区状态为
Tue Sep 12 11:19:28 IST 2017
Mon Jan 01 11:19:28 GMT 2007
Tue Sep 12 13:19:28 IDT 2017
Mon Jan 01 13:19:28 IST 2007
Tue Sep 12 15:49:28 IST 2017
Mon Jan 01 15:49:28 IST 2007