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

为什么AWST和CCT的时间不一样?

汪鸿志
2023-03-14

我编写了一个名为“dateutils”的静态类,这里是一个名为“parsedate(String)”的静态方法,它将使用一些模式将字符串转换为日期。默认时区为亚洲/上海(我在中国)

public static final TimeZone SHA = TimeZone.getTimeZone("Asia/Shanghai");  

并将其传递给方法timeZone.setDefault(timeZone);并使用SimpleDateFormat来协调字符串。匹配的模式应该是“EEE,dd MMM yyyy HH:MM:SS ZZZ”,这里有三个测试。

//this one is ok.
@Test
public void testParseGMTDate() throws Exception {
    Date date = DateUtils.parseDate("Thu, 02 Aug 2016 08:12:34 GMT");
    assertNotNull(date);
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    log.debug(DateUtils.format(cal.getTime()));
    assertEquals(cal.get(Calendar.YEAR), 2016);
    assertEquals(cal.get(Calendar.MONTH), 8 - 1);
    assertEquals(cal.get(Calendar.DATE), 2);
    assertEquals(cal.get(Calendar.HOUR_OF_DAY), 8 + 8);
    assertEquals(cal.get(Calendar.MINUTE), 12);
    assertEquals(cal.get(Calendar.SECOND), 34);
    assertEquals(DateUtils.format(cal.getTime()), "2016-08-02 16:12:34");
}
// AWST is GMS+8:00 time so this one is ok.
@Test 
public void testParseWSTDate() throws Exception {
    Date date = DateUtils.parseDate("Thu, 02 Aug 2016 08:12:34 AWST");
    assertNotNull(date);
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    log.debug(DateUtils.format(cal.getTime()));
    assertEquals(cal.get(Calendar.YEAR), 2016);
    assertEquals(cal.get(Calendar.MONTH), 8 - 1);
    assertEquals(cal.get(Calendar.DATE), 2);

    assertEquals(cal.get(Calendar.HOUR_OF_DAY), 8);
    assertEquals(cal.get(Calendar.MINUTE), 12);
    assertEquals(cal.get(Calendar.SECOND), 34);
}

// junit.framework.AssertionFailedError: 
// Expected :9
// Actual   :8
@Test
public void testParseDateCCT() throws Exception {
    Date date = DateUtils.parseDate("Thu, 02 Aug 2016 08:12:34 CCT");
    assertNotNull(date);
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);
    log.debug(DateUtils.format(cal.getTime()));
    assertEquals(cal.get(Calendar.YEAR), 2016);
    assertEquals(cal.get(Calendar.MONTH), 8 - 1);
    assertEquals(cal.get(Calendar.DATE), 2);

    assertEquals(cal.get(Calendar.HOUR_OF_DAY), 8); //Expected: 9
    assertEquals(cal.get(Calendar.MINUTE), 12);
    assertEquals(cal.get(Calendar.SECOND), 34);
}
public static final TimeZone SHA = TimeZone.getTimeZone("Asia/Shanghai");
static {
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeZone(SHA);
    calendar.set(2000, 0, 1, 0, 0, 0);
    calendar.set(MILLISECOND, 0);
    TWO_DIGIT_START = calendar.getTime();

}
public static Date parseDate(String dateValue) {
    return parseDate(dateValue, null, null, SHA);
}
public static Date parseDate(String dateValue, String[] dateFormats, Date startDate, TimeZone timeZone) {
        TimeZone.setDefault(timeZone);
        String[] localDateFormats = dateFormats != null ? dateFormats : DEFAULT_PATTERNS;
        Date localStartDate = startDate != null ? startDate : TWO_DIGIT_START;
        String v = dateValue;
        if (dateValue.length() > 1 && dateValue.startsWith("\'") && dateValue.endsWith("\'")) {
            v = dateValue.substring(1, dateValue.length() - 1);
        }

        String[] arr = localDateFormats;
        int len = localDateFormats.length;

        for (String dateFormat : DEFAULT_PATTERNS) {
            //            String dateFormat = arr[i];
            SimpleDateFormat dateParser = DateUtils.DateFormatHolder.formatFor(dateFormat);
            dateParser.set2DigitYearStart(localStartDate);
            ParsePosition pos = new ParsePosition(0);
            Date result = dateParser.parse(v, pos);
            if (pos.getIndex() != 0) {
                _LOG.debug("Date parsed using: {}", dateFormat);
                return result;
            }
        }

        _LOG.error("Can't parse data: {data:{}, formats:{}, startDate:{},tz:{}}",
                dateValue, localDateFormats, localStartDate, TimeZone.getDefault());
        return null;
    }

共有1个答案

郁鸿博
2023-03-14

你犯了三个错误:

  • 使用了非标准非唯一伪时区3-4个字母缩写
  • 然后继续错误地假定它们的意思
  • 使用陈旧的Java类进行日期-时间处理。

相反,使用大陆/区域格式的适当时区名称。研究那些区域的文档意义,而不是假设/猜测。对于日期-时间工作,只使用java.time类。

要了解更多信息,请参阅Oracle教程。并搜索堆栈溢出以获得许多示例和解释。

大部分Java.time功能在ThreeTen-Backport中后端移植到Java6&7中,并在ThreetenABP中进一步适应Android。

instant类是以UTC(GMT)表示的时间线上的一个时刻,分辨率可达纳秒。

Instant instant = Instant.parse ( "2016-08-02T08:12:34Z" ); // 02 Aug 2016 08:12:34
ZoneId zoneId_Perth = ZoneId.of ( "Australia/Perth" );
ZonedDateTime zdt_Perth = instant.atZone ( zoneId_Perth );
ZoneId zoneId_Shanghai = ZoneId.of ( "Asia/Shanghai" );
ZonedDateTime zdt_Shanghai = zdt_Perth.withZoneSameInstant ( zoneId_Shanghai );
ZoneId zoneId_Cocos = ZoneId.of ( "Indian/Cocos" );
ZonedDateTime zdt_Cocos = zdt_Perth.withZoneSameInstant ( zoneId_Cocos );

根据一条评论,你可能指的是北京时间。如果是的话,要知道根据维基百科中的这个列表,北京时间被亚洲/上海时区覆盖。

转储到控制台。您可以看到,珀斯和上海都比今年8月的UTC提前了8个小时,一天中的一个小时是16对8(16:12:3408:12:34)。科科斯群岛介于两者之间,在14:42:34比协调世界时提前6.5小时。

System.out.println ( "instant: " + instant + " | zdt_Perth: " + zdt_Perth + " | zdt_Shanghai: " + zdt_Shanghai + " | zdt_Cocos: " + zdt_Cocos );

即时:2016-08-02T08:12:34Z ZDT_珀斯:2016-08-02T16:12:34+08:00[澳大利亚/珀斯]ZDT_上海:2016-08-02T16:12:34+08:00[亚洲/上海]ZDT_可可:2016-08-02T14:42:34+06:30[印度/可可]

若要以此处显示的标准ISO 8601格式以外的格式生成字符串,请使用DateTimeFormatter类。

DateTimeFormatter f = DateTimeFormatter.ofLocalizedDateTime( FormatStyle.FULL );
f = f.withLocale( Locale.CHINA );
String output = zdt_Shanghai.format( f );
 类似资料:
  • 尽管有值,但我不能得到一个用户的值的和时间。 即使用户17有工作时间值,我也会在sumTW列中得到该用户的NULL值。我该怎么解决? 这就是我的查询看起来的样子: 下面是表格代码: (这个表和原来的不一样,原来的有外键。我去掉它们只是为了能够再现同样的问题,同样的问题被报告了)。

  • 问题内容: 因此,如果我有一个,由于某种原因,如果我在另一段代码(如)中引用它,则在编译过程中它不会内联到代码中。因此,它不是在被编译之后而是。 问题答案: 您不是编译时间常数,因为JLS 表示 不是。只能在常量表达式中使用的类型是基本类型和。 它的意义是,一个实例(通常)具有语义上重要的对象标识,该标识将其与其他实例区分开。此对象标识不能编码在类文件中……至少,不能用当前的类文件格式编码。(如果

  • 考虑浮点数0.644696875。让我们用Java和C把它转换成八位小数的字符串: 结果:0.64469688 自己试试吧:http://tpcg.io/oszC0w 结果:0.64469687 自己试试吧:http://tpcg.io/fQqSRF 为什么最后一个数字不同? 数字0.644696875不能精确地表示为机器号。它表示为分数2903456606016923/4503599627370

  • 问题内容: 当您添加 在命令行中,JVM给您提供了一个接近此值的堆,但最多可以出14%。JVM可以使您更接近所需的数字,但只能通过反复试验才能实现。 版画 我正在运行HotSpot Java 8 Update 5。 显然,堆可以在上面,但是为什么要这样而不是说呢? BTW == 表示应该为1024 ^ 3,比1000 ^ 3高7%,但您得到的东西比1000 ^ 3低7%。 太多的变化表明我缺少关于

  • 输出 pytz 只支持 上海时间,不支持 北京时间 但是上海时间有一个很恶心的地方,会比北京时间多 6 分钟 同样的问题,在我使用一些 linux 发行版(带GUI)的时候,也遇到过这样的问题,只能设置上海时间,没有北京时间可以选 why?是有什么国际法规定吗? 不过 python3.9 内置的 zoneinfo,但是不会出现多 6 分钟的问题 输出如下:

  • 添加时 对于命令行,JVM会给出一个接近于该值的堆,但最多可以超出14%。JVM可以给出一个更接近您所想要的数字,但只能通过反复试验。 显然,堆可以是上面的东西,但为什么这个而不是呢? BTW==表示应为1024^3,比1000^3高7%,但您得到的值比1000^3低7%。 偏离了这么多,表明我缺少了关于堆工作方式的一些基本知识。如果我请求-xmx1000m,而它是我不会在意,我会假设它需要遵守某