当前位置: 首页 > 知识库问答 >
问题:

Tz.InDaylightTime(new Date())为ID:-Asia/Choibalsan的时区GMT+8返回true(错误

西门骁
2023-03-14

时区问题:-北京、重庆、香港、乌鲁木齐(GMT 8)

在Debug中获取上述时区的ID:-[南极洲/凯西,亚洲/文莱,亚洲/赤塔,亚洲/乔巴山,亚洲/重庆,亚洲/重庆,亚洲/哈尔滨,亚洲/香港,亚洲/伊尔库茨克,亚洲/库拉山-隆坡,亚洲/古晋,亚洲/澳门,亚洲/澳门,亚洲/望加锡,亚洲/马尼拉,亚洲/上海,亚洲/新加坡,亚洲/台北,亚洲/乌荣-潘丹,亚洲/乌兰巴托,亚洲/乌兰巴托,澳大利亚/珀斯,澳大利亚/西部,CTT,ETC/GMT-8,中国香港,新加坡]

问题:-tz.indaylighttime(new Date())为id Asia/Choibalsan返回true并给出3600000日光差。因此,它的显示时间比香港用户提前1小时。因为它增加了3600000作为日光节约差

这是错误的,因为香港时区的夏令时为“否”。“tz.InDaylightTime()”在此处应返回false。

这个isssue将在linux服务器JDK8上进行生产。

它是用JDK8在windows上的本地系统上工作的。

我的参考代码:-

public static String setDateTimeInTimezone(Date date, String userTimeZone) {
    int offset = parseTimeZone(userTimeZone);
    DateFormat formatter = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss");

    int timezoneDSTSaving = 0;
    String[] timeArray = TimeZone.getAvailableIDs(offset);
    TimeZone tz=null;
    for (int i = 0; i < timeArray.length; i++) {
        tz = TimeZone.getTimeZone(timeArray[i]);
        if (tz.inDaylightTime(new Date())) {
            timezoneDSTSaving = tz.getDSTSavings();
        }
        if (timezoneDSTSaving != 0) {
            break;
        }
    }
    //formatter.setTimeZone(tz);
    return formatter.format(new Date(date.getTime() + offset + timezoneDSTSaving));
}

public static int parseTimeZone(String userTimeZone) {
    // Represent GMT String used to display user time zone.
    final String gmtStringConstant = GMT_OFFSET_STRING;
    // Represent 60 minute in a hour.
    final int minutes = 60;
    // Represent 60 seconds in minute.
    final int seconds = 60;
    // Represent 1000 milli seconds in second.
    final int milliseconds = 1000;
    int timezoneDifference = 0;
    int gmtIndex = userTimeZone.indexOf(gmtStringConstant);
    // If "(GMT" String is not found in timezone, return 0.
    if (gmtIndex == -1) {
        return timezoneDifference;
    }
    String timeZone = userTimeZone.substring(gmtIndex + gmtStringConstant.length(), userTimeZone.length() - 1);
    int indexOfColon = timeZone.indexOf(":");
    if (indexOfColon != -1) {
        int hourDiff = Integer.parseInt(timeZone.substring(0, indexOfColon)) * minutes * seconds * milliseconds;
        int minDiff = Integer.parseInt(timeZone.substring(indexOfColon + 1)) * seconds * milliseconds;
        if (hourDiff < 0) {
            minDiff *= -1;
        }
        timezoneDifference = hourDiff + minDiff;
    } else {
        timezoneDifference = Integer.parseInt(timeZone) * minutes * seconds * milliseconds;
    }
    return timezoneDifference;
}

注意:我不想使用ZODATIME,我只想用util date处理

共有1个答案

郏稳
2023-03-14
  • DST在亚洲/Choibalsan中一直有效,直到2016-09-23遵守停止。现在全年偏移量为+08:00
  • 您正在使用糟糕的日期-时间类,现在应该避免。

注意:我不想使用ZODATIME,我只想用util date处理

当JSR310被采用时,可怕的java.util.date类几年前就被现代的java.time类所取代。

将所需的时区指定为zoneid对象。

ZoneId z = ZoneId.of( "Asia/Choibalsan" ) ;

获取该区域的规则、该区域的人员使用的偏移量的过去、现在和将来更改的历史记录。获取zoneRules对象。

ZoneRules rules = z.getRules() ;

指定要确定DST是否有效的时刻。你是在4月6日16时12:32问这个问题的,所以让我们利用那个时刻。

LocalDate ld = LocalDate.of( 2016 , Month.APRIL , 6 ) ;
LocalTime lt = LocalTime.of( 12 , 32 ) ;
ZonedDateTime zdt = ZonedDateTime.of( ld , lt , z ) ;

ZDT.ToString():

通过提取即时调整为UTC。

Instant instant = zdt.toInstant() ;  // Extract a `Instant`, adjusting from time zone to UTC.

询问DST在那个区域是否有效。

boolean inDst = rules.isDaylightSavings​( instant ) ;

并询问DST调整的量是多少(如果DST有效)。

Duration d = rules.getDaylightSavings​( instant ) ;

请参阅ideone.com上的code run live。

ZDT.ToString():2016-04-06T12:32+09:00[亚洲/乔巴山]

Instant.ToString():2016-04-06T03:32:00Z

indst.ToString():true

我们得到的一个结果是,此刻asia/choibalsan确实在DST中。

让我们试试当前时刻。

System.out.println(
    ZoneId
    .of( "Asia/Choibalsan" )
    .getRules()
    .isDaylightSavings( 
        Instant.now() 
    )
);

我们得到false,当前不在DST中。这与Time.is网站的报告一致,目前不在DST网站,同时也声称+08:00Asia/Choibalsan的全年偏移量。

这些结果与本网站的报告一致,即该时区的DST观测被取消,最后一次DST转换是在2016年9月23日。

 类似资料:
  • 问题内容: 我有一个遗留应用程序,我将需要补充一些数据。当前,我们有一个数据库表,用于存储美国(及其地区)邮政编码,GMT偏移量以及一个标志,用于显示该邮政编码是否使用夏时制。这是从某个免费提供商处下载的,我现在找不到源。 现在,我需要用每个邮政编码的完整奥尔森名称(例如)来补充此表,因为这似乎是将存储在数据库中的给定日期/时间(对于该购买者而言本地的)转换为对象的唯一好方法。 看一下桌子: 在另

  • 问题内容: 据我所知,使用或实例化对象分别返回或的新实例。具有 新标识 的新实例对象。 在我实际测试它之前,这对我来说是很清楚的,我注意到它实际上返回了而不是预期的: 如预期的那样,分别使用和创建对象时,也会表现出这种行为: 我可以在状态文档中找到唯一相关的信息: […]例如,return和return 。 如果未提供任何参数,则构造函数将创建一个新的空元组。 可以说,这不足以回答我的问题。 那么

  • 问题内容: 如果我这样做: 那又回来了。仅仅是因为在列表中。 但是,如果我这样做: 那又回来了。而等于: 为什么? 问题答案: 运算符优先级 2.x,3.x。的优先级低于的优先级。因此,它等效于: 这就是你想要的: 正如@Ben指出的那样:建议从不写作,更喜欢。前者使它看起来像一个函数调用,而它却是一个运算符,而不是一个函数。

  • 我想以秒为单位获取差异,以确定系统时区是在远程时区的前面还是后面。这里的远程时区值是从数据库中获取的“格林尼治标准时间”。它可能是“美国/东方”,我将其转换为“美国/New_York”。但是对于格林尼治标准时间,我得到了错误。 但它给出了以下错误, 如何解决此错误?用什么代替GMT??

  • 问题内容: 无论计算机上设置的时区如何,我都需要对GMT / UTC进行任何与时间相关的操作。在代码中有任何方便的方法吗? 为了明确起见,我将所有操作都使用数据库服务器时间,但是它是根据本地时区格式化的。 谢谢! 问题答案: OP回答了这个问题,以更改正在运行的JVM的单个实例的默认时区,并设置系统属性: 如果从数据库检索Date / Time / Timestamp对象时需要设置特定的时区,请使

  • 与许多Web应用程序一样,我正在开发的应用程序需要为我们亲爱的最终用户转换时区。然而,当我在PHP 5.3中使用Carbon/DateTime时,我发现这很奇怪: 我将的时区设置为GMT 5,但是当我格式化时,它变成,而不是预期的。 同样,如果我将其设置为负数,即,则格式显示而不是预期的。 有人能开导吗? 我能够在PHP5.3.3、5.3.13、5.3.28中复制这个问题。认为这是一个PHP特定的