Date.toString not showing local timezone - java

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

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

Timezone conversion in Grails leads to wrong dates

I'm about to deal with time zones in Grails (Java). Here Java 7 is used and Grails 2.3.7.
I have a WebApp where each user is assigned a timeZoneID. If a user enters a date, it only consists of day, month and year. I want to set the time automatically.
The date entered by the user (e.g. 01.10.2018, german format) should be saved in the DB (MySQL) in UTC format.
When the date is displayed to the user, it is formatted according to the user's time zone.
Many timeZoneIDs work fine with my code (Europe/Berlin, Hont_Kong, ....), but America/New_York for example doesn't and I don't understand why.
The code to parse and save a date is as follows:
//endDate is 31.10.2018
def format = messageService.getMessage(code: 'default.date.short.format')
//--> dd.MM.yyyy for DE and MM/dd/yy for EN
println("Use format: " + format)
SimpleDateFormat sdf = new SimpleDateFormat(format);
//set timezone (America/New_York)
sdf.setTimeZone(TimeZone.getTimeZone(user.timeZoneID))
//parse endDate
Date parsedEndDate = sdf.parse(endDate)
//create a calendar instance (e.g. America/New_York)
Calendar calendarEnd = Calendar.getInstance(TimeZone.getTimeZone(user.timeZoneID));
//set time
calendarEnd.setTime(parsedEndDate);
//set hour/minute automatically
calendarEnd.set(Calendar.HOUR_OF_DAY, 23)
calendarEnd.set(Calendar.MINUTE, 59)
//at this point it should be 31.10.2018, 23:59 (german format, timezone America/New_York)
//Convert to UTC before saving date in DB (MySQL)
calendarEnd.setTimeZone(TimeZone.getTimeZone('UTC'))
//save the date
def obj = new Foo(date:calendarEnd).save(flush:true)
The code inside my view (gsp) to display a date is as follows:
<g:formatDate
timeZone="${user.timeZoneID}"
date="${fooInstance?.calendarEnd}"
format="${message(code: 'default.date.format', default: 'MM/dd/yyyy, hh:mm a')}"/>
Inside the DB I get 2018-11-01 00:59:00
Inside my view (GSP) it results in 31.10.2018, 19:59, instead of 31.10.2018, 23:59
Thank you very much for your help.
The problem is in convert step:
//Convert to UTC before saving date in DB (MySQL)
calendarEnd.setTimeZone(TimeZone.getTimeZone('UTC'))
Because you are just changing the time zone so it is using the given time and date as if it is the UTC time zone.
Java 1.7 and before are somewhat unwieldy in regards to the Time API so a lot of people use Joda Time.
Otherwise you can use the advice from this question resulting in something like:
calendarEnd.add(Calendar.MILLISECOND, TimeZone.getTimeZone('UTC').getOffset(parsedEndDate.getTime())
This is not tested and could be wrong as the offset calculation might be diffrent

local to UTC conversion in java

I need to convert local time at a specific city to UTC.
For example ,
convert time in NYC to UTC .
If I pass the local time and country , the service should be able to return the UTC
Is there any library/utility which maps the city/country to timezone and then converts it to UTC ?
I am trying to avoid building a time zone master and do the conversion .
Since this is common problem, if there are any libraries which are already doing it - please revert back
Just need to use Calendar and TimeZone classes?
Define a TimeZone for UTC:
TimeZone tz = TimeZone.getTimeZone("UTC");
And then create the calendar
Calendar cal = Calendar.getInstance(tz);
To retrieve the Date object use calendar.getTime
cal.getTime()
If you already have your date in a Date object (localDate) you can use a formatter:
SimpleDateFormat formatter = new SimpleDateFormat(); formatter.setTimeZone(TimeZone.getTimeZone("UTC"));
String dateinUTC = formatter.format(localDate)

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

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.

TimeZone issue in Java XMLGregorianCalendar

I hope this is not a repeat.
I checked other searches here and all of them seem to talk about "displaying" the date in the right TimeZone format using SimpleDateFormat.
However, my problem is I obtain an XMLGregorianCalendar Object which is let us say in "CET".
I have to find out the format from this object and send the current time also in the same TimeZone as the server.
For eg: I need an XMLGregorianCalendar Object that returns me in this format(with Timezone):
2012-09-19T15:23:36.421+02:00
So I just tried this following snippet which seems to only return the time in local Timezone :(
TimeZone utc = TimeZone.getTimeZone("CET");
GregorianCalendar gc = new GregorianCalendar();
DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssZ");
df.setTimeZone(utc);
System.out.println(" - Gregorian UTC [" + df.format(gc.getTime()) + "]")
XMLGregorianCalendar currServTime = DatatypeFactory.newInstance().newXMLGregorianCalendar(gc);
System.out.println("currServTime is "+currServTime);
You should include the time zone you're interested in in the GregorianCalendar, either by passing it to the constructor or by setting it afterwards. So either of these lines should work for you:
GregorianCalendar gc = new GregorianCalendar(utc);
gc.setTimeZone(utc);

Categories