If i create a new Date() object. What will be the default timezone it will print.
I have my machine running in GMT. And i am creating a new Date() object. If i print why does it shows Thu Jul 05 08:21:05 PKT 2012. How does it takes the timezone as PKT ?
The date itself doesn't have any time zone. Its toString() method uses the current default time zone to return a String representing this date:
Date date = new Date();
System.out.println(TimeZone.getDefault());
System.out.println(date);
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
System.out.println(TimeZone.getDefault());
System.out.println(date);
Executing the above code on my machine leads to the following output:
sun.util.calendar.ZoneInfo[id="Europe/Paris",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=184,lastRule=java.util.SimpleTimeZone[id=Europe/Paris,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]
Fri Jul 06 09:24:45 CEST 2012
sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
Fri Jul 06 07:24:45 UTC 2012
Well actually basic date times usually are time zone agnostic, they don't store time zones. To make use of time zone you use formatters, calendars and the like. Of course the basic date has to be in a default time zone, whatever it might be (usually GMT), otherwise you wouldn't be able to create a local date from the basic date instance.
In you particular case it would help to look into a) the javadocs and b) into the class itself, since JDK is usually distributed with source code of java.util.Date. According to javadoc the java.util.Date class represents number of milliseconds since the standard base time known as "the epoch", namely 1 January 1970, 00:00:00 GMT.
If it shows a different date when printed on your machine, it is because your system will print it using time zone default for your system. You can however print it yourself using any other time zone.
If you are running under linux, there is some magic timezone file somewhere in the system. For my gentoo the magic was just creating a text file /etc/timezone with content
Europe/Berlin
The funny thing is that date gave the correct time and timezone (CEST) all the time, but java sent me to Greenwhich.
> date
Thu Sep 18 08:49:14 CEST 2014
Related
I have the following date object Wed Nov 01 00:00:00 GMT 2017. This obviously is in GMT, however, I'd like to consider it to be in a different timezone.
As an example, I'd like to consider the above date in the following timezone US/Mountain and I'd like to then convert it to UTC, resulting in Wed Nov 01 07:00:00 UTC.
I've tried to find a way to change the timezone of a date, while preserving the time, but failed.
Thanks
I understand from you comment that you have got a java.util.Date instance. It prints as (for example) Wed Nov 01 00:00:00 GMT 2017. This is what its toString method produces. The Date doesn’t have a time zone in it. Usually Date.toString() grabs the JVM’s time zone setting and renders the date in this time zone. So it appears you are running GMT time zone? You can read more in this popular blog entry: All about java.util.Date.
If you can, avoid having a Date. The modern Java date and time API known as java.time or JSR-310 is so much nicer to work with, both in general and not least for time zone magic like yours. Then use assylias’ answer.
For this answer I am assuming that you got a Date from some legacy API that you cannot change (or cannot afford to change just now). I still recommend the modern API for the change you desire. The output from the following snippet I give as comments in the code.
System.out.println(oldFashionedDateObject); // Wed Nov 01 00:00:00 GMT 2017
// first thing, convert the Date to an instance of a modern class, Instant
Instant pointInTime = oldFashionedDateObject.toInstant();
// convert to same hour and minute in US/Mountain and then back into UTC
ZonedDateTime convertedDateTime = pointInTime.atOffset(ZoneOffset.UTC)
.atZoneSimilarLocal(ZoneId.of("US/Mountain"))
.withZoneSameInstant(ZoneOffset.UTC);
System.out.println(convertedDateTime); // 2017-11-01T06:00Z
// only assuming you absolutely and indispensably need an old-fashioned Date object back
oldFashionedDateObject = Date.from(convertedDateTime.toInstant());
System.out.println(oldFashionedDateObject); // Wed Nov 01 06:00:00 GMT 2017
As assylias, I got Wed Nov 01 06:00:00. According to Current Local Time in Denver, Colorado, USA summer time (DST) ended on November 5 this year.
With the java time API, you can:
Parse the string as a ZonedDateTime
Use the zonedDateTime.withZoneSameLocal and zonedDateTime.withZoneSameInstant to convert the result
Something like this:
DateTimeFormatter fmt = DateTimeFormatter.ofPattern("EEE MMM dd HH:mm:ss z uuuu");
ZonedDateTime gmt = ZonedDateTime.parse("Wed Nov 01 00:00:00 GMT 2017", fmt);
ZonedDateTime mountain = gmt.withZoneSameLocal(ZoneId.of("US/Mountain"));
ZonedDateTime utc = mountain.withZoneSameInstant(ZoneOffset.UTC);
System.out.println(utc.format(fmt));
which, by the way, outputs: Wed Nov 01 06:00:00 Z 2017 (the DST will be in effect on November 3rd only).
Calendar c = Calendar.getInstance();
System.out.println(c.getTime());
c.set(2007, 0, 1);
System.out.println(c.getTime());
Output:
Tue Sep 12 12:36:24 IST 2017
Mon Jan 01 12:36:24 IST 2007
But, When I use the same code in a different environment, Output changes to below:
Output:
Tue Sep 12 12:36:24 IST 2017
Mon Jan 01 12:36:24 GMT 2007
FYI, I tried to print the timezone of the calendar instance, before and after setting the values and both are in "IST".
I want to know the root cause of this.
The second output in your question is the correct and expected behaviour on a JVM running Irish time (Europe/Dublin). On September 12, 2017 Ireland is on summer time (DST). While it is not clearly documented, Date.toString() (which you invoke implicitly when printing the Date you get from c.getTime()) prints the date and time in the JVM’s time zone, which in September is rendered as IST for Irish Summer Time.
When you set the date on the Calendar object also using Irish time, the hour of day is preserved; in your case you get Jan 01 2007 12:36:24 Irish standard time. Now imagine the confusion if both Irish Summer Time and Irish Standard Time were rendered as IST. You would not be able to distinguish. Instead, since Irish standard time coincides with GMT, this is what Date.toString() prints when the date is not in the summer time part of the year (which January isn’t).
My guess is that your first output is from a JVM running India time. It too is rendered as IST, and since India doesn’t use summer time, the same abbreviation is given summer and winter.
java.time
Before understanding the explanation for the behaviour you observed, I posted a comment about the outdated and the modern Java date and time classes. I still don’t think the comment is way off, though. This is the modern equivalent of your code:
ZonedDateTime zdt = ZonedDateTime.now(ZoneId.of("Europe/Dublin"));
System.out.println(zdt);
zdt = zdt.with(LocalDate.of(2007, Month.JANUARY, 1));
System.out.println(zdt);
It prints
2017-09-12T11:45:33.921+01:00[Europe/Dublin]
2007-01-01T11:45:33.921Z[Europe/Dublin]
If you want to use the JVM’s time zone setting, use ZoneId.systemDefault() instead of ZoneId.of("Europe/Dublin"). As the name states, contrary to Date, ZonedDateTime does include a time zone. It corresponds more to the old Calendar class. As you can see, its toString method prints the offset from UTC (Z meaning zero offset) and the time zone name in the unambiguous region/city format. I believe that this leaves a lot less room for confusion. If you want to print the date in a specific format, use a DateTimeFormatter.
Appendix: sample output from your code
For the sake of completeness, here are the outputs from your code when running different time zones that may be rendered as IST:
Europe/Dublin (agrees with your second output)
Tue Sep 12 11:19:28 IST 2017
Mon Jan 01 11:19:28 GMT 2007
Asia/Tel_Aviv
Tue Sep 12 13:19:28 IDT 2017
Mon Jan 01 13:19:28 IST 2007
Asia/Kolkata (agrees with your first output)
Tue Sep 12 15:49:28 IST 2017
Mon Jan 01 15:49:28 IST 2007
You need to set time zone and you will get desired result.
TimeZone.setDefault(TimeZone.getTimeZone("IST"));
Here is a working code.
import java.util.Calendar;
import java.util.TimeZone;
public class Cal {
public static void main(String[] args) {
// TODO Auto-generated method stub
TimeZone.setDefault(TimeZone.getTimeZone("IST")); // Add this before print
Calendar c = Calendar.getInstance();
System.out.println(c.getTime());
c.set(2007, 0, 1);
System.out.println(c.getTime());
}
}
As per Doc "Typically, you get a TimeZone using getDefault which creates a TimeZone based on the time zone where the program is running. For example, for a program running in Japan, getDefault creates a TimeZone object based on Japanese Standard Time."
SO when you running in different timezone it is using as default timezone. Hope you clear now. I attach doc. please read.
To talk about this interesting behaviour:
The source code from the Calendar class:
public final void set(int year, int month, int date)
{
set(YEAR, year);
set(MONTH, month);
set(DATE, date);
}
Which leads to the set method:
public void set(int field, int value)
{
// If the fields are partially normalized, calculate all the
// fields before changing any fields.
if (areFieldsSet && !areAllFieldsSet) {
computeFields();
}
internalSet(field, value);
isTimeSet = false;
areFieldsSet = false;
isSet[field] = true;
stamp[field] = nextStamp++;
if (nextStamp == Integer.MAX_VALUE) {
adjustStamp();
}
}
The interesting part here is the computeFields() method which has two implementation (one for Gregorian and one for Japenese calendar). These methods are quite complex but as far as I can see this is the only place where your Calendar instance may change time zone in your usecase.
Our server is running in netherlands but users uses the application in UK .
For UK 2017-03-26 02:30:00 is valid date-time but not in Netherlands.
I am using the code to convert the time by setting the timezone . But its not giving me right output.
String toDate ="2017-03-26 02:30:00";//Valid Time in UK
Date date = new Date();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// Use London's time zone to format the date in
df.setTimeZone(TimeZone.getTimeZone("London"));
System.out.println("Date and time in London: " + df.parse(toDate));
Output from Program : Date and time in London: Sun Mar 26 04:30:00 CEST 2017
Output Required : Date and time in London: Sun Mar 26 02:30:00 CEST 2017
Java version used : 1.7 . Can not use joda time for some dependency.
First a detail, TimeZone.getTimeZone() is dangerous, if it doesn’t recognize the ID string, it will tacitly give you GMT. Exactly in London this is so close to the correct you may get fooled for a while. TimeZone.getTimeZone("London") gives you UTC (or GMT). As Stefan Freitag pointed out, it has to be TimeZone.getTimeZone("Europe/London") for the correct British time zone.
Next a very common misunderstanding: A Date object does not have a time zone in it. It’s a point in time only. So how come it is printed as Sun Mar 26 04:30:00 CEST 2017, where CEST obviously refers to a time zone (Central European Summer Time, used in the Netherlands)? When printing the date, you are implicitly invoking Date.toString(). This methods unconditionally prints the time according the default time zone for the JVM. Therefore, setting the time zone for the DateFormat you used for parsing has no effect here. And therefore changing the JVM’s time zone setting, as Hugo did in a comment, works. The other way of getting correct output for British users is to format the Date back into a string using a DateFormat with British time zone.
If you use Hugo’s trick in the beginning, before creating the DateFormat, it too will have the British time zone, and you need not call df.setTimeZone() (but you may if you think it makes the code clearer, of course).
Look forward to using Java 8 or later some day. The new date and time classes in java.time generally don’t come with the surprises experienced with the old ones.
If i create a new Date() object. What will be the default timezone it will print.
I have my machine running in GMT. And i am creating a new Date() object. If i print why does it shows Thu Jul 05 08:21:05 PKT 2012. How does it takes the timezone as PKT ?
The date itself doesn't have any time zone. Its toString() method uses the current default time zone to return a String representing this date:
Date date = new Date();
System.out.println(TimeZone.getDefault());
System.out.println(date);
TimeZone.setDefault(TimeZone.getTimeZone("UTC"));
System.out.println(TimeZone.getDefault());
System.out.println(date);
Executing the above code on my machine leads to the following output:
sun.util.calendar.ZoneInfo[id="Europe/Paris",offset=3600000,dstSavings=3600000,useDaylight=true,transitions=184,lastRule=java.util.SimpleTimeZone[id=Europe/Paris,offset=3600000,dstSavings=3600000,useDaylight=true,startYear=0,startMode=2,startMonth=2,startDay=-1,startDayOfWeek=1,startTime=3600000,startTimeMode=2,endMode=2,endMonth=9,endDay=-1,endDayOfWeek=1,endTime=3600000,endTimeMode=2]]
Fri Jul 06 09:24:45 CEST 2012
sun.util.calendar.ZoneInfo[id="UTC",offset=0,dstSavings=0,useDaylight=false,transitions=0,lastRule=null]
Fri Jul 06 07:24:45 UTC 2012
Well actually basic date times usually are time zone agnostic, they don't store time zones. To make use of time zone you use formatters, calendars and the like. Of course the basic date has to be in a default time zone, whatever it might be (usually GMT), otherwise you wouldn't be able to create a local date from the basic date instance.
In you particular case it would help to look into a) the javadocs and b) into the class itself, since JDK is usually distributed with source code of java.util.Date. According to javadoc the java.util.Date class represents number of milliseconds since the standard base time known as "the epoch", namely 1 January 1970, 00:00:00 GMT.
If it shows a different date when printed on your machine, it is because your system will print it using time zone default for your system. You can however print it yourself using any other time zone.
If you are running under linux, there is some magic timezone file somewhere in the system. For my gentoo the magic was just creating a text file /etc/timezone with content
Europe/Berlin
The funny thing is that date gave the correct time and timezone (CEST) all the time, but java sent me to Greenwhich.
> date
Thu Sep 18 08:49:14 CEST 2014
I've just came upon a very strange behaviour of Java's Date class when I try to create two dates consequently:
Date startDate = new Date(1282863600000L);
System.out.println(startDate);
Date endDate = new Date(1321919999000L);
System.out.println(endDate);
The output is respectively:
Fri Aug 27 00:00:00 BST 2010
Mon Nov 21 23:59:59 GMT 2011
Has anyone seen something like that? Both date are initialized in an identical manner but when printed the first is shown in BST and the latter in GMT?
I tried to find explanation about that but I didn't. Can someone help me?
Thanks in advance!
This is documented behaviour.
From Date.toString():
Converts this Date object to a String of the form:
dow mon dd hh:mm:ss zzz yyyy
zzz is the time zone (and may reflect daylight saving time). Standard time zone abbreviations include those recognized by the method parse. If time zone information is not available, then zzz is empty - that is, it consists of no characters at all.
You are using a locale that uses British Summer Time and creating a date where a day-light-saving rule applies. This would be the expected form of the date at that time to a local user.
For me the output of this code is
Fri Aug 27 01:00:00 CEST 2010
Tue Nov 22 00:59:59 CET 2011
The exact result depends on the default locale Java is using on your system.
The difference is that CEST is the central european summer time, while CET is the central european time (i.e. not summer time).
You seem to be running in a british locale (en_GB or similar), so your output shows the British Summer Time and the Greenwich Mean Time respectively.
The first date you specify falls into the respective summer times and the second doesn't. So Java chooses the appropriate time zone for each locale/time combination.
After a lovely session of trying different long values I got this:
Date startDate1 = new Date(1284245999999L);
Date startDate2 = new Date(1284246000000L);
System.out.println(startDate1);
System.out.println(startDate2);
Date endDate = new Date(1321919999000L);
System.out.println(endDate);
The output was:
Sun Sep 12 01:59:59 IDT 2010
Sun Sep 12 01:00:00 IST 2010 <-- Long value is greater, but due to DST changes, actual time is one hour earlier
Tue Nov 22 01:59:59 IST 2011
Note that incrementing the long by 1 from 1284245999999L to 1284246000000L takes us "back in time" because of the transition from standard time to daylight savings time.
That is how Java time calculation behaves - the number of milliseconds since 1/1/1970 does not change, but the time it represents is based on the timezone.