Can't convert time to GMT - java

My problem is that I want to convert the local time to GMT. I am able to convert the actual time and save it to Parse but the problem is that Parse applies its own:
Wed Feb 24 10:00:00 GMT+05:30 2016
This is the date that I am getting after converting to GMT00:00 but the problem is the GMT+05:30 that is actually false as my date is actually in GMT. Now when I put this date in the server it further decreases the time by 5:30 hrs. So how can we change this GMT+05:30 to GMT+00:00

If you are using java 8. you could utilize from the new time library.
As you tell it seems what you want, is to have a stamp in UTC which is GMT+00
more about time library here
This line:
System.out.println(Instant.now().toString());
gives
2016-02-25T17:54:55.420Z
Hope it makes thing more clear to you.

We'll start with the current local time.
Calendar cal = Calendar.getInstance(); // automatically produces and instance of the current date/time
As I understand it, your local date is accurate to GMT but your time is 5:30 ahead of actual GMT.
In order to subtract 5:30 from your local time you can perform the following.
cal.add(Calendar.HOUR, -5);
cal.add(Calendar.MINUTE, -30);
System.out.println(cal.getTime());
Conversely, if you would like to add to the time field, you can simply use:
cal.add(Calendar.HOUR, 5); // note I have removed the minus(-) symbol
cal.add(Calendar.MINUTE, 30); // note I have removed the minus(-) symbol
System.out.println(cal.getTime());

Related

Java Calendar Date still adding Time on UTC Date 00:00 [duplicate]

This question already has answers here:
Convert Java Date to UTC String
(7 answers)
Closed 5 years ago.
I set my Calendar instance to a UTC date at 00:00 however once i return the result its 1 hour ahead
Calendar cal = Calendar.getInstance(TIMEZONE_UTC, Locale.ENGLISH);
cal.set(2017, 12 - 1, 15);
cal.set(Calendar.AM_PM, Calendar.AM);
cal.set(Calendar.HOUR, 0);
cal.set(Calendar.MINUTE, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
System.out.println(cal.getTime());
// Fri Dec 15 01:00:00 CET 2017 but should be 00:00:00
I suppose there is the winter/summer offset but I didn't found any description in the Gregorian or Calendar Element to handle this issue
I am getting the impression that you are really after just the date of December 15, 2017, and just wanted to make sure that there is no unexpected hour-of-day? If so, LocalDate from java.time, the modern Java date and time API, is made for you:
LocalDate ld = LocalDate.of(2017, Month.DECEMBER, 15);
System.out.println(ld);
This prints
2017-12-15
No hours, minutes or seconds to be concerned about.
If you do need a date-time at 00:00 UTC (the time I used to call midnight until Basil Bourque’s comment), there are several ways to obtain it. One of them is:
OffsetDateTime utcDateTime = LocalDateTime.of(2017, Month.DECEMBER, 15, 0, 0)
.atOffset(ZoneOffset.UTC);
System.out.println(utcDateTime);
This prints
2017-12-15T00:00Z
The Z in the end means UTC or offset zero. You see that the time of day is 00:00 as you wanted.
The Calendar class that you used in the question is long outdated, so I recommend you don’t use it anymore. java.time, the modern Java date and time API also known as JSR-310, is so much nicer to work with.
What went wrong in your code?
While a Calendar does contain a time zone (you initialized it to TIMEZONE_UTC), a Date (another outdated class) doesn’t. So when you convert to Date using cal.getTime() you lose the information that you wanted the time to be in UTC. Next (and this confuses many), when you print the date, you implicitly call Date.toString(), and this method grabs your JVM’s time zone setting and produces a string with the time in this time zone. So apparently you are (like I am) in a time zone that is at UTC+01:00 in December. The following two date-times denote the same point on the timeline:
Fri Dec 15 01:00:00 CET 2017
Fri Dec 15 00:00:00 UTC 2017
The reason why you see local time printed is you're displaying it via an instance of Calendar using Date.toString() which uses the local timezone(implicitly use the system timezone).

Android timezone bug really wierd

Anyone can tell me that where the code here give different results?
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(1477785600000l);
cal.add(Calendar.DAY_OF_MONTH, 1);
System.out.println(cal.getTime());
System.out.println(cal.getTimeInMillis());
Calendar cal1 = Calendar.getInstance();
cal1.setTimeInMillis(1477785600000l);
cal1.add(Calendar.HOUR, 24);
System.out.println(cal1.getTime());
System.out.println(cal1.getTimeInMillis());
It works fine server-side but give different results when run on android platform.
You should use Calendar.HOUR_OF_DAY instead of Calendar.HOUR.
Like this:
cal1.add(Calendar.HOUR_OF_DAY, 23);
Are you using the same calendar instance to compare the equality of results?
Calendar cal = Calendar.getInstance();
cal.setTimeInMillis(1477785600000l);
//add 1 day to the date
cal.add(Calendar.DAY_OF_MONTH, 1);
Log.e("first time", "" + cal.getTime());
Log.e("second time", "" + cal.getTimeInMillis());
//reset the calendar to the instance value removing the day added before
cal.add(Calendar.DAY_OF_MONTH, -1); //or you can use cal.setTimeInMillis(1477785600000l);
//add 24 hours to the base calendar value
cal.add(Calendar.HOUR, 24);
Log.e("third time", "" + cal.getTime());
Log.e("fourth time", "" + cal.getTimeInMillis());
And i'm obtaining the same values in the Android Monitor output
E/first time: Mon Oct 31 02:00:00 CET 2016
E/second time: 1477875600000
E/third time: Mon Oct 31 02:00:00 CET 2016
E/fourth time: 1477875600000
Just a copy of Thomas's comment.
It's the right answer and thank you all
Keep in mind that 1 day is not necessarily equal to 24 hours, i.e. when daylight saving is involved. As an example (not correct, just to illustrate the point) if I'd add 1 day to Oct 31st 2:00 I'd expect to get Nov 1st 2:00, but if I add 24 hours and the dst switch happens at that time I could get Nov 1st 3:00 (or so). - What I mean is that if you add 1 to the "day" field the hour is not changed but if you add 24 to the "hour" field you get a calculation of the day as well (roll over) which might include dst.
Please look into the Cal.add() method. In the first instance you add month and in the second instance you add hour. Change them and it will work fine.
Please see the documentation link: https://developer.android.com/reference/java/util/Calendar.html#getDisplayNames(int, int, java.util.Locale)
You need to use HOUR_OF_DAY for 24hr format. HOUR is HOUR is used for the 12-hour clock (0 - 11). Noon and midnight are represented by 0, not by 12. E.g., at 10:04:15.250 PM the HOUR is 10 not 22.

Calendar/Date timezone Conversion issue

I will get a Date like Sat May 31 16:38:17 GMT 2014. In DB also column has the same value. But when I will search for date like Sat May 31 16:30:00 GMT 2014 it wont search. But If I give less than 5:30 hours like Sat May 31 11:00:00 GMT 2014 . It works fine.
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone( "GMT-0:00" ));
cal.setTimeInMillis(inputDate.getTime());
cal.set(Calendar.MILLISECOND, 0);
inputDate = cal.getTime();
The underlying implementation of Date and Calendar both use the same system: a long representing milliseconds since 1st of January 1970, 0:00:00 GMT.
See Here for Date (lines 136 & 168) and HERE for Calendar (line 778)
So this gets us to this:
cal.setTimeInMillis(inputDate.getTime());
// this gets the long from the Date and puts it into the Calendar
// nothing is changed, you only get added functionality
// even if you change the Timezone this only affects how it is displayed
cal.set(Calendar.MILLISECOND, 0);
// the long is modified by setting the that represents only milliseconds to zero
inputDate = cal.getTime();
//the long is stored in a Date and returned
You get back a minimally altered Date object. Without the second instruction there would be no change at all.
This explains why nothing is converted, but not why the select doesn't work.
From the info you gave it seems there is a mismatch in the timezones of trinity of the DB, the JVM and your system.
Something in the line of this: your system is set to IST and your JVM somehow interprets your system time as GMT. To check this you could run System.out.println(new Date()). If it writes out the timezone as GTM but the numbers are the same as your systems clock (IST) then that is your problem.
You could also check:
do the time-stamps of an insert statement match with what arrives in the database
do the time-stamps of a database entry match the one you receive after a select

Java Calendar: 1am switchover to standard time (from DST)

I have some code that uses Calendar.set() to return the beginning of the hour for a given date value. I encountered the following issue on Sunday Nov 4th, 2012 (Eastern Timezone - EDT to EST switchover):
public void testStartOfHourDST1() {
Calendar cal = Calendar.getInstance();
long time = 1352005200000L; // Nov 4, 2012, 1AM EDT
cal.setTimeInMillis(time);
cal.set(Calendar.MILLISECOND, 0);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MINUTE, 0);
System.out.println(new Date(time));
System.out.println(new Date(cal.getTimeInMillis()));
System.out.println(System.getProperty("java.version"));
assertEquals(cal.getTimeInMillis(), time); // fails
return;
}
Ouput:
Sun Nov 04 01:00:00 EDT 2012
Sun Nov 04 01:00:00 EST 2012
1.6.0_35
Perhaps this is not the correct way to be using calendar, but running the same test for the next hour (or previous hour) works fine. Is this a JVM issue?
Thanks
It's not really an issue, in the sense that it is deterministic and doing what it was programmed to do. It's an issue if you would prefer that it pick the earlier of the two 1ams!
After changing fields on the Calendar the only information it has is "1am in US/Eastern". Well, your timezone had two 1ams that day, which one is it supposed to pick? The authors of OpenJDK made a decision that when presented with this ambiguity, they would always interpret it as the later one, in standard time. This comment is from java.util.GregorianCalendar OpenJDK 6:
// 2. The transition out of DST. Here, a designated time of 1:00 am - 1:59 am
// can be in standard or DST. Both are valid representations (the rep
// jumps from 1:59:59 DST to 1:00:00 Std).
// Again, we assume standard time.
If you print out the actual values of the numbers you will see cal.getTimeInMillis() has actually been changed by an hour from the value of time.
Getting the correct time zone is very important. For example, as I'm sure you are aware the system current time in milliseconds is measured from midnight on the 1st of January 1970. This is well documented. The Date constructor JavaDoc says:
public Date(long date)
Allocates a Date object and initializes it to represent the specified
number of milliseconds since the standard base time known as "the
epoch", namely January 1, 1970, 00:00:00 GMT.
which is fine, but makes the output of this program a little hard to understand at first:
import java.util.Date;
import java.util.TimeZone;
import java.text.SimpleDateFormat;
public class Demo {
public static void main(String[] args) {
TimeZone tz = TimeZone.getTimeZone("Europe/London");
Date d = new Date(-3600000);
SimpleDateFormat df = new SimpleDateFormat("MMMM dd, yyyy HH:mm:ss.SSS z");
df.setTimeZone(tz);
System.out.println(String.format("%8dms -> %s",
Long.valueOf(d.getTime()) ,df.format(d)));
d.setTime(0);
System.out.println(String.format("%8dms -> %s",
Long.valueOf(d.getTime()) ,df.format(d)));
}
}
The output is:
-3600000ms -> January 01, 1970 00:00:00.000 GMT
0ms -> January 01, 1970 01:00:00.000 GMT
As you can see, the epoch is apparently displaced by an hour!
Except it is not. If you use the "GMT" time zone explicitly, all is well. The "Europe/London" time zone is simply tricky like that.
When working with Calendars, understand the time zone you are using or be caught out.

How to set time to a date object in java

I created a Date object in Java. When I do so, it shows something like: date=Tue Aug 09 00:00:00 IST 2011. As a result, it appears that my Excel file is lesser by one day (27 feb becomes 26 feb and so on) I think it must be because of time. How can I set it to something like 5:30 pm?
Calendar cal = Calendar.getInstance();
cal.set(Calendar.HOUR_OF_DAY,17);
cal.set(Calendar.MINUTE,30);
cal.set(Calendar.SECOND,0);
cal.set(Calendar.MILLISECOND,0);
Date d = cal.getTime();
Also See
Joda time
Calendar doc
Can you show code which you use for setting date object? Anyway< you can use this code for intialisation of date:
new SimpleDateFormat("yyyy-MM-dd hh:mm:ss").parse("2011-01-01 00:00:00")
I should like to contribute the modern answer. This involves using java.time, the modern Java date and time API, and not the old Date nor Calendar except where there’s no way to avoid it.
Your issue is very likely really a timezone issue. When it is Tue Aug 09 00:00:00 IST 2011, in time zones west of IST midnight has not yet been reached. It is still Aug 8. If for example your API for putting the date into Excel expects UTC, the date will be the day before the one you intended. I believe the real and good solution is to produce a date-time of 00:00 UTC (or whatever time zone or offset is expected and used at the other end).
LocalDate yourDate = LocalDate.of(2018, Month.FEBRUARY, 27);
ZonedDateTime utcDateDime = yourDate.atStartOfDay(ZoneOffset.UTC);
System.out.println(utcDateDime);
This prints
2018-02-27T00:00Z
Z means UTC (think of it as offset zero from UTC or Zulu time zone). Better still, of course, if you could pass the LocalDate from the first code line to Excel. It doesn’t include time-of-day, so there is no confusion possible. On the other hand, if you need an old-fashioned Date object for that, convert just before handing the Date on:
Date oldfashionedDate = Date.from(utcDateDime.toInstant());
System.out.println(oldfashionedDate);
On my computer this prints
Tue Feb 27 01:00:00 CET 2018
Don’t be fooled, it is correct. My time zone (Central European Time) is at offset +01:00 from UTC in February (standard time), so 01:00:00 here is equal to 00:00:00 UTC. It’s just Date.toString() grabbing the JVMs time zone and using it for producing the string.
How can I set it to something like 5:30 pm?
To answer your direct question directly, if you have a ZonedDateTime, OffsetDateTime or LocalDateTime, in all of these cases the following will accomplish what you asked for:
yourDateTime = yourDateTime.with(LocalTime.of(17, 30));
If yourDateTime was a LocalDateTime of 2018-02-27T00:00, it will now be 2018-02-27T17:30. Similarly for the other types, only they include offset and time zone too as appropriate.
If you only had a date, as in the first snippet above, you can also add time-of-day information to it:
LocalDate yourDate = LocalDate.of(2018, Month.FEBRUARY, 27);
LocalDateTime dateTime = yourDate.atTime(LocalTime.of(17, 30));
For most purposes you should prefer to add the time-of-day in a specific time zone, though, for example
ZonedDateTime dateTime = yourDate.atTime(LocalTime.of(17, 30))
.atZone(ZoneId.of("Asia/Kolkata"));
This yields 2018-02-27T17:30+05:30[Asia/Kolkata].
Date and Calendar vs java.time
The Date class that you use as well as Calendar and SimpleDateFormat used in the other answers are long outdated, and SimpleDateFormat in particular has proven troublesome. In all cases the modern Java date and time API is so much nicer to work with. Which is why I wanted to provide this answer to an old question that is still being visited.
Link: Oracle Tutorial Date Time, explaining how to use java.time.
If you don't have access to java 8 and the API java.time, here is my simple function to copy the time of one date to another date using the old java.util.Calendar (inspire by Jigar Joshi) :
/**
* Copy only the time of one date to the date of another date.
*/
public static Date copyTimeToDate(Date date, Date time) {
Calendar t = Calendar.getInstance();
t.setTime(time);
Calendar c = Calendar.getInstance();
c.setTime(date);
c.set(Calendar.HOUR_OF_DAY, t.get(Calendar.HOUR_OF_DAY));
c.set(Calendar.MINUTE, t.get(Calendar.MINUTE));
c.set(Calendar.SECOND, t.get(Calendar.SECOND));
c.set(Calendar.MILLISECOND, t.get(Calendar.MILLISECOND));
return c.getTime();
}
Calendar calendar = new Calendar.Builder()
.setDate(2022, Calendar.JUNE, 1)
.setTimeOfDay(0, 0, 0)
.build();
System.out.println(calendar.getTimeInMillis());

Categories

Resources