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

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.

Related

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

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();

How to convert date object to ones own timezone in android?

In android, I download date information from a MySQL database on a free web server, then convert it to a Date object using:
Note: the server time is 5 hours ahead of toronto.
public static Date getDateFromSQLDate(String sqldate) {
try {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
Date date = (Date) formatter.parse(sqldate);
TimeZone targetTimeZone = TimeZone.getDefault();
TimeZone serverTimeZone = TimeZone.getTimeZone("Europe/London");
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.setTimeZone(serverTimeZone);
calendar.add(Calendar.MILLISECOND, serverTimeZone.getRawOffset() * -1);
if (serverTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, calendar.getTimeZone().getDSTSavings() * -1);
}
calendar.add(Calendar.MILLISECOND, targetTimeZone.getRawOffset());
if (targetTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, targetTimeZone.getDSTSavings());
}
return calendar.getTime();
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
This doesn't seem to work..
The problem is that the date is relative to the timezone of the server. The one downloading could be confused with the times as they don't know its not in their own timezone.
I have a Date object, is there a way I can retrieve the timezone of the location the users phone is in, and then modify that Date object to be their own timezone?
Thanks
EDIT:
How to get TimeZone from android mobile?
This gets a timezone object, but how do I change a Date object with it?
My app has to deal with server time similar to you.
(All datetime that I got from server represent datetime at UTC +00:00)
// date string to convert
String dateString = "2014-01-07 12:00:00"
// create date formatter, set time zone to UTC and parse
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
TimeZone serverTimeZone = TimeZone.getTimeZone("UTC");
formatter.setTimeZone(serverTimeZone);
Date date = formatter.parse(dateString);
Log.i("Debug", "date object : " + date.toString());
// I'm in Bangkok (UTC +07:00) so I'll see "Wed Jan 07 19:00:00 GMT+07:00 2015"
// If you do this in Toronto, you should see "Wed Jan 07 07:00:00 GMT -05:00 2015"
When you wanna print this date in Toronto, I believe you don't have to calculate DST by yourself because calendar and date formatter should handle that (not sure, I read from somewhere long ago)
// Create timezone for Toronto
TimeZone torontoTimeZone = TimeZone.getTimeZone("America/Toronto");
// Create calendar, set timezone, to see hour of day in Toronto
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(torontoTimeZone);
calendar.setTime(date);
Log.i("Debug", "Hour of day : " + calendar.get(Calendar.HOUR_OF_DAY);
// Hour of day : 7
// Create date formatter, set timezone, to print date for Toronto user.
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy, hh:mm", Locale.US);
formatter.setTimeZone(torontoTimeZone);
String torontoDate = formatter.format(date);
Log.i("Debug", "Date in Toronto : " + torontoDate);
// Date in Toronto : 07 Jan 2015, 07:00
You can set calendar and date formatter to user timezone by replace
TimeZone timezone = TimeZone.getTimeZone("America/Toronto")
with
TimeZone timezone = TimeZone.getDefault()
When I deal with date from server, I'll
request UTC time from server, if server doesn't send me UTC time, convert to UTC time first.
when parse date object from server, I always create date object represent time at UTC (time at server)
perform calculation or anything else with UTC date object.
pass only UTC date object from and to Activity/Fragment/Service/Model
only format date string with user timezone only when I need to display to user.
This is how you can change the date to your timezone
SimpleDateformat sdf = new SimpleDateFormat("yourformat");
TimeZone tz = TimeZone.getDefault();
sdf.setTimezone(tz);
sdf.format(yourdate); //will return a string in "your-format" to represent date
You're on the right track. You need to set the time zone of the Calendar object to the server's time zone. Then you can add the offset (and factor in DST) with the TimeZone that you got from the user's device (the link you included).
Code:
calendar.add(Calendar.MILLISECOND, serverTimeZone.getRawOffset() * -1);
if (serverTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, calendar.getTimeZone().getDSTSavings() * -1);
}
calendar.add(Calendar.MILLISECOND, targetTimeZone.getRawOffset());
if (targetTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, targetTimeZone.getDSTSavings());
}
After that, you can retrieve the date in the usual way from the Calendar.
Also see this answer for more information.

Parsing time to calendar

I would like to set the timepart of a calendar. Here is what I'm doing
Calendar calNow = Calendar.getInstance();
Calendar endWait = Calendar.getInstance();
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm");
Date d1 = null;
try {
d1 = sdf.parse("14:45");
}catch(ParseException ex){
logger.error("Error parsing time");
}
endWait.setTime(d1);
Date waitTo = endWait.getTime();
Date now = calNow.getTime();
The "now" variable is correct date and time, however the waitTo was expected to be the date of today and time 14:45, but is tomorrow at 02:45.
For me it is not giving tomorrow, but waitTo = Thu Jan 01 14:45:00 CET 1970.
The reason for this can be found in the javadoc of SimpleDateFormat:
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.
Calendar.setTime() will use the date and time information of the passed Date instance.
To only update the hours and minutes of the waitTo you can:
Calendar tmpCal=Calendar.getInstance();
tmpCal.setTime(d1);
endWait.set(Calendar.HOUR_OF_DAY,tmpCal.get(Calendar.HOUR_OF_DAY));
endWait.set(Calendar.MINUTE, tmpCal.get(Calendar.MINUTE));
This way the day, month, year part of the endWait will not be altered.

Joda Time Not getting expected result

I have a date string of format MM/dd/yyyy that I am parsing using SimpleDateFormat
Now say the startDateString is 11/26/2012 for the code given below. I set the time zone to America/New_York
SimpleDateFormat df=new SimpleDateFormat("MM/dd/yyyy");
Date st = df.parse(startDateString);
Calendar startDate = Calendar.getInstance(TimeZone.getTimeZone("America/New_York"));
System.out.println("BEFORE : Start Date :"+startDate.getTime());
startDate.setTime(st);
System.out.println("AFTER : Start Date :"+startDate.getTime());
DateTimeZone timezone = DateTimeZone.forID("America/New_York");
DateTime actualStartDate = new DateTime(startDate,timezone);
System.out.println("JODA DATE TIME "+ actualStartDate);
The outout of above code snippet:
BEFORE : Start Date :Tue Nov 27 12:26:51 IST 2012
AFTER : Start Date :Mon Nov 26 00:00:00 IST 2012 //ok it sets date to 26th
//with all time parameters as 0.
JODA DATE TIME 2012-11-25T13:30:00.000-05:00 // here the date and
// time parameter are changed
What my problem is when I create my actualStartDate like this :
DateTime actualStartDate = new DateTime(startDate,timezone);
The date changes to 25 and the time changes to 13:00:00
I think this is because of timezone zone difference between India and US (total -10:30 from IST Indian time)
What I want is JODA DATE TIME 2012-11-26T00:00:00.000-05:00
Do I manually set the parameters of time inside my startDate calendar instance to 0 ?
I suspect the problem is that you're parsing in your default time zone. This:
AFTER : Start Date :Mon Nov 26 00:00:00 IST 2012
shows that the instant in time you're using is midnight IST - not midnight in New York or in UTC. Currently IST is 18:30 in UTC, so the instant you're representing is 25-11-25T18:30:00Z.
When you convert that into New York time, you end up with 2012-11-25T13:30:00-05:00, which is exactly what Joda Time is doing.
I would strongly advise that:
You avoid using the Java libraries at all (that's where all the problems have come from here - both in parsing, and the result of Date.toString() confusing you)
You use LocalDate to represent a date, rather than DateTime. You're trying to represent a date after all, not an instant in time. This bypasses time zones entirely, as a date doesn't have a time zone.
Sample code:
import java.util.*;
import org.joda.time.*;
import org.joda.time.format.*;
public class Test {
public static void main (String[] args) {
String text = "11/26/2012";
DateTimeFormatter formatter =
DateTimeFormat.forPattern("MM/dd/yyyy")
.withLocale(Locale.US);
LocalDate date = formatter.parseLocalDate(text);
System.out.println(date);
}
}
Once you've got a LocalDate, if you want to find out the instant at which that day started in a particular time zone, you can use LocalDate.toDateTimeAtStartOfDay(DateTimeZone).

Current Time/Date Code Error

How do I get Current Time as this code is giving (Time-->Thu Jan 01 05:56:27 ACT 1970)??
DateFormat timeFormat = new SimpleDateFormat("HH:mm:ss.SS");
Date time = new Date();
String currentTime=timeFormat.format(time);
time=timeFormat.parse(currentTime);
System.out.println("Time-->"+time);
salesOrder.setOrderTime(time);
Class java.util.Date is not suitable for storing only a time-of-day (hours, minutes, seconds, milliseconds). Class Date is a timestamp, it contains a number of milliseconds since 01-01-1970, 00:00:00 GMT.
Use LocalTime from the Joda Time library for this instead.
Note: What you are doing in your code is first formatting a Date object to a String, and then parsing it back to a Date again, throwing away the day, month, year part. What you end up with is a Date object that's set to a number of hours, minutes, seconds and milliseconds since 01-01-1970, 00:00:00 GMT.
use DateFormat timeFormat = new SimpleDateFormat();
instead of
DateFormat timeFormat = new SimpleDateFormat("HH:MM:ss:SS");
The problem is in formatting. You have not provided the Day,year fieldr, thats why it is acting that way. Or You can use this with proper formatting :
DateFormat timeFormat = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss Z");
EDIT:
Try this:
Calendar c = Calendar.getInstance();
c.setTime(time);
System.out.println(c.get(Calendar.YEAR)+ " "+c.get(Calendar.MONTH)+ " "+ c.get(Calendar.DAY_OF_MONTH));
Where time set in Calendar object is time that is not parsed/formatted using simpleDateFormat.
From calendar object, you can get individual month , day , year and use it the way you like, or you can just call c.getTime() to get the Date object.
Your format only contains hours and minutes and seconds. Given just a time of day with no date component, DateFormat.parse() does not fill in the current date; it falls back on the epoch of the system, "time zero", which is January 1, 1970. If you want a date string that can be turned back into a Date object, you need to include the year and month and day as well as the hour.

Categories