I am trying to convert locale time to UTC, and then UTC to locale time. But I am not getting the result.
public class DateDemo
{
public static void main(String args[])
{
DateFormat dateFormatter =
DateFormat.getDateTimeInstance
(DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault());
TimeZone.setDefault(TimeZone.getDefault());
SimpleDateFormat simpleDateFormatter = new SimpleDateFormat("dd/MM/yyyy");
SimpleDateFormat simpleTimeFormatter = new SimpleDateFormat("hh:mm:ss a");
Date today = new Date();
String localeFormattedInTime = dateFormatter.format(today);
try
{
Date parsedDate = dateFormatter.parse(localeFormattedInTime);
System.out.println("Locale:" + localeFormattedInTime);
System.out.println("After parsing a date: " + parsedDate);
simpleDateFormatter.setTimeZone(TimeZone.getDefault());
simpleTimeFormatter.setTimeZone(TimeZone.getDefault());
String date = simpleDateFormatter.format(today);
String time = simpleTimeFormatter.format(today);
System.out.println("Today's only date: " + date);
System.out.println("Today's only time: " + time);
//// Locale to UTC converting
simpleDateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
simpleTimeFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
String utcDate = simpleDateFormatter.format(today);
String utcTime = simpleTimeFormatter.format(today);
System.out.println("Convert into UTC's date: " + utcDate);
System.out.println("Convert into UTC's only time: " + utcTime);
//// UTC to locale converting
simpleDateFormatter.setTimeZone(TimeZone.getDefault());
simpleTimeFormatter.setTimeZone(TimeZone.getDefault());
Date getDate = simpleDateFormatter.parse(utcDate);
Date getTime = simpleTimeFormatter.parse(utcTime);
String getLocalDate = simpleDateFormatter.format(getDate);
String getLocalTime = simpleTimeFormatter.format(getTime);
System.out.println("Get local date: " + getLocalDate);
System.out.println("Get local time: " + getLocalTime);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
I am sending local date & time to the web service, and then when require I need to retrieve the UTC date & time and then convert into locale date & time (i.e. user's local settings).
Sample Output:
Locale:11/9/12 8:15 PM
After parsing a date: Fri Nov 09 20:15:00 SGT 2012
Today's only date: 09/11/2012
Today's only time: 08:15:30 PM
Convert into UTC's date: 09/11/2012
Convert into UTC's only time: 12:15:30 PM
Get local date: 09/11/2012
Get local time: 12:15:30 PM
After Saksak & ADTC answers:
For the code fragment, UTC date & time (what is actually coming as GMT-5 because database may be in USA) is the input, and I want to get local date & time as output. But this following segment is still giving GMT-5 time.
SimpleDateFormat simpleDateTimeFormatter = new SimpleDateFormat("dd/MM/yyyy hh:mm:ss a");
....
Date inDateTime = simpleDateTimeFormatter.parse(intent.getExtras().getString("inTime")); Date outDateTime = simpleDateTimeFormatter.parse(intent.getExtras().getString("outTime"));
simpleDateTimeFormatter.setTimeZone(TimeZone.getDefault()); simpleDateTimeFormatter.setTimeZone(simpleDateTimeFormatter.getTimeZone());
//TimeZone tzTimeZone = TimeZone.getDefault();
//System.out.println("Current time zone: " + tzTimeZone.getDisplayName());
String getLocalInTimeString = simpleDateTimeFormatter.format(inDateTime);
String getLocalOutTimeString = simpleDateTimeFormatter.format(outDateTime);
My question: getLocalInTimeString & getLocalOutTimeString still showing GMT-5 timing. What's wrong here? Do I need to set any other things?
What you need to do to solve your problem is the following, you have your code to convert back to local time in this order :
simpleDateFormatter.setTimeZone(TimeZone.getDefault());
simpleTimeFormatter.setTimeZone(TimeZone.getDefault());
Date getDate = simpleDateFormatter.parse(utcDate);
Date getTime = simpleTimeFormatter.parse(utcTime);
and what you need to do is wait until you parse utcDate, utcTime Strings back to Date Object
then set the date formatter time zone to local zone as follows :
Date getDate = simpleDateFormatter.parse(utcDate);
Date getTime = simpleTimeFormatter.parse(utcTime);
simpleDateFormatter.setTimeZone(TimeZone.getDefault());
simpleTimeFormatter.setTimeZone(TimeZone.getDefault());
this should print the correct date/time in local.
Edit:
here is the full main method :
public static void main(String[] args) {
DateFormat dateFormatter = DateFormat.getDateTimeInstance(DateFormat.SHORT, DateFormat.SHORT, Locale.getDefault());
TimeZone.setDefault(TimeZone.getDefault());
SimpleDateFormat simpleDateFormatter = new SimpleDateFormat("dd/MM/yyyy");
SimpleDateFormat simpleTimeFormatter = new SimpleDateFormat("hh:mm:ss a");
Date today = new Date();
String localeFormattedInTime = dateFormatter.format(today);
try {
Date parsedDate = dateFormatter.parse(localeFormattedInTime);
System.out.println("Locale:" + localeFormattedInTime);
System.out.println("After parsing a date: " + parsedDate);
simpleDateFormatter.setTimeZone(TimeZone.getDefault());
simpleTimeFormatter.setTimeZone(TimeZone.getDefault());
String date = simpleDateFormatter.format(today);
String time = simpleTimeFormatter.format(today);
System.out.println("Today's only date: " + date);
System.out.println("Today's only time: " + time);
//// Locale to UTC converting
System.out.println("TimeZone.getDefault() >>> " + TimeZone.getDefault());
simpleDateFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
simpleTimeFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
String utcDate = simpleDateFormatter.format(today);
String utcTime = simpleTimeFormatter.format(today);
System.out.println("Convert into UTC's date: " + utcDate);
System.out.println("Convert into UTC's only time: " + utcTime);
//// UTC to locale converting
/**
** //////EDIT
*/
// at this point your utcDate,utcTime are strings that are formated in UTC
// so first you need to parse them back to Dates using UTC format not Locale
Date getDate = simpleDateFormatter.parse(utcDate);
Date getTime = simpleTimeFormatter.parse(utcTime);
// NOW after having the Dates you can change the formatters timezone to your
// local to format them into strings
simpleDateFormatter.setTimeZone(TimeZone.getDefault());
simpleTimeFormatter.setTimeZone(TimeZone.getDefault());
String getLocalDate = simpleDateFormatter.format(getDate);
String getLocalTime = simpleTimeFormatter.format(getTime);
System.out.println("Get local date: " + getLocalDate);
System.out.println("Get local time: " + getLocalTime);
} catch (ParseException e) {
e.printStackTrace();
}
}
Your problem is in lines 54 and 55:
Date getDate = simpleDateFormatter.parse(utcDate);
Date getTime = simpleTimeFormatter.parse(utcTime);
These lines are merely parsing Strings that contain the date and time, but these strings do not have any timezone information:
utcDate = "09/11/2012"
utcTime = "12:15:30 PM"
Therefore the parser assumes that the Strings are already in the locale of the timezone you set in lines 51 and 52.
Now think about how to fix it ;) HINT: Make sure the parser is assuming the correct timezone of the time represented by the strings.
PS: [RESOLVED!] I solved the problem but I discovered that the timezone conversion is erratic, for at least where I am. Time is 8:30 pm local. Convert to UTC, 12:30 pm (correct, 8 hr difference). Convert back, it's 8:00 pm (WRONG, eventhough the set timezone is correct - I got the original one and passed it back in - I'm only getting 7.5 hour difference). You should look for more reliable ways unless you can figure out what's going on and how to solve it.
[RESOLUTION:] The problem above was actually because the original code was splitting the date and time into two different parsers. If you use just one parser for both date and time combined you will get the correct date and time in the target locale. So in conclusion the parser is reliable but the way you use it makes a big difference!
SimpleDateFormat simpleDateTimeFormatter
= new SimpleDateFormat("dd/MM/yyyy hh:mm:ss a");
Date getDateTime
= simpleDateTimeFormatter.parse(utcDate + " " + utcTime);
//use above line if you have the date and time as separate strings
simpleDateTimeFormatter.setTimeZone(TimeZone.getDefault());
String getLocalDateTime = simpleDateTimeFormatter.format(getDateTime);
System.out.println("Get local date time: " + getLocalDateTime);
WHY USING TWO SEPARATE PARSERS FOR DATE AND TIME IS UNRELIABLE:
As explained above, it's a bad idea to use two separate parsers for date and time parts. Here's why:
Date getDate = simpleDateFormatter.parse(utcDate);
Date getTime = simpleTimeFormatter.parse(utcTime);
//Time zone changed to local here
String getLocalDate2 = simpleDateTimeFormatter.format(getDate);
String getLocalTime2 = simpleDateTimeFormatter.format(getTime);
System.out.println("Get local date2: " + getLocalDate2);
System.out.println("Get local time2: " + getLocalTime2);
OUTPUT:
Get local date2: 10/11/2012 08:00:00 AM
Get local time2: 01/01/1970 10:35:10 AM
I get the half hour difference because the default date 01/01/1970 is used in the Date variable storing time (second line). When this is converted to local timezone, the error happens as the formatter bases its conversion on the default date 01/01/1970 (where I live, the time difference was +7.5 hours in 1970 - today, it is +8 hours). This is why two separate parsers is not reliable even if you get the right result and you must always use a combined parser that accepts both date and time information.
Related
Can somebody find what is wrong with this code. I am trying to convert the Date Time value to Long using the Date and Time Stamp.These two always returns two different values for the same date time.
String date = "2016-01-08 06:23:13.0";
if(date.lastIndexOf('.') != -1)
{
date = date.substring(0,date.lastIndexOf('.'));
date = date+"+0000";
}
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");
Date myDate = fmt.parse(date);
System.out.println(myDate);
long timestamp = myDate.getTime();
System.out.println("The time stamp value is " + timestamp);
Timestamp tm = Timestamp.valueOf("2016-01-08 06:23:13.0");
System.out.println("The time stamp value using Timestamp is " + tm.getTime());
Your code with SimpleDateFormat parses the date assuming the zero digits specify the UTC timezone. Timestamp assumes local timezone.
You are adding a time zone specification to your first variant:
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");
^
If you ommitt this, and specify the same input values for both calculations, the result is the same.
...
String date = "2016-01-08 06:23:13";
SimpleDateFormat fmt = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
Date myDate = fmt.parse(date);
System.out.println(myDate);
long timestamp = myDate.getTime();
System.out.println("The time stamp value is " + timestamp);
Timestamp tm = Timestamp.valueOf(date);
long t2 = tm.getTime();
System.out.println("The time stamp value using Timestamp is " + t2 + " (diff: " + (t2 - timestamp) + ")");
...
Fri Jan 08 06:23:13 CET 2016
The time stamp value is 1452230593000
The time stamp value using Timestamp is 1452230593000 (diff: 0)
See #Joni's answer for an explaination:
With your explicit timezone specification of +0000 you specify UTC+0 as the time zone
Timestamp, on the other hand, assumes your local time zone which leads to a different value unless you live in UTC+0. (Actually it seems a bit more subtle: see Is java.sql.Timestamp timezone specific? for more information)
i have written this code to convert the current system date and time to some other timezone. I am not getting any error but i am not getting my output as expected. Like if i execute my program at a particular time.. My output is ::
The current time in India is :: Fri Feb 24 16:09:23 IST 2012
The date and time in :: Central Standard Time is :: Sat Feb 25 03:39:23 IST 2012
And the actual Time according to CST time zone is ::
Friday, 24 February 4:39:16 a.m(GMT - 6:00)
So there's some time gap. and i don't know why this is happening. Any help will be appreciated.. The code is ::
package MyPackage;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class Temp2 {
public static void main(String[] args) {
try {
Calendar currentdate = Calendar.getInstance();
String strdate = null;
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
strdate = formatter.format(currentdate.getTime());
TimeZone obj = TimeZone.getTimeZone("CST");
formatter.setTimeZone(obj);
//System.out.println(strdate);
//System.out.println(formatter.parse(strdate));
Date theResult = formatter.parse(strdate);
System.out.println("The current time in India is :: " +currentdate.getTime());
System.out.println("The date and time in :: "+ obj.getDisplayName() + "is ::" + theResult);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
It's over the web. Could have googled. Anyways, here is a version for you (shamelessly picked and modified from here):
Calendar calendar = Calendar.getInstance();
TimeZone fromTimeZone = calendar.getTimeZone();
TimeZone toTimeZone = TimeZone.getTimeZone("CST");
calendar.setTimeZone(fromTimeZone);
calendar.add(Calendar.MILLISECOND, fromTimeZone.getRawOffset() * -1);
if (fromTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, calendar.getTimeZone().getDSTSavings() * -1);
}
calendar.add(Calendar.MILLISECOND, toTimeZone.getRawOffset());
if (toTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, toTimeZone.getDSTSavings());
}
System.out.println(calendar.getTime());
Your mistake is to call parse instead of format.
You call parse to parse a Date from a String, but in your case you've got a Date and need to format it using the correct Timezone.
Replace your code with
Calendar currentdate = Calendar.getInstance();
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
TimeZone obj = TimeZone.getTimeZone("CST");
formatter.setTimeZone(obj);
System.out.println("Local:: " +currentdate.getTime());
System.out.println("CST:: "+ formatter.format(currentdate.getTime()));
and I hope you'll get the output you are expecting.
SimpleDateFormat#setTimezone() is the answer. One formatter with ETC timezone you use for parsing, another with UTC for producing output string:
DateFormat dfNy = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
dfNy.setTimeZone(TimeZone.getTimeZone("EST"));
DateFormat dfUtc = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
dfUtc.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
return dfUtc.format(dfNy.parse(input));
} catch (ParseException e) {
return null; // invalid input
}
Handling dates in Java in my daily work is a non-trivial task. I suggest you to use Joda-Time that simplify our coding days and you don't have to "re-invent the wheel".
You can use two SimpleDateFormat, one for parse the date string with EST timezone, one for print the date with UTC timezone
String format = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat estFormatter = new SimpleDateFormat(format);
estFormatter.setTimeZone(TimeZone.getTimeZone("EST"));
Date date = estFormatter.parse("2015-11-01 01:00:00");
SimpleDateFormat utcFormatter = new SimpleDateFormat(format);
utcFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(utcFormatter.format(date));
You can just use "CST6CDT"
because in some countries they follow CDT in summer and CST in winter
public static String getDateInCST() {
Calendar calendar = Calendar.getInstance();
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
formatter.setTimeZone(TimeZone.getTimeZone( "CST6CDT"));
String strdate = formatter.format(calendar.getTime());
TimeZone.getAvailableIDs();
return strdate;
}
Problem is when you print date obj it call toString method and it will print in your machines default time zone. Try this code and see difference.
Calendar currentdate = Calendar.getInstance();
String strdate = null;
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ssz");
strdate = formatter.format(currentdate.getTime());
System.out.println("strdate=>" + strdate);
TimeZone obj = TimeZone.getTimeZone("CST");
formatter.setTimeZone(obj);
strdate = formatter.format(currentdate.getTime());
Date theResult = formatter.parse(strdate);
System.out.println("The current time in India is :: " +currentdate.getTime());
System.out.println("The date and time in :: " + obj.getDisplayName() + "is ::" + theResult);
System.out.println("The date and time in :: " + obj.getDisplayName() + "is ::" + strdate);
First message, don’t handle your date and time as strings in your code. Just as you don’t handle numbers and Boolean values as strings (I hope). Use proper date-time objects.
java.time
Sometimes we get date and time as string input. It may be from a text file, from the user or from data exchange with another system, for example. In those cases parse into a proper date-time object first thing. Second message, use java.time, the modern Java date and time API, for your date and time work.
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
String input = "2015-11-01 01:00:00";
ZonedDateTime nyTime = LocalDateTime.parse(input, formatter)
.atZone(ZoneId.of("America/New_York"));
System.out.println("Time in New York: " + nyTime);
Output from this snippet is:
Time in New York: 2015-11-01T01:00-04:00[America/New_York]
To convert to GMT:
OffsetDateTime gmtTime = nyTime.toOffsetDateTime()
.withOffsetSameInstant(ZoneOffset.UTC);
System.out.println("GMT Time: " + gmtTime);
GMT Time: 2015-11-01T05:00Z
If you need to give string output, format using a date-time formatter. Here’s an example of formatting for an American audience:
DateTimeFormatter userFormatter
= DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
.withLocale(Locale.US);
String formattedDateTime = gmtTime.format(userFormatter);
System.out.println("GMT Time formatted for user: " + formattedDateTime);
GMT Time formatted for user: Nov 1, 2015, 5:00:00 AM
You additionally asked:
Between the two results below, which one should you take?
I understand that you ask because both are valid answers. On November 1, 2015 summer time (DST) ended at 2 AM. That is, after 01:59:59 came 01:00:00 a second time. So when we have got 2015-11-01 01:00:00 as input, it is ambiguous. It could be in Eastern Daylight Time, equal to 05:00 GMT, or it could be in Eastern Standard Time, one hour later, hence equal to 06:00 GMT. There is no way that I can tell you which of them is correct in your case. You may control which result you get using withEarlierOffsetAtOverlap() or withLaterOffsetAtOverlap(). Above we got the DST interpretation. So to get the standard time interpretation:
nyTime = nyTime.withLaterOffsetAtOverlap();
System.out.println("Alternate time in New York: " + nyTime);
Alternate time in New York: 2015-11-01T01:00-05:00[America/New_York]
We notice that the hour of day is still 01:00, but the offset is now -05:00 instead of -04:00. This also gives us a different GMT time:
GMT Time: 2015-11-01T06:00Z
GMT Time formatted for user: Nov 1, 2015, 6:00:00 AM
Avoid SimpleDateFormat and friends
While the other answers are generally correct, the classes DateFormat, SimpleDateFormat, Date and Calendar used there are poorly designed and long outdated. The first two are particularly troublesome. I recommend you avoid all of them. I frankly find the modern API so much nicer to work with.
Link
Oracle tutorial: Date Time explaining how to use java.time.
Please refer to below mentioned code.
DateFormat utcConverter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
utcConverter.setTimeZone(TimeZone.getTimeZone("GMT"));
String sampleDateTime = "2015-11-01 01:00:00";
DateFormat nyConverter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
nyConverter.setTimeZone(TimeZone.getTimeZone("EST"));
Calendar nyCal = Calendar.getInstance();
nyCal.setTime(nyConverter.parse(sampleDateTime));
System.out.println("NY TIME :" +nyConverter.format(nyCal.getTime()));
System.out.println("GMT TIME :" +utcConverter.format(nyCal.getTime()));
2020 Answer Here
If you want the new java.time.* feature but still want to mess with java.util.Date:
public static Date convertBetweenTwoTimeZone(Date date, String fromTimeZone, String toTimeZone) {
ZoneId fromTimeZoneId = ZoneId.of(fromTimeZone);
ZoneId toTimeZoneId = ZoneId.of(toTimeZone);
ZonedDateTime fromZonedDateTime =
ZonedDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()).withZoneSameLocal(fromTimeZoneId);
ZonedDateTime toZonedDateTime = fromZonedDateTime
.withZoneSameInstant(toTimeZoneId)
.withZoneSameLocal(ZoneId.systemDefault())
;
return Date.from(toZonedDateTime.toInstant());
}
for java.sql.Timestamp
public static Timestamp convertBetweenTwoTimeZone(Timestamp timestamp, String fromTimeZone, String toTimeZone) {
ZoneId fromTimeZoneId = ZoneId.of(fromTimeZone);
ZoneId toTimeZoneId = ZoneId.of(toTimeZone);
LocalDateTime localDateTimeBeforeDST = timestamp.toLocalDateTime();
ZonedDateTime fromZonedDateTime = ZonedDateTime.of(localDateTimeBeforeDST, fromTimeZoneId);
ZonedDateTime toZonedDateTime = fromZonedDateTime.withZoneSameInstant(toTimeZoneId);
return Timestamp.valueOf(toZonedDateTime.toLocalDateTime());
}
For google calendar API
private String getFormatedDate(Date date)
{
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+05:30");
df.setTimeZone(TimeZone.getTimeZone("GMT+05:30"));
return df.format(date);
}
I have a String with timestamp in GMT. I want to convert this to a DateTime object in EST.
E.g If the string has:
final String gmtTime = "20140917-18:55:25"; // 4:55 PM GMT
I need to convert this to : 20140917-12:55:25 //12:55 PM EST
All these tries failed:
System.out.println("Time in GMT " + DateTimeFormat.forPattern("yyyyMMdd-HH:mm:ss").parseDateTime(gmtTime));
System.out.println("Time in EST " +
DateTimeFormat.forPattern("yyyyMMdd-HH:mm:ss").parseDateTime(gmtTime).withZone(DateTimeZone.forID("America/New_York")));
Output:
Time in GMT 2014-09-17T18:55:25.000-04:00
Time in EST 2014-09-17T18:55:25.000-04:00 //I expect: 2014-09-17T12:55:25.000-04:00
Any suggestions?
Joda-Time
Here a Joda-Time 2.4 solution:
String gmtTime = "20140917-18:55:25";
DateTime dateTimeGMT =
DateTimeFormat.forPattern("yyyyMMdd-HH:mm:ss").withZoneUTC().parseDateTime(gmtTime);
System.out.println("Time in GMT " + dateTimeGMT); // Time in GMT 2014-09-17T18:55:25.000Z
System.out.println(
"Time in EST "
+ DateTimeFormat.forPattern("yyyyMMdd-HH:mm:ss").withZone(
DateTimeZone.forID("America/New_York")
).print(dateTimeGMT)
); //Time in EST 20140917-14:55:25
I think that you have the wrong expectation regarding the result. EST (more correct to use is "America/New_York" as zone identifier) is four hours behind UTC, hence the local timestamp there is four hours earlier than the local representation of the same moment at UTC-offset.
Also note that I set the timezone on the formatter not on the parsed DateTime-object.
#Test
public void TimeZoneTest() {
Date now = new Date();
String DATE_PATTERN = "yyyyMMdd-HH:mm:ss";
DateFormat dfEST = new SimpleDateFormat(DATE_PATTERN);
dfEST.setTimeZone(TimeZone.getTimeZone("America/New_York"));
DateFormat dfGMT = new SimpleDateFormat(DATE_PATTERN);
dfGMT.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println(dfEST.format(now));
System.out.println(dfGMT.format(now));
}
And the output is:
20140919-09:02:19
20140919-13:02:19
I have a Java Date object containing date and time information, e.g.2010-11-11T09:30:47. I want to write a method that will convert this Date object to the following format.
"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'
I wrote the following code.
private Calender getValue(Date dateObject) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
String timestamp = formatter.format(dateObject);
System.out.println("Created GMT cal with date [" + timestamp + "]");
}
When I run the program, it is printing
Created GMT cal with date [2010-11-11T04:00:47.000Z]
What I gave is "2010-11-11T09:30:47", My time is 09:30:47. What it is printing is "04:00:47".
Why the time is changing 9.30 to 4.00.?
What do I need to do to get the same time as I give. Like 2010-11-11T09:30:47.000Z
Thanks a lot.
You just need to remove the following line
formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
Because you are setting the Timezone to be GMT, whereas your timezone is GMT + 5.30. That is the reason when you set the time to 9.30, you will get 9.30 - 5.30 = 4.00.
You can just use the following code:
private void getValue(Date dateObject)
{
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
String timestamp = formatter.format(dateObject);
System.out.println("Created GMT cal with date [" + timestamp + "]");
}
Your date probably has the time 09:30:47 in your time zone. But you configured the date format to the GMT time zone. So it's displaying the time as it is in the GMT time zone.
If you used another date format to parse the input string and get a Date object, make sure this oter date format also uses the GMT time zone.
To get more help, show us how you create the Date object passed to your method.
Remove formatter.setTimeZone(TimeZone.getTimeZone("GMT"));
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'");
String timestamp = formatter.format(new Date());
System.out.println("Created GMT cal with date [" + timestamp + "]");
i have written this code to convert the current system date and time to some other timezone. I am not getting any error but i am not getting my output as expected. Like if i execute my program at a particular time.. My output is ::
The current time in India is :: Fri Feb 24 16:09:23 IST 2012
The date and time in :: Central Standard Time is :: Sat Feb 25 03:39:23 IST 2012
And the actual Time according to CST time zone is ::
Friday, 24 February 4:39:16 a.m(GMT - 6:00)
So there's some time gap. and i don't know why this is happening. Any help will be appreciated.. The code is ::
package MyPackage;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class Temp2 {
public static void main(String[] args) {
try {
Calendar currentdate = Calendar.getInstance();
String strdate = null;
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
strdate = formatter.format(currentdate.getTime());
TimeZone obj = TimeZone.getTimeZone("CST");
formatter.setTimeZone(obj);
//System.out.println(strdate);
//System.out.println(formatter.parse(strdate));
Date theResult = formatter.parse(strdate);
System.out.println("The current time in India is :: " +currentdate.getTime());
System.out.println("The date and time in :: "+ obj.getDisplayName() + "is ::" + theResult);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
It's over the web. Could have googled. Anyways, here is a version for you (shamelessly picked and modified from here):
Calendar calendar = Calendar.getInstance();
TimeZone fromTimeZone = calendar.getTimeZone();
TimeZone toTimeZone = TimeZone.getTimeZone("CST");
calendar.setTimeZone(fromTimeZone);
calendar.add(Calendar.MILLISECOND, fromTimeZone.getRawOffset() * -1);
if (fromTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, calendar.getTimeZone().getDSTSavings() * -1);
}
calendar.add(Calendar.MILLISECOND, toTimeZone.getRawOffset());
if (toTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, toTimeZone.getDSTSavings());
}
System.out.println(calendar.getTime());
Your mistake is to call parse instead of format.
You call parse to parse a Date from a String, but in your case you've got a Date and need to format it using the correct Timezone.
Replace your code with
Calendar currentdate = Calendar.getInstance();
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ss");
TimeZone obj = TimeZone.getTimeZone("CST");
formatter.setTimeZone(obj);
System.out.println("Local:: " +currentdate.getTime());
System.out.println("CST:: "+ formatter.format(currentdate.getTime()));
and I hope you'll get the output you are expecting.
SimpleDateFormat#setTimezone() is the answer. One formatter with ETC timezone you use for parsing, another with UTC for producing output string:
DateFormat dfNy = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
dfNy.setTimeZone(TimeZone.getTimeZone("EST"));
DateFormat dfUtc = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.ROOT);
dfUtc.setTimeZone(TimeZone.getTimeZone("UTC"));
try {
return dfUtc.format(dfNy.parse(input));
} catch (ParseException e) {
return null; // invalid input
}
Handling dates in Java in my daily work is a non-trivial task. I suggest you to use Joda-Time that simplify our coding days and you don't have to "re-invent the wheel".
You can use two SimpleDateFormat, one for parse the date string with EST timezone, one for print the date with UTC timezone
String format = "yyyy-MM-dd HH:mm:ss";
SimpleDateFormat estFormatter = new SimpleDateFormat(format);
estFormatter.setTimeZone(TimeZone.getTimeZone("EST"));
Date date = estFormatter.parse("2015-11-01 01:00:00");
SimpleDateFormat utcFormatter = new SimpleDateFormat(format);
utcFormatter.setTimeZone(TimeZone.getTimeZone("UTC"));
System.out.println(utcFormatter.format(date));
You can just use "CST6CDT"
because in some countries they follow CDT in summer and CST in winter
public static String getDateInCST() {
Calendar calendar = Calendar.getInstance();
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS");
formatter.setTimeZone(TimeZone.getTimeZone( "CST6CDT"));
String strdate = formatter.format(calendar.getTime());
TimeZone.getAvailableIDs();
return strdate;
}
Problem is when you print date obj it call toString method and it will print in your machines default time zone. Try this code and see difference.
Calendar currentdate = Calendar.getInstance();
String strdate = null;
DateFormat formatter = new SimpleDateFormat("dd-MM-yyyy HH:mm:ssz");
strdate = formatter.format(currentdate.getTime());
System.out.println("strdate=>" + strdate);
TimeZone obj = TimeZone.getTimeZone("CST");
formatter.setTimeZone(obj);
strdate = formatter.format(currentdate.getTime());
Date theResult = formatter.parse(strdate);
System.out.println("The current time in India is :: " +currentdate.getTime());
System.out.println("The date and time in :: " + obj.getDisplayName() + "is ::" + theResult);
System.out.println("The date and time in :: " + obj.getDisplayName() + "is ::" + strdate);
First message, don’t handle your date and time as strings in your code. Just as you don’t handle numbers and Boolean values as strings (I hope). Use proper date-time objects.
java.time
Sometimes we get date and time as string input. It may be from a text file, from the user or from data exchange with another system, for example. In those cases parse into a proper date-time object first thing. Second message, use java.time, the modern Java date and time API, for your date and time work.
DateTimeFormatter formatter
= DateTimeFormatter.ofPattern("uuuu-MM-dd HH:mm:ss");
String input = "2015-11-01 01:00:00";
ZonedDateTime nyTime = LocalDateTime.parse(input, formatter)
.atZone(ZoneId.of("America/New_York"));
System.out.println("Time in New York: " + nyTime);
Output from this snippet is:
Time in New York: 2015-11-01T01:00-04:00[America/New_York]
To convert to GMT:
OffsetDateTime gmtTime = nyTime.toOffsetDateTime()
.withOffsetSameInstant(ZoneOffset.UTC);
System.out.println("GMT Time: " + gmtTime);
GMT Time: 2015-11-01T05:00Z
If you need to give string output, format using a date-time formatter. Here’s an example of formatting for an American audience:
DateTimeFormatter userFormatter
= DateTimeFormatter.ofLocalizedDateTime(FormatStyle.MEDIUM)
.withLocale(Locale.US);
String formattedDateTime = gmtTime.format(userFormatter);
System.out.println("GMT Time formatted for user: " + formattedDateTime);
GMT Time formatted for user: Nov 1, 2015, 5:00:00 AM
You additionally asked:
Between the two results below, which one should you take?
I understand that you ask because both are valid answers. On November 1, 2015 summer time (DST) ended at 2 AM. That is, after 01:59:59 came 01:00:00 a second time. So when we have got 2015-11-01 01:00:00 as input, it is ambiguous. It could be in Eastern Daylight Time, equal to 05:00 GMT, or it could be in Eastern Standard Time, one hour later, hence equal to 06:00 GMT. There is no way that I can tell you which of them is correct in your case. You may control which result you get using withEarlierOffsetAtOverlap() or withLaterOffsetAtOverlap(). Above we got the DST interpretation. So to get the standard time interpretation:
nyTime = nyTime.withLaterOffsetAtOverlap();
System.out.println("Alternate time in New York: " + nyTime);
Alternate time in New York: 2015-11-01T01:00-05:00[America/New_York]
We notice that the hour of day is still 01:00, but the offset is now -05:00 instead of -04:00. This also gives us a different GMT time:
GMT Time: 2015-11-01T06:00Z
GMT Time formatted for user: Nov 1, 2015, 6:00:00 AM
Avoid SimpleDateFormat and friends
While the other answers are generally correct, the classes DateFormat, SimpleDateFormat, Date and Calendar used there are poorly designed and long outdated. The first two are particularly troublesome. I recommend you avoid all of them. I frankly find the modern API so much nicer to work with.
Link
Oracle tutorial: Date Time explaining how to use java.time.
Please refer to below mentioned code.
DateFormat utcConverter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
utcConverter.setTimeZone(TimeZone.getTimeZone("GMT"));
String sampleDateTime = "2015-11-01 01:00:00";
DateFormat nyConverter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
nyConverter.setTimeZone(TimeZone.getTimeZone("EST"));
Calendar nyCal = Calendar.getInstance();
nyCal.setTime(nyConverter.parse(sampleDateTime));
System.out.println("NY TIME :" +nyConverter.format(nyCal.getTime()));
System.out.println("GMT TIME :" +utcConverter.format(nyCal.getTime()));
2020 Answer Here
If you want the new java.time.* feature but still want to mess with java.util.Date:
public static Date convertBetweenTwoTimeZone(Date date, String fromTimeZone, String toTimeZone) {
ZoneId fromTimeZoneId = ZoneId.of(fromTimeZone);
ZoneId toTimeZoneId = ZoneId.of(toTimeZone);
ZonedDateTime fromZonedDateTime =
ZonedDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault()).withZoneSameLocal(fromTimeZoneId);
ZonedDateTime toZonedDateTime = fromZonedDateTime
.withZoneSameInstant(toTimeZoneId)
.withZoneSameLocal(ZoneId.systemDefault())
;
return Date.from(toZonedDateTime.toInstant());
}
for java.sql.Timestamp
public static Timestamp convertBetweenTwoTimeZone(Timestamp timestamp, String fromTimeZone, String toTimeZone) {
ZoneId fromTimeZoneId = ZoneId.of(fromTimeZone);
ZoneId toTimeZoneId = ZoneId.of(toTimeZone);
LocalDateTime localDateTimeBeforeDST = timestamp.toLocalDateTime();
ZonedDateTime fromZonedDateTime = ZonedDateTime.of(localDateTimeBeforeDST, fromTimeZoneId);
ZonedDateTime toZonedDateTime = fromZonedDateTime.withZoneSameInstant(toTimeZoneId);
return Timestamp.valueOf(toZonedDateTime.toLocalDateTime());
}
For google calendar API
private String getFormatedDate(Date date)
{
DateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss+05:30");
df.setTimeZone(TimeZone.getTimeZone("GMT+05:30"));
return df.format(date);
}