int screenHeight = BrowserInfo.get().getScreenHeight();
int tzOffset = BrowserInfo.get().getTimezoneOffset();
int rtzOffset = BrowserInfo.get().getRawTimezoneOffset();
+ int dstDiff = BrowserInfo.get().getDSTDifference();
+ boolean dstInEffect = BrowserInfo.get().isDSTInEffect();
+ long curDate = BrowserInfo.get().getCurrentDate().getTime();
String widgetsetVersion = ApplicationConfiguration.VERSION;
String token = History.getToken();
String parameters = "repaintAll=1&" + "sh=" + screenHeight + "&sw="
+ screenWidth + "&cw=" + clientWidth + "&ch=" + clientHeight
+ "&vw=" + offsetWidth + "&vh=" + offsetHeight + "&fr=" + token
- + "&tzo=" + tzOffset + "&rtzo=" + rtzOffset + "&wsver="
- + widgetsetVersion;
+ + "&tzo=" + tzOffset + "&rtzo=" + rtzOffset + "&dstd="
+ + dstDiff + "&dston=" + dstInEffect + "&curdate=" + curDate
+ + "&wsver=" + widgetsetVersion;
return parameters;
}
package com.vaadin.terminal.gwt.client;
+import java.util.Date;
+
import com.google.gwt.user.client.ui.RootPanel;
/**
}-*/;
/**
- * Get's the timezone offset from GMT in minutes, as reported by the browser
+ * Gets the timezone offset from GMT in minutes, as reported by the browser
* AND adjusted to ignore daylight savings time. DST does not affect this
* value.
*
}-*/;
+ /**
+ * Gets the difference in minutes between the browser's GMT timezone and
+ * DST.
+ *
+ * @return the amount of minutes that the timezone shifts when DST is active
+ */
+ public native int getDSTDifference()
+ /*-{
+ var d = new Date();
+ var tzo1 = d.getTimezoneOffset(); // current offset
+
+ for (var m=12;m>0;m--) {
+ d.setUTCMonth(m);
+ var tzo2 = d.getTimezoneOffset();
+ if (tzo1 != tzo2) {
+ // NOTE js indicates this 'backwards' (e.g -180)
+ return (tzo1 > tzo2 ? tzo1-tzo2 : tzo2-tzo1); // offset w/o DST
+ }
+ }
+
+ return 0; // no DST
+ }-*/;
+
+ /**
+ * Determines whether daylight savings time (DST) is currently in effect in
+ * the region of the browser or not.
+ *
+ * @return true if the browser resides at a location that currently is in
+ * DST
+ */
+ public boolean isDSTInEffect() {
+ return getTimezoneOffset() != getRawTimezoneOffset();
+ }
+
+ /**
+ * Returns the current date and time of the browser. This will not be
+ * entirely accurate due to varying network latencies, but should provide a
+ * close-enough value for most cases.
+ *
+ * @return the current date and time of the browser.
+ */
+ public Date getCurrentDate() {
+ return new Date();
+ }
+
/**
* @return true if the browser runs on a touch based device.
*/
getHTTPRequestParameter(request, "sw"),
getHTTPRequestParameter(request, "sh"),
getHTTPRequestParameter(request, "tzo"),
- getHTTPRequestParameter(request, "rtzo"));
+ getHTTPRequestParameter(request, "rtzo"),
+ getHTTPRequestParameter(request, "dstd"),
+ getHTTPRequestParameter(request, "dstActive"),
+ getHTTPRequestParameter(request, "curdate"));
}
@Override
request.getRemoteAddr(), request.isSecure(),
request.getHeader("user-agent"), request.getParameter("sw"),
request.getParameter("sh"), request.getParameter("tzo"),
- request.getParameter("rtzo"));
+ request.getParameter("rtzo"), request.getParameter("dstd"),
+ request.getParameter("dston"), request.getParameter("curdate"));
}
protected ClassLoader getClassLoader() throws ServletException {
package com.vaadin.terminal.gwt.server;
+import java.util.Date;
import java.util.Locale;
import com.vaadin.terminal.Terminal;
private boolean secureConnection;
private int timezoneOffset = 0;
private int rawTimezoneOffset = 0;
+ private int dstDifference;
+ private boolean dstInEffect;
+ private Date currentDate;
private VBrowserDetails browserDetails;
* TimeZone offset in minutes from GMT
* @param rtzo
* raw TimeZone offset in minutes from GMT (w/o DST adjustment)
+ * @param dstDiff
+ * the difference between the raw TimeZone and DST in minutes
+ * @param dstInEffect
+ * is DST currently active in the region or not?
+ * @param curDate
+ * the current date in milliseconds since the epoch
*/
void updateBrowserProperties(Locale locale, String address,
boolean secureConnection, String agent, String sw, String sh,
- String tzo, String rtzo) {
+ String tzo, String rtzo, String dstDiff, String dstInEffect,
+ String curDate) {
this.locale = locale;
this.address = address;
this.secureConnection = secureConnection;
rawTimezoneOffset = 0; // default gmt+0
}
}
+ if (dstDiff != null) {
+ try {
+ // browser->java conversion: min->ms
+ dstDifference = Integer.parseInt(dstDiff) * 60 * 1000;
+ } catch (final NumberFormatException e) {
+ dstDifference = 0; // default no difference
+ }
+ }
+ if (dstInEffect != null) {
+ this.dstInEffect = Boolean.parseBoolean(dstInEffect);
+ }
+ if (curDate != null) {
+ try {
+ long curTime = Long.parseLong(curDate);
+ currentDate = new Date(curTime);
+ } catch (final NumberFormatException e) {
+ currentDate = new Date();
+ }
+ }
}
/**
return rawTimezoneOffset;
}
+ /**
+ * Gets the difference in minutes between the browser's GMT TimeZone and
+ * DST.
+ *
+ * @return the amount of minutes that the TimeZone shifts when DST is active
+ */
+ public int getDSTDifference() {
+ return dstDifference;
+ }
+
+ /**
+ * Determines whether daylight savings time (DST) is currently in effect in
+ * the region of the browser or not.
+ *
+ * @return true if the browser resides at a location that currently is in
+ * DST
+ */
+ public boolean isDSTInEffect() {
+ return dstInEffect;
+ }
+
+ /**
+ * Returns the current date and time of the browser. This will not be
+ * entirely accurate due to varying network latencies, but should provide a
+ * close-enough value for most cases.
+ *
+ * @return the current date and time of the browser.
+ */
+ public Date getCurrentDate() {
+ return currentDate;
+ }
+
}
<tr><td rowspan="1" colspan="3">New Test</td></tr>
</thead><tbody>
<tr>
- <td>open</td>
- <td>/run/com.vaadin.tests.application.WebBrowserTest?restartApplication</td>
- <td></td>
+ <td>open</td>
+ <td>/run/com.vaadin.tests.application.WebBrowserTest?restartApplication</td>
+ <td></td>
</tr>
<tr>
- <td>click</td>
- <td>vaadin=runcomvaadintestsapplicationWebBrowserTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td>
- <td></td>
+ <td>click</td>
+ <td>vaadin=runcomvaadintestsapplicationWebBrowserTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[0]/VButton[0]/domChild[0]/domChild[0]</td>
+ <td></td>
</tr>
+<!-- Raw offset -->
<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestsapplicationWebBrowserTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VLabel[0]</td>
- <td>7200000</td>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestsapplicationWebBrowserTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[2]/VLabel[0]</td>
+ <td>7200000</td>
</tr>
+<!-- offset to Helsinki -->
<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestsapplicationWebBrowserTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[3]/VLabel[0]</td>
- <td>0</td>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestsapplicationWebBrowserTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[6]/VLabel[0]</td>
+ <td>0</td>
</tr>
+<!-- in Helsinki? -->
<tr>
- <td>assertText</td>
- <td>vaadin=runcomvaadintestsapplicationWebBrowserTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VLabel[0]</td>
- <td>Yes</td>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestsapplicationWebBrowserTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[7]/VLabel[0]</td>
+ <td>Yes</td>
+</tr>
+<!-- DST active? -->
+<tr>
+ <td>assertText</td>
+ <td>vaadin=runcomvaadintestsapplicationWebBrowserTest::/VVerticalLayout[0]/ChildComponentContainer[1]/VVerticalLayout[0]/ChildComponentContainer[4]/VLabel[0]</td>
+ <td>Yes</td>
</tr>
-
</tbody></table>
</body>
</html>
final Label rawOffsetLabel = new Label("n/a");\r
rawOffsetLabel.setCaption("Browser raw offset");\r
\r
+ final Label dstDiffLabel = new Label("n/a");\r
+ dstDiffLabel.setCaption("Difference between raw offset and DST");\r
+\r
+ final Label dstInEffectLabel = new Label("n/a");\r
+ dstInEffectLabel.setCaption("Is DST currently active?");\r
+\r
+ final Label curDateLabel = new Label("n/a");\r
+ curDateLabel.setCaption("Current date in the browser");\r
+\r
final Label diffLabel = new Label("n/a");\r
diffLabel.setCaption("Browser to Europe/Helsinki offset difference");\r
\r
- hkiOffset));\r
\r
containsLabel.setValue(contains ? "Yes" : "No");\r
+\r
+ dstDiffLabel.setValue(String.valueOf(getBrowser()\r
+ .getDSTDifference()));\r
+\r
+ dstInEffectLabel\r
+ .setValue(getBrowser().isDSTInEffect() ? "Yes"\r
+ : "No");\r
+\r
+ curDateLabel.setValue(getBrowser().getCurrentDate()\r
+ .toString());\r
}\r
});\r
\r
addComponent(update);\r
addComponent(offsetLabel);\r
addComponent(rawOffsetLabel);\r
+ addComponent(dstDiffLabel);\r
+ addComponent(dstInEffectLabel);\r
+ addComponent(curDateLabel);\r
addComponent(diffLabel);\r
addComponent(containsLabel);\r
\r