I cannot use Joda. When I try to create a Date or Calendar from a String representing a date or datetime in UTC, the resulting object has a timezone associated with it...
Here's the code:
Case 1:
SimpleDateFormat sdf = new SimpleDateFormat("yyyyDDD");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = sdf.parse("2012018");
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
cal.setTime(date);
System.out.println(cal.getTime()); //Tue Jan 17 19:00:00 EST 2012 !?!*&#&??
Case 2:
SimpleDateFormat sdf = new SimpleDateFormat("yyMMddHHmm");
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = sdf.parse("1202011431");
Calendar cal = new GregorianCalendar(TimeZone.getTimeZone("UTC"));
cal.setTime(date);
System.out.println(cal.getTime()); //Wed Feb 01 09:31:00 EST 2012 !?!*&#&??
Objects of type java.util.Date are an absolute amount of time since Epoch. When you create a Date object from a Calendar, it loses any TimeZone that the Calendar may have been using and just gives you a raw quantity of time. EST isn't really 'associated' with your Date, it's just that the toString method on Date uses the JVM default timezone to create a human readable representation.
It's important to understand that the usage of Calendar in the above code samples is doing absolutely nothing. Changing just the timezone like that changes only the human readable representation of that Calendar. The raw number of milliseconds since epoch is the same before and after you call setTime and getTime.
(All of the methods on java.util.Date that are related to human readable representations are deprecated and do not work properly, it is best to simply pretend they do not exist.)
When you print the time, it is always printed in local timezone configured on your machine and that is what you want (Store and represent date/time in UTC and convert to user specific timezone during presentation).
Yes, dates in Java have a time zone associated with them. The toString on a Date prints the date in the local timezone. If you do not want that, use a DateFormat to not show it. Note, that you will need to set the timezone on the DateFormat to UTC to get what you want.
Related
I'm using "Asia/Bangkok" zone id.
That offset is from GMT UTC+07:00.
but when I did followings, then it is not +7:00 when set "01/01/1900 7:00:00.000"
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSS");
Date date = dateFormat.parse("01/01/1900 7:00:00.000");
System.out.println(date);
System.out.println(date.getTimezoneOffset());
Date date2 = dateFormat.parse("01/01/1900 6:00:00.000");
System.out.println(date2);
System.out.println(date2.getTimezoneOffset());
The result is
Mon Jan 01 07:00:00 ICT 1900
-402
Mon Jan 01 06:00:00 ICT 1900
-420
I wondered if the offset had changed around 7:00 a.m. on January 1, 1900, so I looked it up on Wikipedia.
https://en.wikipedia.org/wiki/Time_in_Thailand
It was UTC+6:42, but from 1880 to 1920.
I have 3 questions.
Why it happen different time offset between "01/01/1900 7:00:00.000" and "01/01/1900 6:00:00.000"
Where can I see time zone history in Java.
How can I ignore different time offset in same Timezone.
-- additional question --
I understand that I should use LocalDateTime.
What is the best way to ignore offset and convert Date to LocalDateTime?
For example, in the following case, the value of convertedDate2 was converted based on an offset of -402.
DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MM/dd/yyyy H:mm:ss.SSS");
LocalDateTime originalLdate = LocalDateTime.parse("01/01/1900 7:00:00.000", dateFormatter);
LocalDateTime originalLdate2 = LocalDateTime.parse("01/01/1900 6:00:00.000", dateFormatter);
System.out.println(originalLdate);
System.out.println(originalLdate2);
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy HH:mm:ss.SSS");
Date date = dateFormat.parse("01/01/1900 7:00:00.000");
Date date2 = dateFormat.parse("01/01/1900 6:00:00.000");
LocalDateTime convertedDate = date.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
LocalDateTime convertedDate2 = date2.toInstant().atZone(ZoneId.systemDefault()).toLocalDateTime();
System.out.println(convertedDate);
System.out.println(convertedDate2);
LocalDateTime convertedDate3 = LocalDateTime.parse(dateFormat.format(date), dateFormatter);
LocalDateTime convertedDate4 = LocalDateTime.parse(dateFormat.format(date2), dateFormatter);
System.out.println(convertedDate3);
System.out.println(convertedDate4);
The result is
1900-01-01T07:00
1900-01-01T06:00
1900-01-01T07:00
1900-01-01T05:42:04
1900-01-01T07:00
1900-01-01T06:00
If I convert it once to String and then to LocalDateTime, as in convertedDate3 and convertedDate4,
then I could convert as my expectation, but I wonder this is the most efficient way or not?
Java runtime timezone information for each version is available here
https://www.oracle.com/java/technologies/tzdata-versions.html
Inside the linked file (for a specific version) you can find links to the actual data used
https://www.iana.org/time-zones/repository/releases/tzcode2021a.tar.gz
https://www.iana.org/time-zones/repository/releases/tzdata2021a.tar.gz
https://www.iana.org/time-zones/repository/releases/tzdb-2021a.tar.lz
Inside the tzdata*.tar.gz you can find a file called asia which contains the data for Bangkok as well.
It contains these entries
# Thailand
# Zone NAME STDOFF RULES FORMAT [UNTIL]
Zone Asia/Bangkok 6:42:04 - LMT 1880
6:42:04 - BMT 1920 Apr # Bangkok Mean Time
7:00 - +07
Link Asia/Bangkok Asia/Phnom_Penh # Cambodia
Link Asia/Bangkok Asia/Vientiane # Laos
So the -402 timezone should be used for all dates before 1/4/1920, but it seems the implementation is using the -402 offset only from 1/1/1900 0:00:00.000 UTC (from 1/1/1900 6:42:04.000 in your timezone) and until 1/4/1920 in your timezone and -420 otherwise. I am not sure, if that is intended or a bug.
How can I ignore different time offset in same Timezone.
If you are actually using timezones in your application, then you should not ignore them.
However, if you are making an application that is intended to be used just in your local timezone, then you can use a DateTime class without timezone information, such as java.time.LocalDateTime.
Also worth noting: even if these timezones would be correct, the historical dates might still be inaccurate, due to modern time rules being applied for all time (see below). So in the end it depends on what your use case is.
A date-time without a time-zone in the ISO-8601 calendar system. The ISO-8601 calendar system is the modern civil calendar system used today in most of the world. It is equivalent to the proleptic Gregorian calendar system, in which today's rules for leap years are applied for all time. For most applications written today, the ISO-8601 rules are entirely suitable. However, any application that makes use of historical dates, and requires them to be accurate will find the ISO-8601 approach unsuitable.
java.util.Date and java.text.SimpleDateFormat are very old classes. Although they mostly work, they are difficult to use properly, especially where timezones are concerned.
Date.getTimezoneOffset is deprecated. Do not use deprecated methods.
The proper way to work with timezone rules is using the java.time, java.time.zone, and java.time.format packages:
ZoneId zone = ZoneId.systemDefault();
DateTimeFormatter dateFormatter =
DateTimeFormatter.ofPattern("MM/dd/yyyy H:mm:ss.SSS");
LocalDateTime date =
LocalDateTime.parse("01/01/1900 7:00:00.000", dateFormatter);
System.out.println(date);
System.out.println(zone.getRules().getOffset(date));
LocalDateTime date2 =
LocalDateTime.parse("01/01/1900 6:00:00.000", dateFormatter);
System.out.println(date2);
System.out.println(zone.getRules().getOffset(date2));
The entire history of a timezone is in the ZoneRules:
System.out.println();
zone.getRules().getTransitions().forEach(System.out::println);
System.out.println();
zone.getRules().getTransitionRules().forEach(System.out::println);
You also asked:
What is the best way to ignore offset and convert Date to LocalDateTime?
You can’t. It is not possible to convert a Date to a LocalDateTime without assuming a timezone.
A Date is a wrapper for the number of milliseconds since 1970-01-01 00:00:00 UTC. You cannot generate a LocalDateTime from that without knowing which timezone to apply to that millisecond count. For example, noon Eastern Time in the US is a different number of milliseconds since 1970 than noon Greenwich time.
You may not realize it, but when you use SimpleDateFormat, you are specifying a timezone. Every SimpleDateFormat has a timezone property. Since your code never set that timezone explicitly, your date format used the system’s default timezone.
That is one reason to avoid DateFormat and SimpleDateFormat: the implicit use of the default timezone leads to errors and confusing behavior (though it is predictable behavior). When you use the java.time package and its subpackages, there is no ambiguity, and far less chance of confusion.
I have a timestamp that I am trying to put into a Date object, however when I use Calendar, I am running into a strange problem. I seem to be able to unable to create a Date object with the values I want:
public static void main(String args[]){
Date today = new Date();
int hour = 4, min=0, sec=0, ms=64;
Calendar cal = GregorianCalendar.getInstance();
cal.clear();
cal.setTimeZone(TimeZone.getTimeZone("EDT"));
cal.setTime(today);
cal.set(Calendar.HOUR_OF_DAY,hour);
cal.set(Calendar.MINUTE,min);
cal.set(Calendar.SECOND,sec);
cal.set(Calendar.MILLISECOND,ms);
System.out.println("Time is: "+cal.getTime());
}
This produces:
Time is: Mon Jan 13 23:00:00 EST 2014
which is not the result I am looking for.
However, if I comment out the 'setTimeZone' method call, I get the following result:
Time is: Tue Jan 14 04:00:00 EST 2014
This is the result that I am looking for but I am concerned that if I am running on a machine that is not running in the same time zone, I will not get consistent behavior.
This is the result that I am looking for but I am concerned that if I am running on a machine that is not running in the same time zone
it is the problem. The internal representation should be ok, but it prints on local timezone: representation differs from real content.
use SimpleDateFormat http://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html and set TimeZone to see the date on the Zone desired.
The problem here is that Java does not know of the timezone "EDT" (Eastern Daylight Time). As a result, Calendar seems to be setting the timezone to GMT.
The timezone needed here is "America/New_York" or "EST5EDT". When either of these values are used, the correct result is produced.
The list of valid Time Zones can be obtained by calling TimeZone.getAvailableIDs()
It is unfortunate that no warnings are produced when the requested Time Zone is not found.
If you can do away with java.util.Date, you can use joda time API to conveniently set these values as desired:
For your query, you can set your already created Calendar instance as a constructor parameter to DateTime.
DateTime dt = new DateTime(cal);
System.out.println(dt.toDateTimeISO());
Output:
2014-01-14T04:00:00.064-05:00
Calendar.getTime() returns a java.util.Date object. Date objects do not know anything about timezones. The Date object that Calendar.getTime() returns does not know to what timezone the Calendar that it came from is set.
When you print a Date object (for example, by implicitly calling toString() object, as you are doing) it is formatted in the default time zone of the machine you are running it on.
If you want to print a Date in a specific timezone, use a SimpleDateFormat, and set the desired timezone on the SimpleDateFormat object. For example:
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("EDT"));
// Will display the date that the calendar is set to in the EDT timezone
System.out.println(df.format(cal.getTime()));
Java Date objects represent the number of milliseconds seconds since January 1, 1970, 00:00:00 GMT due to the fact that the other methods are deprecated. The two ways to "view" a Date object directly are "getTime()" and "toString()" (using "dow mon dd hh:mm:ss zzz yyyy"). Therefore, you are formatting the GMT value to your local timezone.
When working with dates, it is best to think of them as GMT values, and then as a "formatting" exercise when viewing the date.
For comparison, here is that same kind of code but using Joda-Time 2.3.
Avoid the java.util.Date & .Calendar classes.
Never use three-letter codes for time zones. They are neither standardized nor unique. Instead use proper time zone names. In this case, use "America/New_York" or "America/Montreal".
// Use time zone names, such as from this slightly outdated list: http://joda-time.sourceforge.net/timezones.html
DateTimeZone timeZone = DateTimeZone.forID( "America/New_York" );
// Input.
int hour = 4, min = 0, sec = 0, ms = 64;
// Start with now, then adjust the time of day.
DateTime now = new DateTime( timeZone );
DateTime dateTime = now.withHourOfDay( hour ).withMinuteOfHour( min ).withSecondOfMinute( sec ).withMillisOfSecond( ms );
// If needed, translate to a java.util.Date for use with other classes.
java.util.Date date = dateTime.toDate();
Dump to console…
System.out.println( "now: " + now );
System.out.println( "dateTime: " + dateTime );
System.out.println( "date: " + date );
When run…
now: 2014-01-20T21:04:51.237-05:00
dateTime: 2014-01-20T04:00:00.064-05:00
date: Mon Jan 20 01:00:00 PST 2014
I'm using Java 6. Our servers are on Eastern Standard Time (GMT-5), and I'm trying to store a value that should be interpreted as such but I'm confused about how to convert it. I have
String dateStr = "1368921600000"; // This is 5/19/2013 00:00:00
final Calendar cal = Calendar.getInstance();
cal.setTimeZone(TimeZone.getTimeZone("GMT-5"));
cal.setTimeInMillis(Long.parseLong(dateStr));
final java.util.Date dateObj = cal.getTime();
System.out.println(dateObj.toString());
but right now this prints out "Sat May 18 19:00:00 CDT 2013" (since my local machine is on CDT) but I want the result to be "Sat May 18 24:00:00 CDT 2013". How can i interpret the date string "1368921600000" as an EST date? Thanks, - Dave
1368921600000 is an instant in time, the same instant, everywhere in the world. To convert this to a date and time, you have to specify where in the world you want to know the date/time at that instant. It just so happens that the timestamp is relative to UTC, and is Sun, 19 May 2013 00:00:00 GMT.
If you want the time of this instant (the same instant) somewhere else in the world, you can use the Calendar as you did and extract the individual field values (e.g. HOUR_OF_DAY). If all you care about is getting a text string, you use a DateFormat instance such as SimpleDateFormat:
DateFormat df = new SimpleDateFormat("EEE, d MMM yyyy HH:mm:ss z");
df.setTimeZone(TimeZone.getTimeZone("America/New_York"));
String timeOnUSEastCoast = df.format(new Date(1368921600000L));
// will be GMT-5 or GMT-4 depending on DST
In this example, the output would be GMT-4: Sat, 18 May 2013 20:00:00 EDT (not only has the hour changed, but it's still the previous day on the US east coast).
If you want to output the UTC time but just want to pretend it's EST then it's just easier to tell the DateFormat to leave off the time zone field (remove the "z") in the text output and call it whatever you want, but understand that the timestamp value is always UTC.
It is often not necessary to use the Joda Time library to get historically accurate time-zone- and daylight-savings-aware local time mappings, although this is the common go to response for many.
If you have a database of timestamps that require local time conversion, then here are some principles that have served me well:
Store date/times (Instants, in the parlance of Joda; Dates, in the parlance of the Java Calendar API) in UTC time. UTC does not care about DST. It does not care about time zones. UTC simply represents a universally representable moment in time. This step alone can save a lot of date/time headaches.
Database records should contain TimeZone and/or Locale fields so that mapping from UTC can be performed. Think about your data. Every timestamp in your database does not need time zone information associated with it. Instead, associate the time zone data with a part of your data model that provides appropriate granularity. If your app will only ever be localized in one time zone, then you needn't store this infor at all. In my recent project, I created a Locale table that contains the TZ ID for timestamps in my Encounters table. All other timestamps are subordinate to these records, so it made sense to associate it there.
Use the Java API GregorianCalendar to map UTC Dates to local time. And that's all I ever use it for. I almost never use GregorianCalendars to do date arithmetic or other date operations. Here is the paradigm that I've been working with:
public static void main(String[] args) {
m_GregorianCalendar = new GregorianCalendar(TimeZone.getTimeZone(
"America/Chicago"));
Date d = new Date();
String fmt = "dd-MMM-yyyy # HH:mm";
:
:
String myDate = mapToLocalTime(d, fmt, gc);
:
:
}
public String mapToLocalTime(Date utc, String format, GregorianCalendar gc) {
gc.setTime(utc); // this calendar is already timezone aware (constructed
// with time zone id (DST too))
SimpleDateFormat sdf = new SimpleDateFormat();
sdf.setCalendar(gc); // formatter uses conventions of calendar
sdf.applyPattern(fmt); // pattern for formatter
return sdf.format(utc);
}
Consider representing timestamps internally in a numeric format (longs, doubles). This greatly simplifies date comparisons and date arithmetic. The only downside is that conversions must be done to format the data into a human recognizable form, but if you use functions for these conversions it need not be a big deal at all.
Use either a new java.util.SimpleDateFormat(format) or java.util.DateFormat.getDateTimeInstance(int,int), then use #setTimeZone(timezone).
When you're printing Date.toString(), the Calendar's time zone is not taken into consideration at all. After you do a cal.getTime(), whatever was set in Calendar is no longer relevant.
What is is TimeZone's default time zone.
So right before printing the date, set the default time zone to the one you want to print in, e.g.:
String dateStr = "1368921600000"; // This is 5/19/2013 00:00:00
final Calendar cal = Calendar.getInstance();
TimeZone gmtZero = TimeZone.getTimeZone("GMT");
cal.setTimeInMillis(Long.parseLong(dateStr));
final java.util.Date dateObj = cal.getTime();
TimeZone.setDefault(gmtZero);
System.out.println(dateObj.toString());
This will print the date in GMT regardless of your system time zone.
Just remember to bring back the original default TimeZone afterwards!
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());
I have a db, that stores dates in OleDateTime format, in GMT timezone. I've implemented a class, extending Date in java to represent that in classic date format. But my class is locale-dependent (I'm in GMT+2). Therefore, it converts the date in the db as date - 2 hours. How do I make it convert the date correctly? I want my class to be locale-independent, always using GMT timezone. Actually, the question is:
class MyOleDateTime extends Date {
static {
Locale.setDefault(WhatGoesHere?)
}
// ... some constructors
// ... some methods
}
Well, it's better to use the Calendar object like suggested in other answers. However, if you really want to set global timezone, you can use TimeZone.setDefault(TimeZone.getTimeZone("UTC")); early in your application code. There is also user.timezone Java system property.
Also (just fun to know), it appears that the only country actually living by GMT/UTC time (without daylight saving changes) is Liberia.
In fact, Date objects per se are always locale- and timezone-independent. Its getTime() method will always return the number of milliseconds passed since January 1, 1970 00:00:00 (not counting leap seconds) in UTC. But if you want to get something else than milliseconds, you have to use Calendar, which is timezone-dependent. But it is the right way to go. You don't use that deprecated methods in Date class, do you?
As Michael Borgwardt has already said, the Java Date object does not know anything about timezones. It's just a wrapper for a number of milliseconds since 01-01-1970 00:00:00 UTC.
You start dealing with timezones only when you for example convert the Date object to a String using a DateFormat. You set the timezone on the DateFormat to specify in which timezone you want to see the Date.
DateFormat df = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss Z");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
String text = df.format(date); // text will contain date represented in UTC
A Date is locale-independent, always using GMT timezone. It's just a wrapper around a millisecond timestamp in GMT (more correctly: UTC).
The only things in Date that are timezone dependant are the deprecated methods like getDay() - that's why they're deprecated. Those use the default time zone. The correct thing to do is to avoid using those deprecated methods - not to set the default timezone to UTC! That could cause problems elsewhere, and you can't prevent other parts of the code from setting the default timezone to something else.
Use a Calendar object:
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("GMT"),
locale);
Here's a snippet I used to calculate the GMT offset from the Calendar instance and format it. I appreciate all the help I've gotten from this site, its nice to contribute. I hope this helps someone somewhere. Enjoy.
Calendar calInst = Calendar.getInstance();
//calculate the offset to keep calendar instance GMT
int gmtOffsetMilli = calInst.get(Calendar.ZONE_OFFSET);
long gmtOffsetHr = TimeUnit.HOURS.convert(gmtOffsetMilli, TimeUnit.MILLISECONDS);
calInst = Calendar.getInstance(TimeZone.getTimeZone("GMT " + gmtOffsetHr));