問題描述
我需要將 .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 天的文章就介紹到這了,希望我們推薦的答案對大家有所幫助,也希望大家多多支持html5模板網!