Unless I do something wrong...
I live in Poland (GMT+2). By the time I write this we are in daylight saving time. The following code, however, says that the GMT time offset is only 1 hour instead of 2.
Calendar mCalendar = new GregorianCalendar();
TimeZone mTimeZone = mCalendar.getTimeZone();
System.out.println(mTimeZone);
int mGMTOffset = mTimeZone.getRawOffset();
System.out.printf("GMT offset is %s hours", TimeUnit.HOURS.convert(mGMTOffset, TimeUnit.MILLISECONDS));
prints GMT offset is 1 hours
Same happens for other timezones, for example New York, which is GMT-4:
Calendar mCalendar = new GregorianCalendar(TimeZone.getTimeZone("America/New_York"));
prints GMT offset is -5 hours
There are two methods the TimeZone you have to use:
you can check if the a date is in DaylightSaveTime with:
mTimeZone.inDaylightTime(date)
And if this is True you have to add the value of
mTimeZone.getDSTSavings()
to the Offset:
Calendar mCalendar = new GregorianCalendar();
TimeZone mTimeZone = mCalendar.getTimeZone();
System.out.println("TimeZone: "+mTimeZone);
int mGMTOffset = mTimeZone.getRawOffset();
if (mTimeZone.inDaylightTime(mCalendar.getTime())){
mGMTOffset += mTimeZone.getDSTSavings();
}
System.out.printf("GMT offset is %s hours",
TimeUnit.HOURS.convert(mGMTOffset, TimeUnit.MILLISECONDS));
output:
GMT offset is 2 hours
Check whether DST is active in java .
TimeZone tz = TimeZone.getTimeZone("America/New_York");
boolean inDs = tz.inDaylightTime(new Date());
Below code give you with DST time
TimeZone zone = TimeZone.getTimeZone("America/New_York");
DateFormat format = DateFormat.getDateTimeInstance();
format.setTimeZone(zone);
System.out.println(format.format(new Date()));
Related
I'm using this Android code for converting milliseconds to mm:ss.SS format but in result dateformat adds 30 extra minutes in date.
Date date = new Date(millis);
DateFormat dateFormat= new SimpleDateFormat("mm:ss.SS", Locale.US);
best.add(dateFormat.format(date));\
Actually I want to convert milliseconds to m:ss.SS format. Is there any other best way to achieve this?
Thanks in advance.
You can change your code to:
DurationFormatUtils.formatDuration(millis, "mm:ss.SS");
to set the TImezone:
dateFormat.setTimeZone(TimeZone.getTimeZone("GMT"));
My Guess...if you are living in a GMT+30 min time zone and unless you specify a different one, your formatter will pick your current one, so it considers 0 hours as GMT and as you are in GMT+30 Min, it outputs + 30 Minutes...
To get timezone from user current place you can use:
TimeZone tz = TimeZone.getDefault();
System.out.println("TimeZone "+tz.getDisplayName(false, TimeZone.SHORT)+" Timezon id :: " +tz.getID());
then you can set the Timezone in dateformat.
it will return you the timezone like "IST"
Also you can try the following code to find the GMT offset of a Timezone:
public String getCurrentTimezoneOffset() {
TimeZone tz = TimeZone.getDefault();
Calendar cal = GregorianCalendar.getInstance(tz);
int offsetInMillis = tz.getOffset(cal.getTimeInMillis());
String offset = String.format("%02d:%02d", Math.abs(offsetInMillis / 3600000), Math.abs((offsetInMillis / 60000) % 60));
offset = "GMT"+(offsetInMillis >= 0 ? "+" : "-") + offset;
return offset;
}
it will return Timezone like: GMT+05:30 this format
By using timezone you can find accurate time in all devices..
see this also:https://developer.android.com/reference/java/util/TimeZone.html
I get a string in the format yyyy-MM-dd HH:mm which represents a Date and Time in UTC.
Next step is to put this into a Calendar (with TimeZone UTC).
In addition need to also create a separate Calendar which has converted the UTC to "Europe/London" timeZone (GMT/BST).
After that I need to be able to detect if the "Europe/London" calendar has a DST (Day Light Savings Offset).
The code below will show you how far I have got and it runs ok on a UK based computer whose default System Timezone is GMT. However when I run it on a pc whose timezone is UTC it fails. It seems to not be able to tell me if there is an DST_offset (its always zero).
Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
cal.set(Calendar.YEAR, 2016);
cal.set(Calendar.MONTH, 1);
cal.set(Calendar.DAY_OF_MONTH, 27);
cal.set(Calendar.HOUR_OF_DAY, 23);
cal.set(Calendar.MINUTE, 35);
cal.set(Calendar.SECOND, 0);
cal.set(Calendar.MILLISECOND, 0);
//This is required as Java Date JAN starts at 0.
int MonthCon = cal.get(Calendar.MONTH)-1;
cal.set(Calendar.MONTH, MonthCon);
Date d = cal.getTime();
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
f.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println("UTC: " + f.format(d));
f.setTimeZone(TimeZone.getTimeZone("Europe/London"));
System.out.println("BST: " + f.format(d));
//Creates a BST calendar of the same UTC time
String dateStrBST = f.format(d);
SimpleDateFormat curFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
curFormater.setTimeZone(TimeZone.getTimeZone("Europe/London"));
Date dateObjBST = curFormater.parse(dateStrBST);
System.out.println("BSTNewDate: " + f.format(dateObjBST));
Calendar calBST = Calendar.getInstance(TimeZone.getTimeZone("BST"));
calBST.setTime(dateObjBST);
System.out.println("Current TimeZone is : " + calBST.getTimeZone());
int offset = calBST.get(Calendar.DST_OFFSET);
System.out.println("Day Light Savings: "+offset);
System.out.println("Transition Day: "+isDSTTransitionDay(cal.get(Calendar.YEAR),cal.get(Calendar.MONTH),cal.get(Calendar.DAY_OF_MONTH))+" Transition Type: "+DSTtransitionType(cal.get(Calendar.YEAR),cal.get(Calendar.MONTH),cal.get(Calendar.DAY_OF_MONTH)));
Unfortunately I need to be able to detect if any particular day is a transition day, that is to say a day that changes from DST on/off or off/on. Again this works on the local computer but not on the UTC timezone one.
private static boolean isDSTTransitionDay(int year, int month, int day) throws ParseException
{
Calendar calStartofDay = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calStartofDay.set(Calendar.YEAR, year);
calStartofDay.set(Calendar.MONTH, month);
calStartofDay.set(Calendar.DAY_OF_MONTH, day);
calStartofDay.set(Calendar.HOUR_OF_DAY, 00);
calStartofDay.set(Calendar.MINUTE, 0);
calStartofDay.set(Calendar.SECOND, 1);
Date dStartofDay = calStartofDay.getTime();
SimpleDateFormat f = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
f.setTimeZone(TimeZone.getTimeZone("Europe/London"));
String dateStrUTCtoBST = f.format(dStartofDay);
SimpleDateFormat curFormater = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssz");
curFormater.setTimeZone(TimeZone.getTimeZone("Europe/London"));
Date dateObjBST = curFormater.parse(dateStrUTCtoBST);
Calendar calBST = Calendar.getInstance();
calBST.setTime(dateObjBST);
int offsetStart = calBST.get(Calendar.DST_OFFSET);
calBST.add(Calendar.HOUR_OF_DAY, 23);
int offsetEnd = calBST.get(Calendar.DST_OFFSET);
//System.out.println("Start: "+offsetStart+" End: "+offsetEnd);
if (offsetEnd == offsetStart)
{
return false;
}else
{
//if(offsetStart<offsetEnd) {System.out.println("Transition to BST");}else{System.out.println("Transition to UTC/GMT");};
return true;
}
}
So on the UTC computer it fails miserably as it always puts Calendar.DST_OFFSET at zero. I have clearly misunderstood something along the way so any help/clarity would be good.
I pretty much have to keep Calendars as the rest of the code uses it but I realise the Java8 has many more fancy ways to do things.
Please allow me to be honest, I tried to read your code and didn’t really understand your way of trying to obtain what you want. If you can use Java 8, I recommend switching to using the Java 8 date and time classes. With these your job isn’t very complicated. For the demonstration I have chosen last October 30, the date when Britain (and EU) changed back from summer time (daylight saving time) to standard time.
String originalDate = "2016-10-30 23:35";
LocalDateTime localTime = LocalDateTime.parse(originalDate, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm"));
ZonedDateTime utcTime = localTime.atZone(ZoneOffset.UTC);
ZonedDateTime bstTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/London"));
// the summer time offset is how many milliseconds?
long dstOffset = ChronoUnit.MILLIS.between(utcTime.toLocalDateTime(), bstTime.toLocalDateTime());
System.out.println(dstOffset); // prints 0
// try the same at start of day (midnight)
utcTime = utcTime.toLocalDate().atStartOfDay(ZoneOffset.UTC);
bstTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/London"));
dstOffset = ChronoUnit.MILLIS.between(utcTime.toLocalDateTime(), bstTime.toLocalDateTime());
System.out.println(dstOffset); // prints 3600000
// and next midnight
utcTime = utcTime.plusDays(1);
bstTime = utcTime.withZoneSameInstant(ZoneId.of("Europe/London"));
dstOffset = ChronoUnit.MILLIS.between(utcTime.toLocalDateTime(), bstTime.toLocalDateTime());
System.out.println(dstOffset); // prints 0
You are using
Calendar calBST = Calendar.getInstance();
That sets calBST to the computer's timezone (on the UTC computer, it will be UTC).
calBST.setTime(dateObjBST); sets the time, not the timezone.
Try using getInstance(TimeZone zone) there also.
In any case, I would replace your code like this:
Calendar calStartofDay = Calendar.getInstance(TimeZone.getTimeZone("UTC"));
calStartofDay.set(Calendar.YEAR, 2017);
calStartofDay.set(Calendar.MONTH, 0);
calStartofDay.set(Calendar.DAY_OF_MONTH, 21);
calStartofDay.set(Calendar.HOUR_OF_DAY, 00);
calStartofDay.set(Calendar.MINUTE, 0);
calStartofDay.set(Calendar.SECOND, 1);
Calendar calBST = Calendar.getInstance(TimeZone.getTimeZone("Europe/London"));
calBST.setTimeInMillis(calStartofDay.getTimeInMillis());
// use this to check the time
System.out.printf("%tc%n", calBST);
Also, from the Calendar docs, be careful about this:
set(f, value) changes calendar field f to value. In addition, it sets
an internal member variable to indicate that calendar field f has been
changed. Although calendar field f is changed immediately, the
calendar's time value in milliseconds is not recomputed until the next
call to get(), getTime(), getTimeInMillis(), add(), or roll() is made.
Thus, multiple calls to set() do not trigger multiple, unnecessary
computations. As a result of changing a calendar field using set(),
other calendar fields may also change, depending on the calendar
field, the calendar field value, and the calendar system. In addition,
get(f) will not necessarily return value set by the call to the set
method after the calendar fields have been recomputed. The specifics
are determined by the concrete calendar class.
I found some similar questions, such as:
How to get the timezone offset in GMT(Like GMT+7:00) from android device?
How to find out GMT offset value in android
But all these answers(+12:00) are incorrect for New Zealand Daylight Saving Time now.
When I did debug, I got this from Google Calendar event object:
"dateTime" -> "2016-11-06T10:00:00.000+13:00"
So how to get the correct offset which should be +13:00?
Thanks.
To get the current offset from UTC in milliseconds (which can vary according to DST):
return TimeZone.getDefault().getOffset(System.currentTimeMillis());
To get a RFC 822 timezone String instead, you can simply create a SimpleDateFormat instance:
return new SimpleDateFormat("Z").format(new Date());
The format is (+/-)HHMM
So, I tried to get gmt offset through Calendar and SimpleDateFormat but both returns 0. I found the solution using deprecated methods in Date class.
So, this code works for me.
private double getOffset() {
Calendar calendar = Calendar.getInstance(Locale.ENGLISH);
int defHour = calendar.get(Calendar.HOUR_OF_DAY);
int defMinute = calendar.get(Calendar.MINUTE) + (defHour * 60);
Date date = new Date(System.currentTimeMillis());
int curHour = date.getHours();
int curMinute = date.getMinutes() + (curHour * 60);
double offset = ((double) curMinute - defMinute) / 60;
return offset > 12? -24 + offset : offset;
}
Then you can format a result
This code return me GMT offset.
Calendar calendar = Calendar.getInstance(TimeZone.getTimeZone("GMT"), Locale.getDefault());
Date currentLocalTime = calendar.getTime();
DateFormat date = new SimpleDateFormat("Z");
String localTime = date.format(currentLocalTime);
It returns the time zone offset like this: +0530
TimeZone.setDefault(TimeZone.getTimeZone("Europe/Moscow"));
System.out.println("Default Timezone: " + TimeZone.getDefault());
String date = "08/04/2016 00:00:00";
SimpleDateFormat simpleDateFormatMoscow = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
Date moscowDt = simpleDateFormatMoscow.parse(date);
System.out.println("Moscow Date: " + simpleDateFormatMoscow.format(moscowDt));
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("dd/MM/yyyy HH:mm:ss");
simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Bangkok"));
System.out.println("Bangkok Date: " + simpleDateFormat.format(moscowDt));
Calendar calendar = new GregorianCalendar();
calendar.setTime(moscowDt);
calendar.setTimeZone(TimeZone.getTimeZone("Asia/Bangkok"));
System.out.println("Bangkok Date: " + simpleDateFormat.format(calendar.getTime()));
System.out.println("Test Timezone");
System.out.println(TimeZone.getTimeZone("America/New_York"));
System.out.println(TimeZone.getTimeZone("Europe/Moscow"));
System.out.println(TimeZone.getTimeZone("Asia/Bangkok"));
I tried to use the code this snippet to convert date/time between Moscow and Bangkok. The result is as followed:
Default Timezone:
sun.util.calendar.ZoneInfo[id="Europe/Moscow",offset=14400000,dstSavings=0,useDaylight=false,transitions=78,lastRule=null]
Moscow Date: 08/04/2016 00:00:00
//util date/time
Bangkok Date: 08/04/2016 03:00:00
//joda time
Bangkok Date: 08/04/2016 03:00:00
However, when I convert date/time using https://singztechmusings.wordpress.com/2011/06/23/java-timezone-correctionconversion-with-daylight-savings-time-settings/ or google the time is
Moscow Date: 08/04/2016 00:00:00
Bangkok Date: 08/04/2016 04:00:00
Could anyone please tell me the correct way to convert data/time using java?
And Could anyone please tell me what I did wrong and why the result is inaccurate?
Your Java have wrong timezone offset: "offset=14400000" is 4 hours, but Moscow is UTC+3 for last year and a half.
Upgrade your java with tzupdater.
Java is using its own timezone data which is independenct from the host operation system. It might be inaccurate if you are not using the latest version of Java cause Russia (Europe/Moscow) has switched from daylight saving time to permanent standard time two years ago
This is one way to do it using your local time zone first.
public static void main(String[] args) {
// Create a calendar object and set it time based on the local time zone
Calendar localTime = Calendar.getInstance();
localTime.set(Calendar.HOUR, 17);
localTime.set(Calendar.MINUTE, 15);
localTime.set(Calendar.SECOND, 20);
int hour = localTime.get(Calendar.HOUR);
int minute = localTime.get(Calendar.MINUTE);
int second = localTime.get(Calendar.SECOND);
// Print the local time
System.out.printf("Local time : %02d:%02d:%02d\n", hour, minute, second);
// Create a calendar object for representing a Bangkok time zone. Then we set
//the time of the calendar with the value of the local time
Calendar BangkokTime = new GregorianCalendar(TimeZone.getTimeZone("Asia/Bangkok"));
BangkokTime.setTimeInMillis(localTime.getTimeInMillis());
hour = BangkokTime.get(Calendar.HOUR);
minute = BangkokTime.get(Calendar.MINUTE);
second = BangkokTime.get(Calendar.SECOND);
// Print the local time in Bangkok time zone
System.out.printf("Bangkok time: %02d:%02d:%02d\n", hour, minute, second);
//Then do the same for the Moscow time zone
Calendar MoscowTime = new GregorianCalendar(TimeZone.getTimeZone("Europe/Moscow"));
MoscowTime.setTimeInMillis(localTime.getTimeInMillis());
hour = MoscowTime.get(Calendar.HOUR);
minute = MoscowTime.get(Calendar.MINUTE);
second = MoscowTime.get(Calendar.SECOND);
// Print the local time in Moscow time zone
System.out.printf("Moscow time: %02d:%02d:%02d\n", hour, minute, second);
}
my code computes the date and time correctly including the dayLightSaving time,when run on my local server from india. But when I run the same code from US server I am getting the time which is one hour ahead for the timeZoneId which is not abserving DST.
TimeZone tz = TimeZone.getTimeZone("America/Phoenix");
Date currTime = getDateByTZ(new Date(), tz);
System.out.println("currTime" + currTime);
public static Date getDateByTZ(Date d, TimeZone tz) throws Exception {
if (tz == null) {
tz = TimeZone.getDefault();
}
Integer tzOffSet = tz.getRawOffset();
Integer tzDST = tz.getDSTSavings();
Integer defOffSet = TimeZone.getDefault().getRawOffset();
Integer defDST = TimeZone.getDefault().getDSTSavings();
Calendar cal = Calendar.getInstance(tz);
cal.setTime(d);
if (tz.inDaylightTime(d)) {
cal.add(Calendar.MILLISECOND, -defOffSet);
cal.add(Calendar.MILLISECOND, -defDST);
cal.add(Calendar.MILLISECOND, +tzOffSet);
cal.add(Calendar.MILLISECOND, +tzDST);
} else {
cal.add(Calendar.MILLISECOND, -defOffSet);
cal.add(Calendar.MILLISECOND, tzOffSet);
}
return cal.getTime();
}
Results from Localserver:
currTime:Mon Oct 22 01:52:21 IST 2012
Results from USserver:
currTime:Mon Oct 22 02:52:21 IST 2012
This code doesn't make much sense. A Date object doesn't have to be transformed to be used in another time zone. It represents a universal instant.
What makes sense is to use the time zone when displaying (or formatting as a string) a Date object. In this case, you should simply set the time zone on the DateFormat instance, and the universal instant that constitutes a date will be formatted in order to make sense for the given time zone.
Date now = new Date(); // now, whatever the timezone is
DateFormat df = DateFormat.getDateTimeInstance();
df.setTimeZone(TimeZone.getDefault());
System.out.println("Now displayed in the default time zone : " + df.format(now));
df.setTimeZone(TimeZone.getTimeZone("America/New_York"));
System.out.println("Now displayed in the New York time zone : " + df.format(now));