4

I have some questions regarding timezones. We store all our date in UTC time, but we need to show some of them in local (US Eastern) time and UTC at the same time.

Here is my test, I have a date in UTC and want to display it in UTC and local time:

<html>
<!-- let's assume this date is in UTC, I get it from Database in my code -->
<jsp:useBean id="dateValue" class="java.util.Date" />

GMT
<fmt:formatDate value="${dateValue}" pattern="yyyy-MM-dd HH:mm:ss z" timeZone="GMT"/>
</html>
<!-- Displays the original time +4  - not what I need-->

No time zone
<fmt:formatDate value="${dateValue}" pattern="yyyy-MM-dd HH:mm:ss z"/> 
<!-- Displays the original time, but timezone is EDT -->

US/Eastern
<fmt:formatDate value="${dateValue}" pattern="yyyy-MM-dd HH:mm:ss z" timeZone="US/Eastern"/> 
<!-- Displays the original time, timezone is EDT, I need original + 4 -->

</html>

To reiterate: I have a UTC time from database and want to format it and show in UTC timezone. Server runs in other timezone than UTC.

Basically I need a function like

convertToTimezone(date, originalTimeZone, desiredTimeZone). 

What fmt:formatDate provides is something like

convertToTimezone(date, serverTimeZone, desiredTimeZone). 

I could hack it, but that usually causes problems when there is a daylight time saving, etc.

P.S. For those people looking for answers - one thing to do is to run your server in UTC, then the conversions would work fine. If can't change that, the only way to go is to create the new date with UTC time zone, do it explicitly, I myself converted the time I had to text, then created a new date and provided the data from the text and UTC timezone. If you don't do that, the timezone is read from the server.

Roman Goyenko
  • 6,965
  • 5
  • 48
  • 81

6 Answers6

12

I don't understand your problem. It's all working properly. You seem to be expecting that new Date() would treat the computer time as GMT, i.e. 19:21 GMT. This is wrong. It calculates the real GMT time based on the computer's timezone. The fmt:setTimeZone doesn't change the computer's timezone and also not the outcome of new Date(). The fmt:setTimeZone just sets the default timezone of all dates which are to be formatted by fmt:formatDate. This is only mandatory if the computer's timezone is not GMT.

Remove the fmt:setTimeZone and you'll see that the dates are (incorrectly) off by 4 hour. Then start the server with -Duser.timezone=UTC (to override computer's timezone being the default) and you'll see that it's correct again. Also give it a try with real dates from the DB instead of new Date().

Regardless, running the server in a timezone other than UTC is a bad practice. It would only lead to trouble in all colors. I strongly recommend to run the server in UTC. If you don't want to change the machine's timezone for some reason, then you can do that by adding -Duser.timezone=UTC to server's VM arguments. Use UTC all the time and apply the timezone only at the moment you're displaying it to the enduser. See also DST and Timezone best practices.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Well, we store the dates in database in UTC, but I show the time, like request generated time in local time. So, I need both. For this reason I can't start server with timezone UTC. What I am looking for is a conversion from UTC time to specified timezone time. I don't want to change server time for that. Server has other web applications that are local, so I can't really change the server timezone to UTC. – Roman Goyenko Nov 05 '10 at 14:28
  • There the `fmt:setTimeZone` and/or `fmt:formatDate timeZone` is for. The `Date` itself is always UTC. – BalusC Nov 05 '10 at 14:29
  • well, let's say you have a UTC time from database and you want to format it and show in UTC time, how would you show it in your JSP? Assuming server runs in other timezone than UTC. – Roman Goyenko Nov 05 '10 at 14:37
  • Just the way as you did in your question. The problem is only that your testcase is bogus because you incorrectly expected that `new Date()` would treat the computer time as GMT all time. – BalusC Nov 05 '10 at 14:41
  • I understand that fmt:setTimezone only changes it for the fmt:formatDate. My problem is that fmt:formatDate assumes it formats the date in local time. There is no way to tell it is UTC time. I am going to change testcase in main question – Roman Goyenko Nov 05 '10 at 14:49
  • Then your DB didn't return UTC time at all. – BalusC Nov 05 '10 at 14:56
  • I edited the question so you see my problem better. Basically I need a function like convertToTimezone(date, originalTimeZone, desiredTimeZone). What fmt:formatDate provides is something like convertToTimezone(date, serverTimeZone, desiredTimeZone). I could hack it, but that usually causes problems when there is a daylight time saving, etc. – Roman Goyenko Nov 05 '10 at 15:01
  • The `` does basically `new Date()` and it uses the computer's timezone to calculate the GMT time and then stores it. Further the `fmt:formatDate` does more like `convertToTimezone(date, UTC, desiredTimeZone)` because `Date` internally uses UTC (GMT without DST). – BalusC Nov 05 '10 at 15:05
  • not really, adds 4 hours, so it assumes the date is in local server time. – Roman Goyenko Nov 05 '10 at 15:12
  • 1
    In case of date from `new Date()`, it's because your computer time is GMT-4. In case of date from DB, it's because DB is apparently returning date as GMT-4 (maybe because the DB server itself is also running GMT-4). – BalusC Nov 05 '10 at 15:18
  • 1
    Ok, what you are telling is right, the DB reading was setting timezone to ETD, not UTC. Thanks a lot for help! – Roman Goyenko Nov 05 '10 at 15:40
3

You need to use the international time (UTC/Zulu) to add the following schedule client time use, for example "GMT+1". See this example.

Put this parameter as argument in your server to set UTC time use, in this case is for tomcat:

-Duser.timezone="UTC"

/* Java */      

@RequestMapping(value = "/web", method = { RequestMethod.POST, RequestMethod.GET })
public String web(Model model, HttpSession session, Locale locale) {

    Date today = new Date();
    model.addAttribute("currentTime", today);
    model.addAttribute("timezone", "GMT+1");

    return "web";
}

To show date choose your pattern you want (properties)

/* JSP web */

<fmt:timeZone value="${timezone}">
<spring:message code="date_format_dateMin" var="pattern"/>
<fmt:formatDate value="${currentTime}" timeZone="${timezone}" pattern="${pattern}" var="searchFormated" />
<span class="innerLabel">${searchFormated}</span>   
</fmt:timeZone>

/* Properties */

date_format_dateMin=yyyy/MM/dd HH:mm
date_format=yyyy/MM/dd HH:mm:ss    
date_format2=yyyy/MM/dd
date_format3_js=yy/mm/dd
date_format4_time=HH:mm
date_format4=dd/MM/yyyy HH:mm:ss
borchvm
  • 3,533
  • 16
  • 44
  • 45
  • That's what I said in the P.S. in my question - I couldn't change my server timezone, so I needed to create a new date with UTC timezone. – Roman Goyenko May 09 '14 at 14:48
  • To convert UTC time use this function: public Date getDateFromStringUTC(String fecha, Locale locale) { SimpleDateFormat simpleDateFormat = new SimpleDateFormat(SkremmConstants.FORMAT_DATE, locale); TimeZone utcZone = TimeZone.getTimeZone("UTC"); simpleDateFormat.setTimeZone(utcZone); Date date = null; try { date = simpleDateFormat.parse(fecha); } catch (ParseException e) { e.printStackTrace(); } return date; } – borchvm May 12 '14 at 09:52
  • I put it down the function – borchvm May 12 '14 at 10:31
3

To convert UTC time I use this function:

 public Date getUTCDateFromString(String fecha, Locale yourLocale) {
    SimpleDateFormat simpleDateFormat = new 
    SimpleDateFormat("yyyy-MM-dd HH:mm:ss", yourLocale);
    TimeZone utcZone = TimeZone.getTimeZone("UTC");
    simpleDateFormat.setTimeZone(utcZone);
    Date date = null;
    try {
        date = simpleDateFormat.parse(fecha);
    } catch (ParseException e) {
        e.printStackTrace();
    }
    return date;
    }
borchvm
  • 3,533
  • 16
  • 44
  • 45
2

Java assumes that your time is GMT+4 because your system time is GMT+4.

Matt Ball
  • 354,903
  • 100
  • 647
  • 710
2

Try:

<fmt:setTimeZone value="Europe/London" scope="session"/>
Sackers
  • 96
  • 2
0
<c:when test="${currentField eq 'dateline'}">
  <c:set target="${storyContent}" property="publishedDate">
  <fmt:formatDate value="${article.publishedDateAsDate}" timeZone="Asia/Dacca"       pattern="${storyContent.dateFormat}"/>
  </c:set>

I have been messing with this problem for 3 days.

First it was like this -

<fmt:formatDate value="${article.publishedDateAsDate}" pattern="${storyContent.dateFormat}"/>

which showed the date in server time UTC+00 hrs.

I wanted to show it in Dhaka time, keeping the server time unchanged. Adding this solved the problem-

timeZone="Asia/Dacca"

You can find all the Java timezone details here http://joda-time.sourceforge.net/timezones.html

Syed Priom
  • 1,893
  • 1
  • 21
  • 22