how to convert UTC time to some other time zone ("CST","IST") - java

In my Android application server will return some UTC date in following format(yyyy-MM-dd HH:mm:ss) 24hours and I need to convert those time into user's TimeZone for example CST, IST.
I did the following code but I do know is it correct or not, please assist me to do the time zone conversion in right way.
I get UTC date as json string and converting into user's time zone format and showing Android side
private static Date utcDate;
private static DateFormat expireFormat = new SimpleDateFormat(
"yyyy-MM-dd HH:mm:ss");
try {
expireFormat.setTimeZone(TimeZone.getTimeZone("UTC"));
utcDate = expireFormat.parse("2014-04-01 10:32:00");
System.out.println(TimeZone.getDefault().getID());
expireFormat.setTimeZone(TimeZone.getTimeZone(TimeZone.getDefault().getID()));
System.out.println(expireFormat.format(utcDate));
} catch (ParseException e) {
e.printStackTrace();
}
output of the code:
Asia/Calcutta
2014-04-01 16:02:00

The overall approach is OK if a re-formatted String is really what you're trying to get.
There are some issues though
SimpleDateFormat is not a threadsafe class. Setting it to a static field inside a server is a problem!
Same as #1 regarding using a static field to hold the intermediate Date object.
Is "CST" China Standard Time? Central Standard Time (US or Australia)? Cuba Standard Time? Three letter abbreviations TimeZone are bad news in general. Try to use an Olson Name or Alias if at all possible.
Is this the server side or the android? If it's a server, you could probably benefit from the new Java 8 API for DateTime handling.

Related

How to convert Date string into UTC Date object?

I'm learning Java and come across this issue. I have a date string with the given format.
String dbTime = "01/01/1998 12:30:00";
final String DATE_FORMAT = "MM/dd/yyyy HH:mm:ss";
Now I wanted to initialize/create a Date object of UTC timezone.
For this, I have tried below code
SimpleDateFormat sdfAmerica = new SimpleDateFormat(DATE_FORMAT);
TimeZone utcTimeZone = TimeZone.getTimeZone("UTC");
sdfAmerica.setTimeZone(utcTimeZone);
String sDateInAmerica = sdfAmerica.format(date); // Convert to String first
Date dateInAmerica = new Date();
try {
dateInAmerica = formatter.parse(sDateInAmerica); // Create a new Date object
} catch (ParseException e) {
e.printStackTrace();
}
This will convert the time into UTC instead of just creating a date object.
01/02/1998 23:00:00
Now I'm confused as to which is the correct approach to convert the time.
I have time in string format and I have to convert it into different formats mainly UTC to PST or PST to UTC.
After some research, I found this tutorial but was unable to get the expected output.
The java.util.Date class is not optimal to start with. While it looks like a full date from the outside, it actually only represents a timestamp without storing actual timezone information.
On Java 8 and later I'd suggest to stick with the better designed java.time.* classes.
String dbTime = "01/01/1998 12:30:00";
String DATE_FORMAT = "MM/dd/yyyy HH:mm:ss";
// parsed date time without timezone information
LocalDateTime localDateTime = LocalDateTime.parse(dbTime, DateTimeFormatter.ofPattern(DATE_FORMAT));
// local date time at your system's default time zone
ZonedDateTime systemZoneDateTime = localDateTime.atZone(ZoneId.systemDefault());
// value converted to other timezone while keeping the point in time
ZonedDateTime utcDateTime = systemZoneDateTime.withZoneSameInstant(ZoneId.of("UTC"));
// timestamp of the original value represented in UTC
Instant utcTimestamp = systemZoneDateTime.toInstant();
System.out.println(utcDateTime);
System.out.println(utcTimestamp);
As you can see from the names alone there are different classes for different use-cases of dates.
java.time.LocalDateTime for example only represents a date and time without a specific timezone context and therefore can be used to parse your string value directly.
To convert timezones, you first have to convert into the a ZonedDateTime, which accepts date, time and timezone. I've intialized the sample on "systemDefault", as on most smaller apps you can use the JVM and OS'es default value to assume the current timezone.
You could also use ZoneId.of("America/Los_Angeles") directly if you want to make sure the value is interpreted as pacific time.
This value can be converted into another ZonedDateTime in another timezone, e.g. UTC.
For UTC especially you could also use the Instant class, which represents only a UTC timestamp and can also be used as a basis for most other types

How to convert 2019-09-18T01:44:35GMT-04:00 to 2019-09-18T01:44:35-04:00 using SimpleDateFormatter

I want to convert date and time to user requested timezone. date and time is in GMT format. i tried got the solution but the final string contains GMT String in resultant date like (2019-09-18T01:44:35GMT-04:00). i don't want GMT String in the resultant output.
public static String cnvtGMTtoUserReqTZ(String date, String format, String timeZone) {
// null check
if (date == null)
return null;
// create SimpleDateFormat object with input format
SimpleDateFormat sdf = new SimpleDateFormat(format);
// set timezone to SimpleDateFormat
sdf.setTimeZone(TimeZone.getTimeZone(timeZone));
try {
// converting date from String type to Date type
Date _date = sdf.parse(date);
// return Date in required format with timezone as String
return sdf.format(_date);
} catch (ParseException e) {
//log.info("Exception in cnvtGMTtoUserReqTime ::: " + e);
}
return null;
}
Actual Output : 2019-09-18T01:44:35GMT-04:00
Expected Output: 2019-09-18T01:44:35-04:00
Proces datetime objects, not strings
Your question is put in the wrong way, which is most likely due to a design flaw in your program. You should not handle date and time as strings in your program. Always keep date and time in proper datetime objects such as Instant, OffsetDateTime and ZonedDateTime. The mentioned classes are from java.time, the modern Java date and time API, which is the best we have for keeping and processing datetime data.
So your question may for example become: How to convert a moment in time to user requested timezone? A moment in time is represented by an Instant object. And the answer to the question is:
ZoneId userRequestedTimeZone = ZoneId.of("America/New_York");
Instant moment = Instant.parse("2019-09-18T05:44:35Z");
ZonedDateTime userDateTime = moment.atZone(userRequestedTimeZone);
System.out.println(userDateTime);
Please substitute your user’s desired time zone where I put America/New_York. Always give time zone in this format (region/city). Output from the snippet as it stands is:
2019-09-18T01:44:35-04:00[America/New_York]
Assuming that you don’t want the [America/New_York] part of the output, format the datetime to the string that you want:
String dateTimeWithNoZoneId = userDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME);
System.out.println(dateTimeWithNoZoneId);
2019-09-18T01:44:35-04:00
The latter output is in ISO 8601 format. This format is good for serialization, that is, if you need to convert the datetime to a machine readable textual format, for example for persistence or exchange with other systems. While also human readable, it’s not what your user prefers to see. And as I said, it’s certainly not what you should be handling and processing inside your program.
Links
Oracle tutorial: Date Time explaining how to use java.time.
Wikipedia article: ISO 8601
Use these formats:
fromFormat = "yyyy-mm-dd'T'HH:mm:sszXXX"
toFormat = "yyyy-mm-dd'T'HH:mm:ssXXX"
For more details see examples listed here

Date.toString not showing local timezone

I have a webapp . I am trying to log the time at which certain process got completed.
m_jobResults.addMessage("sum done", new Date().toString());
I am seeing that Date.toString() returns time in GMT as opposed to local timezone . If I write a test java program on same machine , it displays time in my local timezone. Could anyone suggest what is going wrong here.
Also note java.util.Calendar.getInstance().getTimeZone() shows gmt while debugging in webapp where as a sample test code shows as correct local timezone .
First you have to know is:
Date is always UTC-based.
Date does not have a "local instance."
If you want to have a to have a local time zone, use Date with Calendar and/or TimeZone.getDefault().
Use TimeZone.getTimeZone("Europe/Madrid") to get the Barcelona time zone.
If you want to find your server timezone check here:
final TimeZone timeZone = TimeZone.getDefault();
But maybe your server is not located where your user is... so to get user's locale with your server's timezone:
private String getServerTimeZoneDisplayName()
{
final TimeZone timeZone = TimeZone.getDefault();
final boolean daylight = timeZone.inDaylightTime(new Date());
final Locale locale = servletRequest.getLocale();
return timeZone.getDisplayName(daylight, TimeZone.LONG, locale);
}
If you convert a Date to a String directly, as you are doing by calling toString() on it, it will be formatted with the default timezone of the system that the code is running on. This happens to be GMT in your case.
If you want it to be formatted using a different timezone, then use a SimpleDateFormat object and specify the timezone you want on that object:
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
df.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
String text = df.format(new Date());
System.out.println("The date and time: " + text);

Joda DateTime,, Formatting, and Mysql Timestamp

After a week of going through so many examples, and moving from Java Date,
to Calendar, to Joda. I have decided to seek help from other sources.
The problem:
Our table has two fields Date (Timestamp), and TZ (String). The idea is to store
the user's UTC in timestamp, and timezone, well, you get the idea. So basically
we think in UTC, and present the user with the time converted to their
timezone on the front end (ie, using the value store in table.TZ)
Another requirement is to use the proper Object (Date, DateTime whatever).
And not pass a String representation of the date around. The best would
be a valid Long that will be correctly translated by MySQL, without having
to use the FROM_UNIXTIME mysql function in our query.
Code we are using:
public DateTime convertTimezone(LocalDateTime date, DateTimeZone srcTZ, DateTimeZone dstTZ, Locale l) {
DateTimeFormatter formatter = DateTimeFormat.forPattern("yyyy-MM-dd HH:mm:ss").withLocale(l);
DateTime srcDateTime = date.toDateTime(srcTZ);
DateTime dstDateTime = srcDateTime.toDateTime(dstTZ);
System.out.println(formatter.print(dstDateTime));
System.out.println(formatter.parseDateTime(dstDateTime.toString()));
return formatter.parseDateTime(formatter.print(dstDateTime));
}
The String output is exactly what we need (ie UTC time, 2013-08-23 18:19:12),
but the formatter.parseDateTime(dstDateTime.toString() is crashing with the following
error. Probably because of the UTC timezone independent info, and milleseconds?:
Exception in thread "main" java.lang.IllegalArgumentException: Invalid format: "2013-08- 23T18:19:12.515Z" is malformed at "T18:19:12.515Z"
at org.joda.time.format.DateTimeFormatter.parseDateTime(DateTimeFormatter.java:873)
at com.example.business.rate.RateDeck.convertTimezone(RateDeck.java:75)
at com.example.business.rate.RateDeck.WriteData(RateDeck.java:143)
at com.example.business.rate.RateDeck.main(RateDeck.java:64)
Search engine enriched question:
How to format UTC for Joda DateTime.
PS My first SO post, and it feels nice? :)
Thanks in Advance,
The new fixed version:
public Timestamp convertTimezone(LocalDateTime date, DateTimeZone srcTZ, DateTimeZone dstTZ, Locale l) {
DateTime srcDateTime = date.toDateTime(srcTZ);
DateTime dstDateTime = srcDateTime.toDateTime(dstTZ);
return new Timestamp(dstDateTime.getMillis());
}
Nick.
It's simply crashing because the format of the parsed string doesn't match with the format of the formatter.
The formatter parses using the format yyyy-MM-dd HH:mm:ss, and the toString() method of DateTime formats the date it using (as documented) the ISO8601 format (yyyy-MM-ddTHH:mm:ss.SSSZZ).

Trying to convert yyyy-MM-ddTHH:mm:ss-07:00 to correct time in Android

Okay, so here's my issue in Android right now. On our Database there's a timestamp in this format 8/15/2013 2:00:48 PM and through a .NET WebService I get that same time like this in Android: 2013-08-15T14:00:48-07:00. Now I want to convert this format into a Date Time format that I can use for comparison (for example this webservice provides every instance where a device failed at logging in so we want to check the amount of time between occurances to see if there's any issues). Below I have this code where I'm trying to use JODA Time but it's still not returning the correct format:
public static Date convertStringToDate(String input) {
String pattern = "yyyy-MM-dd'T'HH:mm:ssZ";
DateTimeFormatter formatter = DateTimeFormat.forPattern(pattern);
DateTime dateTime = formatter.parseDateTime(input);
return dateTime.toDate();
//printout shows: Thu Aug 15 17:00:48 EDT 2013
}
I know that the server is returning some crappy time format that is hard to work with (it took a while to get this to work in the iOS App we have, and even there it's still rather clunky) so I don't mind changing the webservice or the query if that would make things easier.
I have a very similar format, and I parse it using SimpleDateFormat, try this:
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZZZ", Locale.US);
Date dateTime = format .parse(value);
What i understand is that you have your correct instance of date already and what you need is to parse it to String.
I suggest you use:
DateFormat formatter = new SimpleDateFormat("d/MM/yyyy hh:mm:ss a");
//this will give you the format '8/15/2013 2:00:48 PM'
String d = formatter.format(date);
Hope this helps.
EDIT:
Also seams you want to have your date instance in -07:00 timezone
So you can change your line
DateTime dateTime = formatter.parseDateTime(input);
for
DateTime dateTime = formatter.withZone(DateTimeZone.forID("-07:00")).parseDateTime(input);

Categories