Converting .NET time to Java time is two days off - java

Yes, I know this question has been posed many times, but I am still unable to get a consistent result between .NET and Java.
There are a number of posts and google search results that refer to the constants:
long UNIX_EPOCH_IN_100NS_INTERVALS = 621355968000000000l;
long DOTNET_EPOCH_IN_MSEC_INTERVALS = -62135596800000l;
The first purports to be the number of 100ns intervals or 'tics' between UTC 0001-01-01 00:00:00 (z yyyy-MM-dd HH:mm:ss) and UTC 1970-01-02 00:00:00, and the second is the difference between the .NET epoch and the Java epoch in milliseconds.
A post here reports a similar issue in the .NET world.
In the code below, I calculate the offset between the epochs and then compare to the published numbers:
SimpleDateFormat sdf = new SimpleDateFormat("z yyyy-MM-dd HH:mm:ss");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date;
try {
date = sdf.parse("UTC 1970-01-01 00:00:00");
} catch (ParseException e) {
e.printStackTrace();
throw new RuntimeException("Stupid java dates !");
}
System.out.println("Unix Epoch Date: " + sdf.format(date));
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.setTime(date);
System.out.println("Unix Epoch Milliseconds: " + cal.getTimeInMillis());
try {
date = sdf.parse("UTC 0001-01-01 00:00:00");
} catch (ParseException e) {
e.printStackTrace();
throw new RuntimeException("Stupid java dates !");
}
System.out.println("Calculated DotNet Epoch Date: " + sdf.format(date));
cal.setTime(date);
System.out.println("Calculated DotNet Epoch Milliseconds: " + cal.getTimeInMillis());
date = new Date(-62135596800000l);
System.out.println("Published DotNet Epoch Date: " + sdf.format(date));
cal.setTime(date);
System.out.println("Published DotNet Epoch Milliseconds: " + cal.getTimeInMillis());
which generates the output:
Unix Epoch Date: UTC 1970-01-01 00:00:00
Unix Epoch Milliseconds: 0
DotNet Epoch Date: UTC 0001-01-01 00:00:00
DotNet Epoch Milliseconds: -62135769600000
Published DotNet Epoch Date: UTC 0001-01-03 00:00:00
Published DotNet Epoch Milliseconds: -62135596800000
Any help appreciated.

Related

date parse giving wrong date in android

In android, I am getting the wrong date when parsing. I am providing 22 Feb (Wednesday). Why is it giving me the wrong week day (Sunday)? Check the screenshot below to see the full code with values.
SimpleDateFormat format = new SimpleDateFormat("dd MMM (EEEE)");
try {
Date date = format.parse(strDate);
Calendar c = Calendar.getInstance();
c.setTime(date);
c.add(Calendar.DATE, 2);
String output = format.format(c.getTime());
tvDeliveryDate.setText(output);
tvDeliveryTime.setText(time);
deliveryDateTime = output + "," + time;
db.putString("deliver_date",output);
db.putString("deliver_time",time);
db.putString("deliver_date_time",output + ", " + time);
} catch (ParseException e) {
e.printStackTrace();
}
Your date format doesn't have a year component, so 1970 is assumed. In 1970, February 22 was a Sunday.
From the SimpleDateFormat.parse() documentation:
This parsing operation uses the calendar to produce a Date. All of the calendar's date-time fields are cleared before parsing, and the calendar's default values of the date-time fields are used for any missing date-time information. For example, the year value of the parsed Date is 1970 with GregorianCalendar if no year value is given from the parsing operation.

java difference between calendars

I'm just doing a simple difference of two timemilisseconds of two different calendar.
Example:
Calendar ini = Calendar.getInstance();
try {
Thread.sleep(1500);
} catch (InterruptedException e) {e.printStackTrace();}
Calendar end = Calendar.getInstance();
long diff = end.getTimeInMillis()-ini.getTimeInMillis();
System.out.println("diff "+diff);
System.out.println("ini date "+ ini.getTime());
System.out.println("end date "+ end.getTime());
System.out.println("diff time format "+timeFormat.format(diff));
The time format is:
private final static String TIME_STRING_FORMAT = "hh:mm:ss.SSS";
private static SimpleDateFormat timeFormat = new SimpleDateFormat(TIME_STRING_FORMAT);
And in the output, always appear 1 our of difference, is it problem of the SimpleDateFormat???
Output:
diff 1500
ini date Sun May 24 22:27:01 CEST 2015
end date Sun May 24 22:27:03 CEST 2015
diff time format 01:00:01.500
Thanks for your help!!
It looks like SimpleDateFormat uses a timezone. See this related question. So when you give it the time 1500 milliseconds, it thinks you're giving it the time since the beginning of epoch time in the GMT time. Then it translates this to your timezone, giving you some hours of offset. You probably want to set the timezone on your timeFormat to GMT. Try this:
Calendar ini = Calendar.getInstance();
try {
Thread.sleep(1500);
} catch (InterruptedException e) {e.printStackTrace();}
Calendar end = Calendar.getInstance();
long diff = end.getTimeInMillis()-ini.getTimeInMillis();
System.out.println("diff "+diff);
System.out.println("ini date "+ ini.getTime());
System.out.println("end date "+ end.getTime());
Date date = new Date(diff);
System.out.println(date);
timeFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("diff time format "+timeFormat.format(date));
The 1 hour difference is caused by your local time zone. Date(long) constructs a date a number of milli seconds after January 1st 1970 GMT. In continental Europe (during winter) 1500 milli seconds after the epoch is thus January 1st 01:00:01.500.
If you use Java 8 see the tutorial on Period and Duration. Duration is probably what you want to use.

Joda-Time Number of Days since Epoch

I have a problem whereby the number of days since epoch returned by Joda-Time library changes depending the time of the date I entered. If I enter 2012-05-14 22:00:00 and 2012-05-14 02:00:00 I would expect the same result since they are both on the same day. The following is my code.
try {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date date1 = sdf.parse("2013-05-03 07:00:00");
Date date2 = sdf.parse("2013-05-03 23:30:00");
MutableDateTime epoch = new MutableDateTime();
epoch.setDate(0); //Set to Epoch time
System.out.println("Epoch: " + epoch);
Days days1 = Days.daysBetween(epoch, new MutableDateTime(date1.getTime()));
Days days2 = Days.daysBetween(epoch, new MutableDateTime(date2.getTime()));
System.out.println("1) Days Since Epoch: " + days1.getDays());
System.out.println("2) Days Since Epoch: " + days2.getDays());
} catch (ParseException e) {
e.printStackTrace();
}
Epoch: 1970-01-01T11:09:00.414+01:00
1) Days Since Epoch: 15827
2) Days Since Epoch: 15828
Does anyone have any idea what I'm doing wrong?
OK found the problem (which was in front of my own eyes :)) ... the epoch I was getting was indeed starting from 1970-01-01 but not from the very first ms of that day.
I needed to add the following line to get it sorted:
epoch.setTime(0);

Time Zones in Java

I'm working on a security signature in java that also verifies the date and time the call is being made. The POST call arrives with something like
String date = "Sat, 27 Apr 2013 01:11:30 GMT"
SimpleDateFormat RFC1123Format = new SimpleDateFormat("EEE, dd MMM yyyyy HH:mm:ss z", Locale.US);
And I'm able to parse it
Calendar gmtTime = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
Date dateHeader = RFC1123Format.parse(date);
gmtTime.setTime(dateHeader);
System.out.println("Date Header (GMT TIME): " + gmtTime.getTimeInMillis() + " ms");
System.out.println("Hour of day (GMT TIME): " + gmtTime.get(Calendar.HOUR_OF_DAY));
Calendar currentTime = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
currentTime.setTimeInMillis(System.currentTimeMillis());
System.out.println("System Date (LA TIME): " + currentTime.getTimeInMillis() + " ms");
System.out.println("Hour of day (LA TIME): " + currentTime.get(Calendar.HOUR_OF_DAY));
currentTime.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("System Date (GMT TIME): " + currentTime.getTimeInMillis() + " ms");
System.out.println("Hour of day (GMT TIME): " + currentTime.get(Calendar.HOUR_OF_DAY));
System.out.println("Diff: " + Math.abs(gmtTime.getTimeInMillis() - currentTime.getTimeInMillis()));
However the printout I get differs by 1 entire hour.
Date Header (GMT TIME): 1367025090000 ms
Hour of day (GMT TIME): 1
System Date (LA TIME): 1367022298441 ms
Hour of day (LA TIME): 0
System Date (GMT TIME): 1367022298441 ms
Hour of day (GMT TIME): 0
Diff: 2791559
Any ideas?
You can use JodaTime >> http://joda-time.sourceforge.net/ that implements TimeZone Calculations more efficiently than Java calendar
You don't give your formatter the calendar that you are using to represent your timestamps.
In this case, your calendar is set to represent timestamps in GMT. GMT is a synonym for UTC and UTC never observes any adjustment for DST. Your formatter, however, by default must convert your supplied string with the system default calendar as the basis, which likely does observe DST.
If this is the case, you can get consistent reporting by making sure that your formatter is using the same calendar that you are using to represent your date/times. Try this:
SimpleDateFormat RFC1123Format = new SimpleDateFormat();
GregorianCalendar gc - new GregorianCalendar(TimeZone.getTimeZone("GMT"));
RFC1123Format.setCalendar(gc);
RFC1123Format.applyPattern("EEE, dd MMM yyyyy HH:mm:ss z");
gc.setTime(RFC1123Format.parse(yourDateString));
Fixed it myself by adding an extra verification to check if Daylight Savings is being observed. This is the final code:
Calendar gmtTime = new GregorianCalendar(TimeZone.getTimeZone("GMT"));
Date dateHeader = RFC1123Format.parse(date);
gmtTime.setTime(dateHeader);
Calendar currentTime = Calendar.getInstance();
currentTime.setTimeInMillis(System.currentTimeMillis());
boolean DST = false;
if(currentTime.getTimeZone().inDaylightTime(currentTime.getTime())) {
DST = true;
}
currentTime.setTimeZone(TimeZone.getTimeZone("GMT"));
if(DST) {
currentTime.set(Calendar.HOUR_OF_DAY, currentTime.get(Calendar.HOUR_OF_DAY) + 1);
.
.
.
<code to handle last day of month and month change as a result of the hour adjustment>
}
Thanks #gangqinlaohu for your suggestion.

Formatting XmlGregorianCalendar timezone issue

I need to format java XmlGregorianCalendar to "yyMMdd" string.
My implementation:
XMLGregorianCalendar date = getDate(); //getting the date
if (date != null) {
SimpleDateFormat sdf = new SimpleDateFormat("yyMMdd");
LOG.debug("Parsing date...");
LOG.debug("XML Date: " + date);
LOG.debug("XML Date timezone: " + date.getTimezone());
GregorianCalendar gc = date.toGregorianCalendar();
LOG.debug("Gregorian calendar: " + gc.toString());
LOG.debug("Gregorian calendar timezone id: " + gc.getTimeZone().getID());
Date d = gc.getTime();
LOG.debug("Date: " + d.toString());
String formatted = sdf.format(d);
LOG.debug("Formatted: " + formatted);
}
What I see in log:
Parsing date...
XML Date: 1943-04-15T00:00:00.000Z
XML Date timezone: 0
Gregorian calendar: java.util.GregorianCalendar[time=?,areFieldsSet=false,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="GMT+00:00",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=1943,MONTH=3,WEEK_OF_YEAR=1,WEEK_OF_MONTH=1,DAY_OF_MONTH=15,DAY_OF_YEAR=1,DAY_OF_WEEK=5,DAY_OF_WEEK_IN_MONTH=1,AM_PM=0,HOUR=0,HOUR_OF_DAY=0,MINUTE=0,SECOND=0,MILLISECOND=0,ZONE_OFFSET=0,DST_OFFSET=0]
Gregorian calendar timezone id: GMT+00:00
Date: Wed Apr 14 20:00:00 EDT 1943
Formatted: 430414
April, 15 was parsed as April, 14. What I'm doing wrong? When I should set timezone?
It was parsed as midnight on April 15th UTC. It was then formatted as 8pm on April 14th EDT, which is correct as EDT is four hours behind UTC.
Note that Date.toString() always uses the local time zone - a Date object has no concept of which time zone it's in.
Your formatted value is also using the default time zone, as you haven't specified a time zone. The calendar value (gc) is in UTC, but when you format it, it will apply the time zone from the formatter (as you format the Date value, which doesn't have a time zone).
It's not clear what you were trying to achieve, but hopefully that will help. As an aside, I'd strongly recommend that you use Joda Time instead if you possibly can - it makes a lot of this much clearer.

Categories

Resources