- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在开发一部分代码,其中我必须使用日历 API 使用现有的 api,而我使用的是全新的 API。在转换中出现了一些奇怪的行为,请看这个例子:
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssX");
String date1 = "0000-01-01T00:00:00Z";
Calendar calendar = Calendar.getInstance();
calendar.setTime(df.parse(date1));
Instant instant = calendar.toInstant();
ZonedDateTime zonedDateTime = instant.atZone(calendar.getTimeZone().toZoneId());
System.out.println(calendar.getTime() + " " +calendar.getTimeZone().getDisplayName());
System.out.println(instant.toString());
System.out.println(zonedDateTime.toString());
String date2 = "0000-01-01T00:00:00+01:00";
calendar.setTime(df.parse(date2));
instant = calendar.toInstant();
zonedDateTime = instant.atZone(calendar.getTimeZone().toZoneId());
System.out.println(calendar.getTime() + " " +calendar.getTimeZone().getDisplayName());
System.out.println(instant.toString());
System.out.println(zonedDateTime.toString());
我得到的输出如下:
Thu Jan 01 01:00:00 CET 1 Central European Standard Time
-0001-12-30T00:00:00Z
-0001-12-30T00:09:21+00:09:21[Europe/Paris]
Thu Jan 01 00:00:00 CET 1 Central European Standard Time
-0001-12-29T23:00:00Z
-0001-12-29T23:09:21+00:09:21[Europe/Paris]
因此公历的第一行对于这两种情况都是正确的:
从 Calendar
转换为 Instant
后,我们已经看到日期有问题,因为我们现在突然:
现在,当我们将 next 从 Instant
转换为 ZonedDateTime
时,我们现在就是
instant.atZone()
导致奇怪的时区 +00:09:21我对它进行了更多测试,一般来说,Calendar
和 Instant
之间的转换对于 1583 年之前的日期变得非常不可靠,而 Instant
到 由于 1911 年之前的日期存在时区问题,Local/ZonedDateTime
变得不可靠。
现在我知道几乎没有人将时间存储/转换为 1911 年之前的日期(但我仍然可以想象这样的用例),但是嘿!让我们看看克里斯托弗·哥伦布是什么时候出发去发现美洲的!
1492-08-03
1492-08-11T23:00:00Z
1492-08-11
因此,我还发现,对于 1911 年之前的早年相同的 ISO 日期,从两个 api 获取 epoch millis 会产生不同的结果(问题似乎出在Calendar 实现中):
System.out.println(Instant.parse("1911-01-01T00:00:00Z").toEpochMilli());
calendar.setTime(df.parse("1911-01-01T00:00:00Z"));
System.out.println(calendar.getTimeInMillis());
正确的转换方式是什么才能“正常工作”(tm)?
注意:到目前为止,我认为最安全的方法是先转换为 ISO 日期字符串。有没有更好的解决方案?
最佳答案
您显示的所有计算都是完全正确的,因为它们保留了以 UTC 表示的瞬间/时刻并使用了公历日期。然而:
期望时区在 1900 年左右的历史引入之前的任何时间都适用是一种非历史的胡说八道。鉴于此,我们不应该尝试比较历史日期的日期和时间表示,而应该只比较瞬间。
在这种情况下,我们甚至应该走得更远更好将自己限制在日期精度而不是日期时间精度。那就是我们最好只讨论日期转换。没有人以毫秒甚至更精确的精度记录历史日期,因为不存在这样精确的时钟。
时区的另一个技术方面是旧的 Java 时区(使用 java.util.TimeZone
)和新类 ZoneId
确实使用不同的规则集在您的示例中的 1911 年之前的几年,因为由 IANA(作为 Java 区域的基础)管理的原始 tz-data-repository 中所谓的 LMT 行的处理方式不同。据我所知,来自 Oracle 的 Xueming Chen had once mentioned the year 1900 as cutting date对于旧的 Java 区域,何时应用 LMT(任意选择的城市的本地平均时间)以及何时应用正常的区域时间。欧洲/巴黎等一些区域甚至在 1900 年之后才引入,因此它们仍然显示 LMT 时间。这解释了像 9 分 21 秒这样的差异。详细地说,actual rules for Paris是:
Zone Europe/Paris 0:09:21 - LMT 1891 Mar 16
0:09:21 - PMT 1911 Mar 11 # Paris Mean Time
# Shanks & Pottenger give 1940 Jun 14 0:00; go with Excoffier and Le Corre.
0:00 France WE%sT 1940 Jun 14 23:00
# Le Corre says Paris stuck with occupied-France time after the liberation;
# go with Shanks & Pottenger.
1:00 C-Eur CE%sT 1944 Aug 25
0:00 France WE%sT 1945 Sep 16 3:00
1:00 France CE%sT 1977
1:00 EU CE%sT
这意味着,java.util.TimeZone
对 1911 年之后的所有历史日期应用第一条非 LMT 线(PMT 线由于偏移量不变而被忽略),因为切割年份为 1900 年。但是 ZoneId
使用 LMT 行 - 如您的示例所示。
我们看到,不同的处理是一种任意选择的技术实现策略,用于处理分区日期时间,即使是在人们拥有精确时钟并且根本不知道时区概念之前的历史时刻。
那是关于时区的事情,现在我们来谈谈日期转换的处理。
新的 java.time
-package 只使用 proleptic gregorian dates,即使是在没有人知道 gregorian date 是什么的日期。这样的日期是在 1582 年由 Pope Gregor 首次引入的。他砍掉了 10 天(因此 1582 年的 10 月 5 日到 10 月 14 日的日期不存在)并引入了一个不同于旧儒略历规则的闰年规则。实际上,旧类 java.util.Calendar
将 1582-10-15 之前的所有日期作为 Julian 日期处理,这解释了您观察到的其他差异。如果将 10 天的截断与不同的闰年规则结合起来,那么您将看到 0000 年儒略历和公历之间的两天差异。
您似乎希望使用 java.time
-API 中的新类重现有关旧日期的旧行为。嗯,这是不可能的。不是新 API 中的错误,而只是限制为公历日期而不支持 Julian 日历日期的设计决定。
尽管如此,如果您坚持要查看 1583 年之前的 Julian 日期并避免使用 java.util.Calendar
或 SimpleDateFormat
等旧类,那么您可以使用我的库 Time4J它具有到 java.time
-API 的转换方法,并为您的哥伦布示例(西类牙出发日)使用这样的代码:
ChronoHistory history =
ChronoHistory.ofFirstGregorianReform(); // the same behaviour like in old Java
ChronoFormatter f =
ChronoFormatter
.ofPattern("yyyy-MM-dd", PatternType.CLDR, Locale.ROOT, HistoricCalendar.family())
.withDefault(HistoricCalendar.ERA, HistoricEra.AD)
.with(history);
HistoricCalendar expected =
HistoricCalendar.of(history, HistoricEra.AD, 1492, 8, 3);
assertThat(
f.parse("1492-08-03"), // date of departure of Columbus to America
is(expected));
assertThat(
expected.transform(PlainDate.axis()), // transformation to gregorian
is(PlainDate.of(1492, 8, 12)));
// conversion to java.time-API
LocalDate threetenAlwaysGregorian = PlainDate.of(1492, 8, 12).toTemporalAccessor();
您的转换导致 1492-08-11(一天前)的事实只是由于时区效应。为避免此类情况,您确实应该限制日期精度,或者如果不可能,您至少应该在中午而不是午夜转换日期。
关于java - java Calendar.toInstant() 和 Instant.atZone(还有 Local/ZonedDateTime.ofInstant())中的不准确性/随机性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62712678/
我使用以下代码来查看用户在特定页面上的停留时间。我为此脚本使用了带有 src 属性的隐藏图像: $timer_seconds = 1; while(!connection_aborted()) {
我在 Keras 中使用自定义损失函数: def get_top_one_probability(vector): return (K.exp(vector) / K.sum(K.exp(vect
当我使用 long 来节省一个月毫秒时,我发现一个问题。但我打印负数。所以我做了一个测试 代码如下: LogUtils.d(TAG, "long max time:"+Long.MAX_VALUE);
关于使用 Lenet5 网络解释某些优化器在 MNIST 上的性能,我有几个问题,以及验证损失/准确性与训练损失/准确性图表究竟告诉我们什么。所以一切都是在 Keras 中使用标准的 LeNet5 网
我有 1000 个 pdf(每个 200 页)。 我需要将每个 pdf 添加到 Azure 搜索索引中的索引(作为小文本 block 和相关元数据,例如每个 pdf 200 个 block ) 已达到
我必须在 mssql 数据库中存储一些间隔。我知道日期时间的准确性约为。 3.3ms(只能结束0、3、7)。但是当我计算日期时间之间的间隔时,我发现结果只能以 0、3 和 6 结尾。所以我总结的间隔越
我想制作一个需要将位置精确到大约 1m 或更小的 Android 应用程序。“Fused Location Manager API”是否足够好,或者 GPS 永远不会如此准确,无论是否与其他传感器融合
我想使用 pySerial 的 serial.tools.list_ports.comports() 列出可用的 COM 端口。 阅读documentation : The function retu
使用 pyomo 和 glpk 求解器,我定义了以下目标规则: def cost_rule(m): return (sum(m.rd[i]*m.pRdImp*m.dt - m.vr[i]*m.
我正在遵循“Lucene in Action”中的示例,第 308-315 页,它描述了 Lucene Spatial。我正在使用 lucene 2.9.4。我用过 http://geocoder.u
我一直在试验各种计时方法的代码。创建延迟的一种方法是使用thread.sleep(millis)运行线程,但可以很好地说明,线程“唤醒”的时间并不完全准确,可能在这个时间之前或之后。然后我遇到一个定义
我在使用 boost::sleep() 函数时遇到奇怪的问题。我有这个基本代码: #include #include #include void thread_func() { time
数字示例 我正在使用标准的 pytesseract img 来发送文本。我尝试过仅使用数字选项,90% 的情况下它是完美的,但上面是一个非常错误的例子!这个例子根本没有产生任何字符 如您所见,现在有字
我想从 python 中的图像中提取文本.为了做到这一点,我选择了 pytesseract .当我尝试从图像中提取文本时,结果并不令人满意。我也经历过this并实现了列出的所有技术。然而,它的表现似乎
在每个时代结束时,我得到例如以下输出: Epoch 1/25 2018-08-06 14:54:12.555511: 2/2 [==============================] - 86
我想为我的移动项目需求之一实现条形码。要存储的数据量非常少(<25 个字母数字)。我想知道对于这个项目实现一维条形码或二维条形码(特别是二维码)是否更明智。如果有人能从 1d 与 2d 的角度对我进行
想象一个二元分类问题。假设我在 pred_test 中存储了 800,000 个预测概率。我将 cutoff 定义为 pred_test 中的任何值,以便大于或等于 cutoff 的值被分配值 1 和
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
我正在使用 iBeacon 和 Altbeacon 测试定位系统。我发现我的三角测量结果实际上非常准确,但有时需要 5 秒以上才能看到正确的结果。 例如,假设我目前正站在A点。 Altbeacon +
因此,我有 2 个独立的数据表,它们看起来非常相同,但它们行中的值可能不同。 编辑: 我可以通过创建一个可以用作主键的临时标识列来获得唯一 ID,如果这样做更容易的话。所以将 ID 列视为主键。 表A
我是一名优秀的程序员,十分优秀!