我需要在原生 Android 应用和基于 .NET 的时间戳之间进行高精度时间转换。
.NET 端简单地使用:
long timeNowTicks = System.DateTime.UtcNow.Ticks;
而且我需要在 Android 端将此 .NET 时间戳匹配到 5 分钟(30 亿滴答)以内。我无法更改 .NET 内容。
我试过:
GregorianCalendar oldUtcTime = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
GregorianCalendar nowUtcTime = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
oldUtcTime.set(1,1,1,0,0,0); // .NET epoch
long utcTicks = 10000 * (nowUtcTime.getTimeInMillis() - oldUtcTime.getTimeInMillis()); // 10,000 ticks per ms
但这始终为我提供了一个大约 250 万秒(~20 天)落后于 DateTime.UtcNow.Ticks 的数字。
Some people说这是因为即使 DateTime 声称遵守公历,他们实际上并没有跳过教皇添加到日历中以在 1500 年代修复它的 10 天,但我在任何地方都找不到一个包罗万象的公式-like 两者之间的转换。
如何在 native Android 时间和 .NET DateTime 之间获得大约 5 分钟的精度?
最佳答案
是的,我相信GregorianCalendar
确实观察到 Julian/Gregorian 切换 - 虽然我注意到你正在设置 oldUtcTime
到公元 1 年的 2 月 1 日,这可能就是您看到 20 天而不是 10 天的差异的原因。
执行此操作的最简单方法是使用 .NET 在毫秒内找出 Unix 纪元 - 然后将其用作 Java 端的常量:
// Handy method in .NET 4.6...
var unixEpoch = DateTimeOffset.FromUnixTimeSeconds(0);
Console.WriteLine(unixEpoch.Ticks / 10000L);
这给出了 62135596800000 的输出。那么你需要:
private static final long BCL_MILLISECONDS_AT_UNIX_EPOCH = 62135596800000L;
private static final long TICKS_PER_MILLISECOND = 10000L;
...
long bclMillis = System.currentTimeMillis() + BCL_MILLISECONDS_AT_UNIX_EPOCH;
long bclTicks = TICKS_PER_MILLISECOND * bclMillis;
请注意,这并不是真正的“高精度”——它只会与每一侧的系统时钟一样准确。对于真正准确的时间,您需要使用 NTP 或类似的东西。您仍然可以发现两个时钟已经超过 5 分钟,只是因为如果时钟没有自动更正,它们会随着时间漂移...
关于java - Android (Java) 和 .NET DateTime 之间的高精度时间同步?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33876839/