问题描述
我需要将 .NET DateTime
转换为等效的 Java Calendar
表示.
I need to transform a .NET DateTime
to an equivalent Java Calendar
representation.
.NET DateTime
使用 Jan 1st 0001(.NET 纪元)以来的 Ticks
作为基础表示.
The .NET DateTime
uses Ticks
since Jan 1st 0001 (the .NET epoch) as the underlying representation.
Java GregorianCalendar
使用自 1970 年 1 月 1 日(Java(或 Unix)纪元)以来的毫秒数.正如预期的那样,对于 Java 纪元之前的日期,该值为负数.
The Java GregorianCalendar
uses milliseconds since Jan 1st 1970 (the Java (or Unix) epoch). The value is negative for dates before the Java epoch, as expected.
自 Java 纪元以来,我在这里以毫秒为单位转换 DateTime
表示:
Here I'm transforming the DateTime
representation in millis since the Java epoch:
var dt = new DateTime(1,2,3); //way, way back.
var javaEpoch = new DateTime(1970, 1, 1);
var javaMillis = (dt - javaEpoch).Ticks / TimeSpan.TicksPerMillisecond;
dt.ToString("MM/dd/yyyy").Dump(); // .Dump() is provided by LinqPad.
javaMillis.Dump(); // Use Console.WriteLine(...)
// for a regular console app.
这个输出:
02/03/0001
-62132745600000
02/03/0001
-62132745600000
现在复制粘贴此 Java 代码段中的毫秒值:
Now copy-paste the milliseconds value in this Java snippet:
java.util.Calendar cal = new java.util.GregorianCalendar();
cal.setTimeInMillis(-62132745600000L);
java.text.SimpleDateFormat df = new java.text.SimpleDateFormat();
df.applyPattern("MM/dd/yyyy");
System.out.println(df.format(cal.getTime()));
这个输出:
02/05/0001
我想我的问题是:我应该如何从 DateTime 中获取有效的毫秒值,然后我才能正确地构造 Java 日历?
I guess my question is: How am I supposed to get a valid milliseconds value from a DateTime, from which I can correctly construct a Java Calendar?
...带有隐含的子问题这里到底发生了什么?"
...with the implied sub-question "what is really going on in here?"
我在从儒略历到公历的缺失日期范围内使用 DateTimeValues(1582 年 10 月 4 日紧随"1582 年 10 月 15 日).
I played with DateTimeValues around the missing date range from Julian to Gregorian calendar (Oct 4 1582 is "followed" by Oct 15 1582).
对于 1582 年 10 月 15 日之后的日期,转换似乎工作正常.
For dates more recent than Oct 15 1582, the conversion seems to work fine.
...但是在缺少的范围内,DateTime 开始(或者更确切地说,不开始)表现得滑稽:
...But around the missing range, DateTime starts (or rather, doesn't start) to act funny:
var timespan = new DateTime(1582, 10, 15) - new DateTime(1582, 10, 4);
返回 11 天的 TimeSpan
,因此 DateTime 运算符不考虑漏洞.是什么赋予了?我认为底层实现是基于System.Globalization.GregorianCalendar
.
returns a TimeSpan
of 11 days, so the hole is not taken into consideration by the DateTime operators. What gives? I thought the underlying implementation is based on System.Globalization.GregorianCalendar
.
推荐答案
回答为什么":
来自(反编译 - 感谢 dotPeek!).NET 4 源代码(评论是我的):
From the (decompiled - thanks dotPeek!) .NET 4 source code (comments are mine):
public static DateTime operator -(DateTime d, TimeSpan t)
{
//range checks
long internalTicks = d.InternalTicks;
long num = t._ticks;
if (internalTicks < num || internalTicks - 3155378975999999999L > num)
throw new ArgumentOutOfRangeException("t",
Environment.GetResourceString("ArgumentOutOfRange_DateArithmetic"));
else
//plain arithmetic using the Ticks property of the two dates.
return new DateTime((ulong) (internalTicks - num) | d.InternalKind);
}
是的,对于 DateTime 运算符,绝对没有特殊的公历"处理.
So yeah, absolutely no special 'gregorian' treatment for DateTime operators.
关于如何修复":
我最终使用了一些类似的东西:(伪 Java)
I ended up using something along these lines: (pseudo-Java)
Calendar cal = new GregorianCalendar();
cal.set(dt.Year, dt.Month - 1 /*it's 0-based*/, dt.Day, dt.Hour, dt.Minute, dt.Second);
cal.set(Calendar.MILLISECOND, dt.Millisecond);
这篇关于在 java 和 .net 之间转换日期 - 休息 2 天的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!