How to convert any TimeZone dateTime to UTC Date in JAVA [duplicate] - java

This question already has answers here:
TimeZone problem in Java
(3 answers)
GregorianCalendar Class in Java
(3 answers)
Calendar returns date in wrong time zone
(5 answers)
Closed 2 years ago.
I have to use the date time which I receive by user, and convert that time to UTC from the given time. Right now, all the solutions are working, but not as I needed. First, it converts to the time zone, but I don't want to initially convert. I have to set that timezone on my date and then convert that time to UTC. Right now, each and every solution shows that I have to pass date and time, and then I am getting updated date and time with the time zone which I provide, and then converts to the UTC. This was not my question.
My user will send me date time of any timezone, and my server will be running on UTC time zone. I will get the zone id from the front end. I want to convert that date time to UTC and verify with my other conditions. It might be possible that I will get UTC-7 time in one request, and then after in next request I will get UTC+5:30. So, all the time should be converted to the UTC and I am not able to set timezone on date.
I wanted to set the specific timezone to date, and I am getting the date and time of that timezone, but I'm not able to set the exact timezone. Here, I am adding my code please tell me where I am wrong:
Calendar laCalendar = Calendar.getInstance();
laCalendar.set(2020, 8, 14, 00, 00);
Date losAngelesDate = laCalendar.getTime();
System.out.println("LA Date1===>" + losAngelesDate);
SimpleDateFormat simpleTimeFormatForUSA = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
simpleTimeFormatForUSA.setTimeZone(TimeZone.getTimeZone("America/Los_Angeles"));
String americaDateString = simpleTimeFormatForUSA.format(laCalendar.getTime());
SimpleDateFormat dateFormatUSA = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
losAngelesDate = dateFormatUSA.parse(americaDateString);
System.out.println("LA Date2===>" + losAngelesDate);
Date utcDate = losAngelesDate;
Calendar calendar = Calendar.getInstance();
calendar.setTime(utcDate);
TimeZone timeZone = TimeZone.getTimeZone("UTC");
SimpleDateFormat simpleTimeFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
simpleTimeFormat.setTimeZone(timeZone);
String utcTime = simpleTimeFormat.format(calendar.getTime());
SimpleDateFormat dateFormat = new SimpleDateFormat("MM/dd/yyyy hh:mm a");
utcDate = dateFormat.parse(utcTime);
System.out.println("UTC date====>" + utcDate);
And my output is
LA Date1===>Mon Sep 14 00:00:56 UTC 2020
LA Date2===>Sun Sep 13 17:00:00 UTC 2020
UTC date====>Sun Sep 13 17:00:00 UTC 2020
Here you can see that my DateTime is converted, but time zone is still UTC and I wanted to update that.

Here, is how I would write it using Java 8 Date/Time APIs.
public static void main(String[] args)
{
System.out.println("UTC");
toTimeZone(new Date(), TimeZone.getTimeZone(ZoneId.of("UTC")));
System.out.println("America/Los_Angeles");
toTimeZone(new Date(), TimeZone.getTimeZone(ZoneId.of("America/Los_Angeles")));
}
public static void toTimeZone(Date date, TimeZone timeZone)
{
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
Instant epochMillisInstant = Instant.ofEpochMilli(calendar.getTimeInMillis());
LocalDateTime localDateTime = LocalDateTime.ofInstant(epochMillisInstant, ZoneId.systemDefault());
ZonedDateTime dateTimeToConvert = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
ZonedDateTime dateTimeWithTimeZone = dateTimeToConvert.withZoneSameInstant(timeZone.toZoneId());
String formattedDateForNewTimeZone = dateTimeWithTimeZone.format(DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a"));
System.out.println(formattedDateForNewTimeZone);
}
Using Just Java 8 Date/Time APIs - Shorter Version
public static void main(String[] args) {
System.out.println("UTC");
toTimeZone(LocalDateTime.now(),"UTC");
System.out.println("America/Los_Angeles");
toTimeZone(LocalDateTime.now(),"America/Los_Angeles");
}
private static void toTimeZone(LocalDateTime localDateTime, String timeZone) {
ZonedDateTime localDateTimeToConvert = ZonedDateTime.of(localDateTime, ZoneId.systemDefault());
ZonedDateTime zonedDateTime = localDateTimeToConvert.withZoneSameInstant(ZoneId.of(timeZone));
String formattedDateForNewTimeZone = zonedDateTime.format(DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a"));
System.out.println(formattedDateForNewTimeZone);
}

Before you convert the Calendar to a Date, set the Timezone to your preference.
For example:
import java.util.Calendar;
import java.util.TimeZone;
public class Timezone{
public static void main(String []args){
Calendar laCalendar = Calendar.getInstance();
TimeZone timezone = TimeZone.getTimeZone("UTC");
laCalendar.set(2020, 8, 14, 00, 00);
laCalendar.setTimeZone(timezone);
java.util.Date losAngelesDate = laCalendar.getTime();
System.out.println(losAngelesDate.toString());
}
}

Related

Local to GMT and vice versa- Date and time conversion not working

I was trying to convert input date time to GMT+0 , later convert that back to its local time. Though local to GMT+0 conversion works, the later conversion-gmt to local fails!
Calendar cal=Calendar.getInstance();
cal.setTime(new Date());
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
System.out.println("my inputTime:"+ sdf.format(cal.getTime()));
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("gmt+0 converted time:"+ sdf.format(cal.getTime()));
//now i want to get my local time from this converted gmt+0 standard time
String standdardTimeStr=sdf.format(cal.getTime());
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
Date date=sdf2.parse(standdardTimeStr);
Calendar cal2= Calendar.getInstance();
cal2.setTime(date);
System.out.println("standard input time:"+ sdf2.format(cal2.getTime()));
sdf2.setTimeZone(TimeZone.getTimeZone("GMT+6")); //or Asia/Dhaka
System.out.println("gmt+6 convertedtime:"+ sdf2.format(cal2.getTime()));
And this is my output:
my inputTime:2020-07-13T15:02:16.849
gmt+0 converted time:2020-07-13T09:02:16.849
standard input time:2020-07-13T09:02:16.849 //taking upper line as input-gmt+0
gmt+6 convertedtime:2020-07-13T09:02:16.849 //this date was supposed to be same as the first date
Please point out what am I doing wrong in coding or conceptually?
Just for the case you want a solution with a modern API, see this commented example:
public static void main(String[] args) {
// provide some fix example datetime String
String dateTime = "2020-05-08T13:57:06.345";
// create the two time zones needed before
ZoneId utc = ZoneId.of("UTC"); // UTC = GMT (+0)
ZoneId local = ZoneId.systemDefault(); // the zone of your JVM / system
/*
* then parse the String which doesn't contain information about a zone
* to an object that just knows date and time
*/
LocalDateTime ldt = LocalDateTime.parse(dateTime);
// and use that to create a zone-aware object with the same date and time
ZonedDateTime utcZdt = ZonedDateTime.of(ldt, utc);
// finally adjust its date and time by changing the zone
ZonedDateTime localZdt = utcZdt.withZoneSameInstant(local);
// then print both results
System.out.println(utcZdt + "\t==\t" + localZdt);
// and maybe try to use a different output format by defining a custom formatter
DateTimeFormatter gmtStyleDtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSO");
System.out.println(utcZdt.format(gmtStyleDtf)
+ "\t==\t" + localZdt.format(gmtStyleDtf));
}
which ouputs the following lines on my system (might be different on yours due to different time zones):
2020-05-08T13:57:06.345Z[UTC] == 2020-05-08T15:57:06.345+02:00[Europe/Berlin]
2020-05-08T13:57:06.345GMT == 2020-05-08T15:57:06.345GMT+2
EDIT:
Here's a possibility of doing the same thing but just dealing with offsets instead of time zones:
public static void main(String[] args) {
// provide some fix example datetime String
String dateTime = "2020-05-08T13:57:06.345";
// create the two offsets needed
ZoneOffset gmt = ZoneOffset.ofHours(0); // UTC = GMT (+0)
ZoneOffset gmtPlusSix = ZoneOffset.ofHours(6); // Asia/Dhaka ;-)
/*
* then parse the String which doesn't contain information about a zone
* to an object that just knows date and time
* NOTE: this just parses the String and does nothing else
*/
LocalDateTime justDateAndTime = LocalDateTime.parse(dateTime);
// and use that to create an offset-aware object with the same date and time
OffsetDateTime dateAndTimeAndGmtPlusSix = OffsetDateTime.of(justDateAndTime, gmtPlusSix);
// finally adjust its date and time by changing the offset keeping the instant
OffsetDateTime dateAndTimeInGmt = dateAndTimeAndGmtPlusSix.withOffsetSameInstant(gmt);
// then print both results
System.out.println(dateAndTimeAndGmtPlusSix + "\t==\t" + dateAndTimeInGmt);
// and maybe try to use a different output format by defining a custom formatter
DateTimeFormatter gmtStyleDtf = DateTimeFormatter.ofPattern("uuuu-MM-dd'T'HH:mm:ss.SSSO");
System.out.println(dateAndTimeAndGmtPlusSix.format(gmtStyleDtf)
+ "\t==\t" + dateAndTimeInGmt.format(gmtStyleDtf));
}
Output:
2020-05-08T13:57:06.345+06:00 == 2020-05-08T07:57:06.345Z
2020-05-08T13:57:06.345GMT+6 == 2020-05-08T07:57:06.345GMT
Note that a Z is equivalent to an offset of GMT/UTC +0.
This way, you could create a method like
public static String convert(String datetime, int fromOffset, int toOffset) {
ZoneOffset fromZoneOffset = ZoneOffset.ofHours(fromOffset);
ZoneOffset toZoneOffset = ZoneOffset.ofHours(toOffset);
OffsetDateTime odt = LocalDateTime.parse(datetime).atOffset(fromZoneOffset);
return odt.withOffsetSameInstant(toZoneOffset)
.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME);
}
maybe handle invalid argument values, use it like this
public static void main(String[] args) {
String dateTime = "2020-05-08T13:57:06.345";
System.out.println(convert(dateTime, 6, 0)));
}
and receive the output
2020-05-08T07:57:06.345
I don't know why you're using a Calendar object. Javadoc of Calendar.getInstance() says:
The Calendar returned is based on the current time in the default time zone
Which means that calling cal.setTime(new Date()); is entirely redundant.
But, even worse than that, the following three are all the same:
// The very long way
Calendar cal = Calendar.getInstance();
cal.setTime(new Date());
Date date = cal.getTime();
// The long way
Calendar cal = Calendar.getInstance();
Date date = cal.getTime();
// The simple way
Date date = new Date();
A Date object always stores the date/time in UTC (GMT+0). Time zones are applied when a string is parsed, and when a string is formatted.
Parsing a string that doesn't specify a time zone offset will be parsed in the time zone of the SimpleDateFormat, which is the default time zone (aka the "local" time zone) unless otherwise specified, and the parsed value is converted to UTC for storage in a Date object.
Formatting a Date value to string will always use the time zone of the SimpleDateFormat.
Cleaning up the code in the question to not use Calendar, since that just obfuscates the issue, and commenting it to show what is going on, will answer your question of "point out what am I doing wrong in coding or conceptually":
Date now = new Date();
// Format the date in the local time zone
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
System.out.println("my inputTime:"+ sdf.format(now));
// Format the date in GMT time zone
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
System.out.println("gmt+0 converted time:"+ sdf.format(now));
// Format the date in GMT time zone (again), since the time ** ERROR MIGHT **
// zone of the formatter is still set to GMT ** BE HERE **
String standdardTimeStr = sdf.format(now);
// Parse the GMT date string as-if it is in local time zone ** OR MAYBE HERE **
SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS");
Date date = sdf2.parse(standdardTimeStr); // Date value here is wrong
// Format the bad date value back to string in the same time
// zone, which means you get GMT time back, even though that
// is not the value of the `date` variable
System.out.println("standard input time:"+ sdf2.format(date));
// Do it again, same result, because the time zone is changed ** ERROR HERE **
// on the wrong formatter object
sdf.setTimeZone(TimeZone.getTimeZone("GMT+6")); //or Asia/Dhaka
System.out.println("gmt+6 convertedtime:"+ sdf2.format(date));
You are missing to take the string representation of time to convert it back to local. The modified code below will give an idea on the same:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.TimeZone;
public class TimeZoneExample {
public static void main(String[] args) throws ParseException {
Calendar cal = Calendar.getInstance();
final Date currentTime = cal.getTime();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS Z");
String timeInCurrentTimeZone = sdf.format(currentTime);
System.out.println("Time in current time zone: " + timeInCurrentTimeZone);
sdf.setTimeZone(TimeZone.getTimeZone("GMT"));
String timeInGMT = sdf.format(currentTime);
System.out.println("Time in GMT: " + timeInGMT);
// Now, take this time in GMT and parse the string -- this is the key, we want to work with the time which got
// displayed not the internal representation and that's why we will get the time from string!
Date parsedTime = sdf.parse(timeInGMT);
String parsedString = sdf.format(parsedTime);
System.out.println("(GMT) Time in Parsed String: " + parsedString); // here it will show up it in GMT as sdf is still set to GMT
// Change the zone for sdf
sdf.setTimeZone(TimeZone.getTimeZone("GMT+6")); // or Asia/Dhaka
System.out.println("(Local) Time in Parsed String: " + sdf.format(parsedTime)); // here it you will see the zone difference
}
}
Note: You will get better picture if you take fixed time instead of current time.

How to set String (HH:mm) to UTC time with current date and convert it to local time

I need to convert a string that is in (HH:mm) format which is supposed to be in UTC time to the local TimeZone. How to add the present date to the string and convert it local time.
I have tried using the calendar
String utcTimeString = "06:00";
SimpleDateFormat sdf = new SimpleDateFormat("HH:mm", Locale.getDefault());
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
Calendar now = Calendar.getInstance(Locale.getDefault());
now.setTime(sdf.parse(utcTimeString));
You are well advised to use the modern API for dates, times, time zones, offsets, calendars and more:
java.time
Doing so, it is pretty easy to
parse the time you receive
get the current date and
combine them to a date-time representation with a certain time zone
See this little example:
public static void main(String[] args) {
// create a time object from the String
LocalTime localTime = LocalTime.parse("06:00", DateTimeFormatter.ofPattern("HH:mm"));
// print it once in an ISO format
System.out.println(localTime.format(DateTimeFormatter.ISO_TIME));
// receive the date of today
LocalDate today = LocalDate.now();
// then use the date and the time object to create a zone-aware datetime object
ZonedDateTime zdt = LocalDateTime.of(today, localTime).atZone(ZoneId.of("UTC"));
// print it
System.out.println(zdt.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));
}
The output is
06:00:00
2019-11-04T06:00:00Z[UTC]
Which you can format as desired using different DateTimeFormatters.
Try like the following.
public String getDateTimeInUTC(String yourTime){
Calendar cal = Calendar.getInstance();
SimpleDateFormat currentDate= new SimpleDateFormat("MMM dd, yyyy ");
String currentDateTime = currentDate.format(cal.getTime())+yourTime; // here concate your time with current date.
System.out.println("Current date with given time: "+currentDateTime);
SimpleDateFormat df = new SimpleDateFormat("MMM dd, yyyy HH:mm", Locale.ENGLISH);
df.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = null;
try {
date = df.parse(currentDateTime);
} catch (ParseException e) {
e.printStackTrace();
}
df.setTimeZone(TimeZone.getDefault());
String formattedDate = df.format(date);
return formattedDate;
}
Call getDateTimeInUTC like below
String strTime = "12:10"; // your string time in HH:mm format
String finalDateTime = getDateTimeInUTC(strTime);
System.out.println("Final date-time in UTC: "+finalDateTime);
OUTPUT:
Current date with given time: Nov 04, 2019 12:10
Final date-time in UTC: Nov 04, 2019 18:10
You can Check this Out :
Calendar calendar = Calendar.getInstance();
calendar.setTime(new Date());
//change the format according to your need
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
//Here you say to java the initial timezone. This is the secret
sdf.setTimeZone(TimeZone.getTimeZone("UTC"));
//Will print in UTC
System.out.println(sdf.format(calendar.getTime()));
//Here you set to your timezone
sdf.setTimeZone(TimeZone.getDefault());
//Will print on your default Timezone
System.out.println(sdf.format(calendar.getTime()));

How do I convert date/time from one timezone to another? [duplicate]

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);
}

How to convert date object to ones own timezone in android?

In android, I download date information from a MySQL database on a free web server, then convert it to a Date object using:
Note: the server time is 5 hours ahead of toronto.
public static Date getDateFromSQLDate(String sqldate) {
try {
DateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault());
Date date = (Date) formatter.parse(sqldate);
TimeZone targetTimeZone = TimeZone.getDefault();
TimeZone serverTimeZone = TimeZone.getTimeZone("Europe/London");
Calendar calendar = Calendar.getInstance();
calendar.setTime(date);
calendar.setTimeZone(serverTimeZone);
calendar.add(Calendar.MILLISECOND, serverTimeZone.getRawOffset() * -1);
if (serverTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, calendar.getTimeZone().getDSTSavings() * -1);
}
calendar.add(Calendar.MILLISECOND, targetTimeZone.getRawOffset());
if (targetTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, targetTimeZone.getDSTSavings());
}
return calendar.getTime();
} catch (ParseException e) {
e.printStackTrace();
}
return null;
}
This doesn't seem to work..
The problem is that the date is relative to the timezone of the server. The one downloading could be confused with the times as they don't know its not in their own timezone.
I have a Date object, is there a way I can retrieve the timezone of the location the users phone is in, and then modify that Date object to be their own timezone?
Thanks
EDIT:
How to get TimeZone from android mobile?
This gets a timezone object, but how do I change a Date object with it?
My app has to deal with server time similar to you.
(All datetime that I got from server represent datetime at UTC +00:00)
// date string to convert
String dateString = "2014-01-07 12:00:00"
// create date formatter, set time zone to UTC and parse
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.US);
TimeZone serverTimeZone = TimeZone.getTimeZone("UTC");
formatter.setTimeZone(serverTimeZone);
Date date = formatter.parse(dateString);
Log.i("Debug", "date object : " + date.toString());
// I'm in Bangkok (UTC +07:00) so I'll see "Wed Jan 07 19:00:00 GMT+07:00 2015"
// If you do this in Toronto, you should see "Wed Jan 07 07:00:00 GMT -05:00 2015"
When you wanna print this date in Toronto, I believe you don't have to calculate DST by yourself because calendar and date formatter should handle that (not sure, I read from somewhere long ago)
// Create timezone for Toronto
TimeZone torontoTimeZone = TimeZone.getTimeZone("America/Toronto");
// Create calendar, set timezone, to see hour of day in Toronto
Calendar calendar = Calendar.getInstance();
calendar.setTimeZone(torontoTimeZone);
calendar.setTime(date);
Log.i("Debug", "Hour of day : " + calendar.get(Calendar.HOUR_OF_DAY);
// Hour of day : 7
// Create date formatter, set timezone, to print date for Toronto user.
SimpleDateFormat formatter = new SimpleDateFormat("dd MMM yyyy, hh:mm", Locale.US);
formatter.setTimeZone(torontoTimeZone);
String torontoDate = formatter.format(date);
Log.i("Debug", "Date in Toronto : " + torontoDate);
// Date in Toronto : 07 Jan 2015, 07:00
You can set calendar and date formatter to user timezone by replace
TimeZone timezone = TimeZone.getTimeZone("America/Toronto")
with
TimeZone timezone = TimeZone.getDefault()
When I deal with date from server, I'll
request UTC time from server, if server doesn't send me UTC time, convert to UTC time first.
when parse date object from server, I always create date object represent time at UTC (time at server)
perform calculation or anything else with UTC date object.
pass only UTC date object from and to Activity/Fragment/Service/Model
only format date string with user timezone only when I need to display to user.
This is how you can change the date to your timezone
SimpleDateformat sdf = new SimpleDateFormat("yourformat");
TimeZone tz = TimeZone.getDefault();
sdf.setTimezone(tz);
sdf.format(yourdate); //will return a string in "your-format" to represent date
You're on the right track. You need to set the time zone of the Calendar object to the server's time zone. Then you can add the offset (and factor in DST) with the TimeZone that you got from the user's device (the link you included).
Code:
calendar.add(Calendar.MILLISECOND, serverTimeZone.getRawOffset() * -1);
if (serverTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, calendar.getTimeZone().getDSTSavings() * -1);
}
calendar.add(Calendar.MILLISECOND, targetTimeZone.getRawOffset());
if (targetTimeZone.inDaylightTime(calendar.getTime())) {
calendar.add(Calendar.MILLISECOND, targetTimeZone.getDSTSavings());
}
After that, you can retrieve the date in the usual way from the Calendar.
Also see this answer for more information.

Date and time conversion to some other Timezone in java

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);
}

Categories