Have 48 Hours difference, converting C# Ticks to Java Timestamp - java

According to MSDN, System.DateTime.Ticks "represents the number of 100-nanosecond intervals that have elapsed since 12:00:00 midnight, January 1, 0001 (0:00:00 UTC on January 1, 0001, in the Gregorian calendar)".
There's a internal field in DateTime, UnixEpoch, with the value 621355968000000000L which should correspond to the Unix Epoch (midnight, January 1, 1970 UTC). (We can get the same value from new DateTime(1970,1,1,0,0,0,0,System.DateTimeKind.Utc);.)
I'm trying to create a Date in Java based on a C# ticks value:
Here's a simple Java example to reproduce the problem:
//C# System.DateTime.UnixEpoch = 621355968000000000;
//Java code:
//before Unix Epoch, in milliseconds
Date date = new Date(-621355968000000000L / 10000);
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS Z");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
df.format(date); // 0001-01-03 00:00:00.000 +0000
Is there a kind of gap in Gregorian calendar, which is taken into account only by one of platforms?

It seems Java Date uses the Julian Calendar for dates when that calendar was used while C#, in this case, uses Gregorian Calendar back before there was one. By default Joda-Time also uses the Gregorian Calendar back in time.
This seems to work but there's probably a better way.
DateTime dt = new DateTime(-621355968000000000L / 10000);
GregorianCalendar gc = new GregorianCalendar();
gc.set(GregorianCalendar.YEAR, dt.getYear());
gc.set(GregorianCalendar.MONTH, dt.getMonthOfYear() - 1);
gc.set(GregorianCalendar.DAY_OF_MONTH, dt.getDayOfMonth());
gc.set(Calendar.HOUR_OF_DAY, 0);
gc.set(Calendar.MINUTE, 0);
gc.set(Calendar.SECOND, 0);
gc.set(Calendar.MILLISECOND, 0);
Date date = gc.getTime();

Related

How to convert a Calendar object to an Instant? [duplicate]

This question already has answers here:
Java get UTC time
(5 answers)
Closed 7 years ago.
I have a Calendar object manipulated according to my needs, but converting it to Instant is not giving me the correct result:
Calendar cal = Calendar.getInstance(); // creates calendar
cal.setTime(inputFiledate); // sets calendar time/date --> inputFiledate is 29-12-2015
cal.set(Calendar.HOUR_OF_DAY, Integer.parseInt(inputFileHour)); -->inputFileHour is 5
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
cal.add(Calendar.HOUR_OF_DAY,3); // adds hours that is now time is 29-12-2015 08:00:00
System.out.println("Date after manipulation "+cal.getTime()); -->Displays
TimeZone tz = TimeZone.getTimeZone("UTC");
// set the time zone with the given time zone value
// and print it
cal.setTimeZone(tz);
// Date date = cal.getTime(); // returns new date object, one hour in the future
Date d= cal.getTime();
System.out.println("DAte to Instant "+ d.toInstant());
System.out.println(" Calendar to Instant "+cal.toInstant());
System.out.println("Date after manipulation2 "+cal.getTime());
This is the output:
Date after manipulation Tue Dec 29 08:00:00 IST 2015
DAte to Instant 2015-12-29T02:30:00Z
Calendar to Instant 2015-12-29T02:30:00Z
Date after manipulation2 Tue Dec 29 08:00:00 IST 2015
In need to convert this Calendar object to instant but it is giving incorrect result 2015-12-29T02:30:00Z
where as the output should be 2015-12-29T08:00:00Z
Where m I going wrong?
Also tried with Zoned datetime, with Timezone, in vain.
Date doesn't have a time zone. From the time difference I assume you are using Indian Time (-5:30) It is just the time relative to epoch which is different in each time zone.
I suggest you do the calculation using ZonedDateTime instead of trying to convert from a Calendar.

Java Date which looks same in any timezone

I am currently trying to get create a java Date which looks the same no matter what timezone I view it in. My current code is:
Calendar cal = Calendar.getInstance();
cal.set(2015, Calendar.JANUARY, 8, 0, 0, 0);
cal.set(Calendar.MILLISECOND, 0);
Date date = cal.getTime();
In my current timeZone this gives me '2015-01-08T00:00:00Z'In another this gives me 2015-01-08T00:00:00-03:00. What I want to know is if there is any way to drop the timezone part so as the time is the same in both time zones.
I would be VERY grateful for any help on this matter. Thank you.
Java SE 8 comes with a new Date & Time API. Have a look at LocalDate and LocalDateTime.
If you are only interested in the format of the time, create a java.text.SimpleDateFormat object to print your time in the format that you want.
http://docs.oracle.com/javase/1.5.0/docs/api/java/text/SimpleDateFormat.html
If you want the time to be printed with the same numbers no matter the TimeZone,
Use String ids[] = java.util.TimeZone.getAvailableIDs();
to get the TimeZone's IDs and find the ID that you want.
In this example, I created two SimpleDateFormat objects set to two different TimeZones. They both print off the same Calendar object. I have taken off the Z in ft2 to remove the time zone portion. By relying on toString(), I think you would be subject to Locale differences in displaying dates, like US MM/dd/yyyy and UK dd/MM/yyyy.
TimeZone tz = TimeZone.getTimeZone("America/New_York");
TimeZone tz2 = TimeZone.getTimeZone("America/Chicago");
Calendar acal = new GregorianCalendar();
SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd'T'hh:mm:ss Z");
ft.setTimeZone(tz);
SimpleDateFormat ft2 = new SimpleDateFormat ("yyyy-MM-dd'T'hh:mm:ss");
ft2.setTimeZone(tz2);
String date1 = ft.format(acal.getTime());
System.out.println(date1);
String date2 = ft2.format(acal.getTime());
System.out.println(date2);
Output:
2015-01-08T10:36:39 -0500
2015-01-08T09:36:39

Subtracting two dates in Java

I want to subtract two dates (one constant and one current) in Java but I've got strange problems with it. Here is the code :
DateFormat df = new SimpleDateFormat("HH:MM");
Date FirstLessonInterval=df.parse("08:45");
Date currentTime = new Date();
long diff = FirstLessonInterval.getTime()-currentTime.getTime();
String s = String.valueOf(diff);
LessonOrBreak=(diff);
I've got minus minutes. When I want to see FirstLessonInterval with FirstLessonInterval.toString() it shows the year 1970. What can I do?
You forgot to give a date, you just defined a time:
DateFormat df = new SimpleDateFormat("HH:MM");
Date FirstLessonInterval=df.parse("08:45");
and this is in unix time day 0 which is the 1.1.1970
try something like
DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:MM");
Date FirstLessonInterval=df.parse("2014/05/10 08:45");
1970 is where all time began according to computers. Are we missing some code in your question? You can faff around with the current time in milliseconds but i'd take a look at JodaTime and use that.
The reason you are getting 1970.... is because I suspect your diff is quite a small number. Then if you look at that as a date then it will be a small number + 1 Jan 1970 which will still be in 1970. But as i said I suspect we are missing some code in your question.
In JodaTime you can do somethign like the below but im not sure what it is you are exactly after
Interval i= new Interval(new DateTime(FirstLessonInterval), new DateTime());
System.out.println("Interval is: " + i.toDurationMillis());
Your format pattern is incorrect, use lower case mm to represent minutes
When you do not specify much details to the outdated Java date api, it considers the time since UNIX epoch (1st Jan 1970)
Since you are assuming the date to be the same as the constant time parameters you provide and independent of the timezones, you can bring your current date comparable to the time since UNIX epoch:
Staying close to your original code;
DateFormat df = new SimpleDateFormat("HH:mm");
Date firstLessonInterval = df.parse("08:45");
Date currentTime = new Date();
// Format the current date comparable to UNIX epoch (only hold time params)
String dateStr = df.format(currentTime.getTime());
// Parse the modified date string to a date object
Date comDate = df.parse(dateStr);
// Take the difference in millis
long diff = firstLessonInterval.getTime() - comDate.getTime();
String s = String.valueOf(diff);
// Print the number of minutes passed since
System.out.println("Minutes {elapsed since/time to} 08:45 - " + Math.abs(diff) / 1000 / 60);
Missing Date Portion
As the other correct answers said, you are using the java.util.Date class which is a date-time class holding both a date portion and a time portion.
LocalTime
If you truly care about only time of day, with no date and no time zone, then use the LocalTime class found in both the Joda-Time library and the new java.tome package in Java 8. By the way the old java.util.Date and .Calendar classes are notoriously troublesome and should be avoided.
Joda-Time
Here is some code with date-time and time zone.
Using the Joda-Time 2.3 library…
DateTimeZone timeZone = DateTimeZone.forID( "Europe/Warsaw" );
DateTime dateTime = new DateTime( 2014, 1, 2, 8, 45, 0, timeZone );
DateTime now = new DateTime( 2014, 1, 2, 8, 30, 0, timeZone ); // Or DateTime.now( timeZone )
Duration duration = new Duration( dateTime, now ); // or use Period or Interval.
Joda-Time offers intelligent classes and methods of working with a span of time (a Period, Interval, or Duration). For example look at the Minutes class. But if all you need is millseconds, here you go.
long millis = duration.getMillis();
The problem is that you are not providing enough info to SimpleDateFormat. It sets the hour and minutes correctly but nothing else.
DateFormat df = new SimpleDateFormat("HH:mm");
System.out.println(df.parse("08:45")); // Thu Jan 01 08:45:00 GMT 1970
System.out.println(new Date()); // Sun May 11 07:52:50 GMT 2014
If you want your date to be with respect to the current date try this:
Date curr = new Date();
Date date = new Date(curr.getYear(),
curr.getMonth(),
curr.getDate(),
8, 45, 0);
System.out.println(date); // Sun May 11 08:45:00 GMT 2014
System.out.println(curr); // Sun May 11 07:52:50 GMT 2014
long diff = date.getTime() - curr.getTime();
System.out.println("Minutes: " + diff/6000); // Minutes: 53
I dont know if this way is efficient or not but it's an idea anyway:
Date curr = new Date();
Date date = new Date(114, /*114 is 2014 , don't know why*/
6,
16,
8, 45, 0);
System.out.println(curr);
System.out.println(date);
Date x = new Date(curr.getYear() - date.getYear() ,
curr.getMonth() - date.getMonth(),
curr.getDate() - date.getDate(),
curr.getHours() - date.getHours(),
curr.getMinutes() - date.getMinutes(),
curr.getSeconds() - date.getSeconds() );
String startDateString = "2017-03-08";
String finishDateString = "2017-03-10";
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd", Locale.ENGLISH);
LocalDate startDate = LocalDate.parse(startDateString, formatter);
LocalDate finishDate = LocalDate.parse(finishDateString, formatter);
Integer day = finishDate.compareTo(startDate);
Integer day will be 3. It means that the difference between two dates equals 3 days

Incrementing date by 18years in java

1.I want to set the setMaxSelectableDate=18years in JDateChooser so i provided it the date by incrementing milliseconds but how should i increment it by 18years.
2.Incrementing by 18years the calculation comes out to be 365*18*24*60*60*1000=56764800000 which gives me error integer number to large.
Date max=new Date();
Date oth1=new Date(max.getTime() + (365*18*24*60*60*1000)); //days*hours*minutes*seconds*milliseconds
SimpleDateFormat maxdateFormatter1 = new SimpleDateFormat("MMM d,yyyy hh:mm:ss a");
String maxdate=maxdateFormatter1.format(oth1);
DateChooser_V1.setMaxSelectableDate(new java.util.Date(maxdate));
Let java.util.Calendar do this work for you:
Calendar c = Calendar.getInstance();
c.setTime(oldDate);
c.add(Calendar.YEAR, 18);
Date newDate = c.getTime();
Which takes care of leap years, historical GMT offset changes, historical Daylight Saving Time schedule changes etc.
You need to use a long. You can achieve this by adding an L to your number:
365L* ...
With JodaTime
DateTime in18Years = new DateTime( ).plusYears( 18 );
Here is how to convert to java.util.Date
Date in18Years = new DateTime( ).plusYears( 18 ).toDate( );
You cannot willy-nilly add seconds (or millseconds) and expect calendar calculations to come out right. Basically it takes some extra effort to account for all of those leap-years, leap seconds, and daylight savings shifts.
Until Java 1.8 comes out, use java.util.Calendar instead of java.util.Date, there are really good reasons that java.util.Date has practically everything in it deprecated. While it looks good in the beginning, with enough use you will find it often "just doesn't work (tm)".
GregorianCalendar now = new GregorianCalendar();
now.add(Calendar.YEAR, 18);
And that's assuming that you didn't overflow Integer.MAX_INT.
I would use a Calendar object to achieve this:
Calendar cal = Calendar.getInstance();
Date dt = new Date();
...
// Set the date value
...
cal.setTime(dt);
cal.add(Calendar.YEAR, +18);
dt = cal.getTime();
Hope this helps you

Why does GregorianCalendar.getInstance contain a calsys and cdate of type Julian Calendar

I tried to do set date value to a PreparedStatement with default value but the value is sometimes returned as a JulianValue. For example (Assume spanBegin and spanEnd are null)
Calendar cal = new GregorianCalendar();
if (spanBegin == null) {
cal.set(0000, Calendar.JANUARY, 1);
spanBegin = cal.getTime();
}
if (spanEnd == null)
{
cal.set(9999, Calendar.DECEMBER, 31);
spanEnd = cal.getTime();
}
On line number 3, since the date January 1, 0000 is scoped by a Julian Calendar, the CDate becomes a Julian Calendar. However, the next Date even if it is in the year 9999, its CDate becomes a Julian Calendar still. I had to create another instance of Gregorian Calendar to fix the issue.
Calendar cal = new GregorianCalendar();
if (spanBegin == null) {
cal.set(0000, Calendar.JANUARY, 1);
spanBegin = cal.getTime();
}
Calendar cal = new GregorianCalendar();
if (spanEnd == null)
{
cal.set(9999, Calendar.DECEMBER, 31);
spanEnd = cal.getTime();
}
The question is, is the this an expected behavior or a bug on the date object? Actually using GregorianCalendar.getInstance() shows that the cdate is sometimes set to JulianCalendar.
There was no Gregorian Calendar until 1582. The Julian calendar was in use all over Europe, until minor problems started to appear caused by the fact the solar year is not exactly 365.25 days, but a little less than that. In order to fix things, pope Gregory XIII ordered to change the calendar to what we know today - every year that divides by 100 is not a leap year, unless it divides by 400. In October 1582 there was the transition - the day after 4 Oct was 15 Oct. This means that until October 1582, the Gregorian and Julian Calendars are the same. You can read more about it here
This is why dates prior to Oct 1582 are converted to use the Julian system. According to the API If you actually need to represent an historical event (which seems not to by the case here) you can do it only from 1st march, 4AD
What version of Java are you using and on what OS? Do you really need to store dates in the years 0 and 9999, or are you just using these as "negative infinity" and "positive infinity" values? How exactly do you see that the calendar is a Julian calendar?
I tried this:
Calendar cal = Calendar.getInstance();
cal.set(0, Calendar.JANUARY, 1);
Date d1 = cal.getTime();
cal.set(9999, Calendar.DECEMBER, 31);
Date d2 = cal.getTime();
System.out.println(d1);
System.out.println(d2);
Output (on Windows XP, using Sun Java 1.6.0_16):
Thu Jan 01 09:53:56 CET 1 java.util.Date
Tue Dec 31 09:53:56 CET 9999 java.util.Date
It changes the year 0 to the year 1. Changing the code to use a second Calendar object for the second date:
Calendar cal = Calendar.getInstance();
cal.set(0, Calendar.JANUARY, 1);
Date d1 = cal.getTime();
Calendar cal2 = Calendar.getInstance();
cal2.set(9999, Calendar.DECEMBER, 31);
Date d2 = cal2.getTime();
System.out.println(d1);
System.out.println(d2);
This does not change anything to the output or the content of the two Date objects.
Note: Beware that integer literals that start with a 0, such as 0000 in your code, will be interpreted as octal numbers by the Java compiler. That doesn't matter in this case because the number is 0, but you should not prepend integer literals with zeroes if you don't mean them as octal numbers.
Thhere is no year 0 in Julian calendar. It goes from 1 BC to 1 AD.

Categories