Slim3 の Timezone の取り扱いについて
- FrontController では、タイムゾーンは UTC に設定されている。
- TestCase から FrontController で設定されているタイムゾーンはローカル時間。
この場合、自分は日本時間に設定しているので、JST で設定されている。 - TestCase で使う Controller のタイムゾーンはローカル時間。
この場合も JST で設定されている。しかし、org.slim3.util.DateUtil 利用した際のタイムゾーンは UTC になる。 - org.slim3.util.DateUtil を利用すると、web.xml で設定している時間帯に自動的に変換される。
FrontController のタイムゾーンの挙動
コントローラー側の記述。
public class TimezoneController extends Controller { @Override public Navigation run() throws Exception { TimeZone tz = TimeZone.getDefault(); requestScope("timeId", tz.getID()); requestScope("timeZoneName", tz.getDisplayName()); requestScope("offset", tz.getRawOffset()); return forward("timezone.jsp"); } }
JSP の記述。
<%@page pageEncoding="UTF-8" isELIgnored="false" session="false"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <%@taglib prefix="f" uri="http://www.slim3.org/functions"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>タイムゾーン</title> </head> <body> <p>${f:h(timeId)}</p> <p>${f:h(timeZoneName)}</p> <p>${f:h(offset)}</p> </body> </html>
表示結果
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>タイムゾーン</title> </head> <body> <p>UTC</p> <p>協定世界時</p> <p>0</p> </body> </html>
コントローラーでローカルのタイムゾーンを設定した場合。
public class TimezoneController extends Controller { @Override public Navigation run() throws Exception { TimeZone tz = TimeZone.getTimeZone("Asia/Tokyo"); requestScope("timeId", tz.getID()); requestScope("timeZoneName", tz.getDisplayName()); requestScope("offset", tz.getRawOffset()); return forward("timezone.jsp"); } }
実行結果。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>タイムゾーン</title> </head> <body> <p>Asia/Tokyo</p> <p>日本標準時</p> <p>32400000</p> </body> </html>
FrontController のタイムゾーンの挙動と org.slim3.util.DateUtil 利用後のタイムゾーン
TimeZone.getTimeZone("Asia/Tokyo") の場合
public class TimezoneController extends Controller { @Override public Navigation run() throws Exception { TimeZone tz = TimeZone.getTimeZone("Asia/Tokyo"); Calendar cal = Calendar.getInstance(tz); String datePattern = "yyyy-MM-dd HH:mm:ss z"; requestScope("timeId", tz.getID()); requestScope("timeZoneName", tz.getDisplayName()); requestScope("offset", tz.getRawOffset()); requestScope("calendarDateTime", cal.getTime()); requestScope("dateDateTime", new Date()); requestScope("dateUtilzedDateTimeOfCalendar", DateUtil.toString(cal.getTime(), datePattern)); requestScope("dateUtilzedDateTimeOfDate", DateUtil.toString(new Date(), datePattern)); } }
実行結果。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>タイムゾーン</title> </head> <body> <p>Asia/Tokyo</p> <p>日本標準時</p> <p>32400000</p> <!-- Calendar から作成した日時 --> <p>Fri Jul 22 04:42:53 UTC 2011</p> <!-- Date を利用した日付 --> <p>Fri Jul 22 04:42:53 UTC 2011</p> <!-- org.slim3.util.DateUtil を利用した Calendar の日付 --> <p>2011-07-22 13:42:53 JST</p> <!-- org.slim3.util.DateUtil を利用した Date の日付 --> <p>2011-07-22 13:42:53 JST</p> </body> </html>
TimeZoneLocator.get() の場合。
public class TimezoneController extends Controller { @Override public Navigation run() throws Exception { TimeZone tz = TimeZoneLocator.get(); Calendar cal = Calendar.getInstance(tz); String datePattern = "yyyy-MM-dd HH:mm:ss z"; requestScope("timeId", tz.getID()); requestScope("timeZoneName", tz.getDisplayName()); requestScope("offset", tz.getRawOffset()); requestScope("calendarDateTime", cal.getTime()); requestScope("dateDateTime", new Date()); requestScope("dateUtilzedDateTimeOfCalendar", DateUtil.toString(cal.getTime(), datePattern)); requestScope("dateUtilzedDateTimeOfDate", DateUtil.toString(new Date(), datePattern)); } }
実行結果。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>タイムゾーン</title> </head> <body> <p>Asia/Tokyo</p> <p>日本標準時</p> <p>32400000</p> <!-- Calendar から作成した日時 --> <p>Fri Jul 22 04:46:15 UTC 2011</p> <!-- Date を利用した日付 --> <p>Fri Jul 22 04:46:15 UTC 2011</p> <!-- org.slim3.util.DateUtil を利用した Calendar の日付 --> <p>2011-07-22 13:46:15 JST</p> <!-- org.slim3.util.DateUtil を利用した Date の日付 --> <p>2011-07-22 13:46:15 JST</p> </body> </html>
Oh...
予想では、TimeZone.getTimeZone("Asia/Tokyo") と TimeZoneLocator.get() で明示して設定した cal.getTime() から日本時間(Fri Jul 22 13:46:15 JST 2011)が帰ってくると思っていたが、UTC の時間が表示されている。
また、TimeZone.getTimeZone("Asia/Tokyo") と TimeZoneLocator.get() で明示して設定した後に、
TimeZone tz = TimeZone.getTimeZone("Asia/Tokyo"); Calendar cal = Calendar.getInstance(tz); cal.setTimeZone(tz); cal.setTime(new Date()); requestScope("calendarDateTime", cal.getTime());
とCalendar クラスにタイムゾーンを設定しても、
<!-- Calendar から作成した日時 --> <p>Fri Jul 22 04:46:15 UTC 2011</p> <!-- Date を利用した日付 --> <p>Fri Jul 22 04:46:15 UTC 2011</p>
のタイムゾーンは変わらなかった。
DateFormat クラスと SimpleDateFormat クラス
日付を Date クラスから出力する場合は、DateFormat クラスか SimpleDateFormat クラスを経由して任意のタイムゾーンの日付に変換する必要があるのが、(やっと)わかった。
上記の Controller の場合、
public class TimezoneController extends Controller { @Override public Navigation run() throws Exception { TimeZone tz = TimeZone.getTimeZone("Asia/Tokyo"); SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss z"); sdf.setTimeZone(tz); DateFormat df = DateFormat.getInstance(); df.setTimeZone(tz); Calendar cal = Calendar.getInstance(); String datePattern = "yyyy-MM-dd HH:mm:ss z"; requestScope("timeId", tz.getID()); requestScope("timeZoneName", tz.getDisplayName()); requestScope("offset", tz.getRawOffset()); requestScope("calendarDateTime", cal.getTime()); requestScope("dateFormat", df.format(cal.getTime())); requestScope("simpleDateFormat", sdf.format(cal.getTime())); requestScope("dateUtilzedDateTimeOfCalendar", DateUtil.toString(cal.getTime(), datePattern)); requestScope("dateUtilzedDateTimeOfDate", DateUtil.toString(new Date(), datePattern)); } }
そして JSP は、
<%@page pageEncoding="UTF-8" isELIgnored="false" session="false"%> <%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%> <%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions"%> <%@taglib prefix="f" uri="http://www.slim3.org/functions"%> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>タイムゾーン</title> </head> <body> <p>${f:h(timeId)}</p> <p>${f:h(timeZoneName)}</p> <p>${f:h(offset)}</p> <!-- Calendar から作成した日時 --> <p>${f:h(calendarDateTime)}</p> <!-- DateFormat を利用した日付 --> <p>${f:h(dateFormat)}</p> <!-- SimpeDateFormat を利用した日付 --> <p>${f:h(simpleDateFormat)}</p> <!-- org.slim3.util.DateUtil を利用した Calendar の日付 --> <p>${f:h(dateUtilzedDateTimeOfCalendar)}</p> <!-- org.slim3.util.DateUtil を利用した Date の日付 --> <p>${f:h(dateUtilzedDateTimeOfDate)}</p> </body> </html>
そして結果は、
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <title>タイムスタンプ</title> </head> <body> <p>Asia/Tokyo</p> <p>日本標準時</p> <p>32400000</p> <!-- Calendar から作成した日時 --> <p>Fri Jul 22 07:28:40 UTC 2011</p> <!-- DateFormat を利用した日付 --> <p>11/07/22 16:28</p> <!-- SimpeDateFormat を利用した日付 --> <p>2011-07-22 16:28:40 JST</p> <!-- org.slim3.util.DateUtil を利用した Calendar の日付 --> <p>2011-07-22 16:28:40 JST</p> <!-- org.slim3.util.DateUtil を利用した Date の日付 --> <p>2011-07-22 16:28:40 JST</p> </body> </html>
これで意図通りの結果が得られるようになった…。