What date is it today? Converting dates from .Net to Java and vise versa.
February 3, 2005
When it was announced that at the Ides of March the Senate is to meet in the Curia Pompeii, everybody preferred this time and place.
Do you think Brutus and Cassius were able to do better if they have all of today technology on their side? Don’t be quick with your answer.
Imagine you have two applications: one built in Java and other running in .Net environment. You want both application to use common database, you want to store dates, but you don’t want to store date objects in the database (for example, you use an ad-hoc database solution that just can not store dates).
The conversion should be done in two phases — one is quite simple and the other is tricky a bit.
First of all, the Java and .Net dates have a different starting point: zero milliseconds in Java corresponds to January 1, 1970, 00:00:00 GMT (aka “the epoch”). In .Net zero milliseconds* corresponds to 12:00 A.M., January 1, 0001 GMT.
So the basic is to bridge over the reference points gap with adding (or substracting) the corresponding number of milliseconds such that zero milliseconds in .Net is mapped to -62135769600000L
milliseconds in Java. This number of milliseconds corresponds to GMT zone, so do not forget to include your time zone offset into the calculations.
The second part is more complex. Default .Net calendar is Gregorian calendar and all of .Net date calculations rely on this calendar rules (even for the dates that are in the past relative to Gregorian calendar invention). From the other side, Java default calendar is also Gregorian calendar, but actually java.util.GregorianCalendar
implements Julian calendar for dates before October 4, 1582.
Thus, the year 1582 in Java Gregorian calendar has 10 days less that the same year in .Net Gregorian calendar and, in addition, each forth year before 1582 (excluding the century years which are not divisible by 400) in Java has one day more that the same year in .Net (because of leap year rule difference). This requires you to add or substract appropriate number of milliseconds for each date before 1582**.
* Actually .Net dates operate with ticks (100-nanosecons units), but to simplify our discussion, I always use milliseconds value, since the converting from ticks to milliseconds and vise versa is trivial.
** I still don’t know what are the actual dates in each of this years that produces the difference, so you are more than welcome to check this.
References :
- The
java.util.GregorianCalendar
documentation on Java documentation site
http://java.sun.com/j2se/1.4.2/docs/api/java/util/GregorianCalendar.html - System.DateTime documentation on MSDN
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/cpref/html/frlrfsystemdatetimeclasstopic.asp - An excellent article about Julian and Gregorian calendars by Peter Meyer
http://www.hermetic.ch/cal_stud/cal_art.html
Special thanks to :
- Konstantin Triger for the major help in research of date conversions issue.
March 14, 2007 at 3:06 pm
Hi,
I need to process in Java a binary stream containing a timestamp constructed in .NET.
I get always an offset of -2 days and I can’t understand why.
In detail, consider the following Visual C++ .NET code block:
{
DateTime dt = DateTime::UtcNow;
printf(“dtLong = %I64d\n”, dt.Ticks);
printf(“%d-%d-%d %d:%d:%d.%d\n\n”, dt.Year, dt.Month, dt.Day, dt.Hour, dt.Minute, dt.Second, dt.Millisecond);
}
example of output:
dtLong = 633094804407456576
2007-3-14 14:47:20.745
feeding my Java app with dtLong I get:
refDateLong = -62135769600000
2007-03-12 14:47:20.745 (NOTE THE -2 DAYS OFFSET)
this is the code of my java app:
{
java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat(“yyyy-MM-dd HH:mm:ss.S”);
sdf.setTimeZone(TimeZone.getTimeZone(“GMT”));
String refDateString = “0001-01-01 00:00:00.0”;
Date refDate = sdf.parse(refDateString);
long refDateLong = refDate.getTime();
System.out.println(“refDateLong = ” + refDateLong);
long timestampSince1 = 633094804407456576L;
long timestampSince2 = timestampSince1 / 10000L;
long timestamp = timestampSince2 + refDateLong;
Date date = new Date(timestamp);
System.out.println(sdf.format(date));
}
do you have any suggestion?
thanks in advance
March 18, 2007 at 7:05 am
Yes. The last paragraph of the post targets exactly this point. Let me express it in other way:
Before year 1582 there is a different number of days in .Net and Java calendars (actually, between Gregorian and Julian calendars) – Gregorian calendar (used by .Net) has one day less than Julian calendar (used by Java) in each century year that is not dividable by 400. There is 12 years like this before 1582 – so you have to add 12 days to your date in conversion.
In addition, year 1582 in Java calendar has 10 days less than .Net, so you have to subtract these 10 days in conversion – what leaves us with exactly two days gap you need to add.
March 19, 2007 at 10:15 am
Thank you, now I understand.
So, having to deal only with dates after 1582, I simply need to substract an offset of 62135596800000L millisecs.
April 11, 2008 at 10:13 am
[…] What date is it today? Converting dates from .Net to Java and vise versa. […]
November 29, 2008 at 9:41 am
tohorsearound
November 29, 2008 at 10:38 pm
I have a Really amazing site herePleasure to look at your site
November 30, 2008 at 1:06 am
Noway!
November 30, 2008 at 3:40 am
here’s another Amazing SiteWow, Nicely Done
March 3, 2009 at 11:41 am
Hello webmaster
I would like to share with you a link to your site
write me here preonrelt@mail.ru
January 15, 2015 at 1:17 pm
Hi admin do you need unlimited articles for your blog ?
What if you could copy content from other pages, make it pass copyscape test and publish on your website – i know the
right tool for you, just type in google:
loimqua’s article tool