com.smartgwt.client.docs

## Interface DateFormatAndStorage

-     public interface DateFormatAndStorage

  ### Date and Time Format and Storage

  The Smart GWT system has the following features for handling Date and Time type values within DataSources and databound components.

  DataSources and databound components may define fields of type `date`, `time`, or `datetime`.

  ### "date" handling

  Fields of type `date` are considered to be logical Dates with no time value, such as a holiday or birthday. In the browser, values for "date" fields are stored as Date objects, but when formatted for display to the user, they are typically displayed without any time information.

  When using the Smart GWT server framework, "date" values are automatically transmitted with year, month and day preserved and time value ignored.

  When sent or received in XML or JSON, date field values should be serialized in the XML Schema date format - `YYYY-MM-DD` - are expected to be received in the same format. Any time value present for a "date" field is ignored.

  The DateUtil.createLogicalDate() method may be used to create a new Date object to represent a logical date value on the browser.

  System wide formatting for dates may be controlled via the `Date.setNormalDisplayFormat()` and `Date.setShortDisplayFormat()` methods.

  ### "datetime" handling

  Fields of type `datetime` are dates with full time information. In the browser, values for datetime fields are stored as Date objects.

  When using the Smart GWT server framework, "datetime" values are automatically transmitted such that the resulting Date object has the same GMT/UTC timestamp (milliseconds since epoch).

  When sent or received in XML or JSON, datetime field values should be serialized out as full datetimes using the standard XML Schema datetime format (EG:`2006-01-10T12:22:04-04:00`). If no timezone offset is supplied, the value is assumed to be GMT/UTC.

  System wide formatting for datetimes may be controlled via the `Date.setShortDatetimeDisplayFormat()` method. Datetimes will be displayed to the user in browser local time by default (see also timezone notes below).

  ### "time" handling

  Fields of type `time` are time values in the absence of a day, such as the beginning of the workday (9:00). In the browser, values for "time" fields are stored as Date objects with the time in browser local time. The date information has no meaning and only the time information is displayed to the user.

  Time formatting is handled by the String class APIs.
  When using the Smart GWT server framework, "time" values are automatically transmitted such that the resulting Date object has the same hour, minute and second values in local time, and year/month/day is ignored.

  When sent or received in XML or JSON, date field values should be serialized as hours, minutes and seconds using the standard XML Schema time format - `"22:01:45"`. Timezone is not relevant and should be omitted.

  The DateUtil.createLogicalTime() method may be used to create a new Date object to represent a logical time value on the browser.

  ### Timezone settings and Daylight Savings Time

  By default, "datetime" values will be shown to the user in browser local time, as derived from the native browser locale. Developers may modify this behavior by specifying an explicit display timezone via String.

  Note that depending on the specific date being displayed, a Daylight Savings Time offset may also be applied based on the browser locale. To disable this behavior set String to false.

  If a custom timezone is specified, it will be respected by all `TimeDisplayFormat`s, and by the standard short `DateDisplayFormat`s when formatting dates representing datetime type values. However native JavaScript Date formatters, including `toLocaleString()` will not respect the specified timezone. Developers specifying a custom timezone may therefore wish to modify the `Date.setNormalDisplayFormat()` to avoid using a native JS Date formatter function.

  Note that in addition to the system-wide date, datetime and time-formatting settings described above, databound components also support applying custom display formats for date values. Typically this can be achieved via a custom `dateFormatter` or `timeFormatter` at the field level (see `DataSourceField.dateFormatter`, `DataSourceField.timeFormatter` and for example `ListGridField.dateFormatter`). Date formatting may also be configured at the component level by setting the `dateFormatter`, `datetimeFormatter` and `timeFormatter` attributes (See for example `ListGrid.dateFormatter`, `ListGrid.timeFormatter`, and `ListGrid.datetimeFormatter`).

  ### Troubleshooting Date and Time values

  Date and time storage and timezones can be confusing, and Isomorphic receives a steady stream of false bug reports from users that are incorrectly analyzing logs and diagnostics. Please consider the following points when troubleshooting issues such as date values changing to a different day, or datetime value shifting when saved and reloaded:

  #### 1. compare values for "datetime" fields via date.getTime()

  Whenever you use Date.toString() (client or server-side) the value you get is based on the server or browser timezone.

  Perhaps you are troubleshooting an issue with datetimes and you try to log the value of a Date like this:

           Date someDate = <some expression>;
           log("date value is: " + someDate);

  Code like this will show the datetime value in the server's timezone if executed server-side, and in the client's timezone if executed client-side. If they are in different timezones, the hour or day will be different, whereas the actual datetime value - milliseconds since epoch as retrieved by Date.getTime() - is the same. To correctly compare two datetime values, compare the result of getTime().

  #### 2. "date" and "time" field values cannot be compared via getTime()

  This is the inverse situation as for "datetime" values. As explained above, "date" values have no meaningful values for time fields (hours/minutes/seconds) and "time" values have no meaningful values for date fields (month/day/year). Here, the result of Date.getTime() is not meaningful, and values should be compared via getHours(), getMonth() et al.

  #### 3. the display timezone does not affect Date.getHours(), Date.getDay() et al

  If you've called setDefaultDisplayTimezone() to cause all datetime values to be rendered in a particular timezone, this does not affect the return values of Date.getHours(), which will still return values for the browser's current timezone. Hence it is not a bug if you have a "datetime" value which is displaying as 4am, but getHours() returns 10 or some other number. This just reflects the timezone offset between the timezone passed to setDefaultDisplayTimezone() and the browser's local timezone.

  #### 4. use correct DataSourceField types and use the matching FormItem type

  If you declare a field as type "date" but values you provide actually contain specific hours, minutes and seconds, these will not be preserved. The system will discard or reset the hours, minutes and seconds in the course of serialization or editing. Likewise if you declare a field as type "time" but actually provide values where year, month and day have meaning, these values will be dropped.

  Similarly, DateItem expects values for "date" fields, TimeItem expects values for "time" fields, and DateTimeItem expects values for "datetime" fields. Providing the wrong type of value to a control, such as providing a value from a "datetime" field to a DateItem, will have unspecified results.

  If you want to take the date and time aspects of a "datetime" value and edit them in separate FormItems, use `getLogicalDateOnly()` and `DateUtil.getLogicalTimeOnly()` to split a datetime value into date and time values, and use `DateUtil.combineLogicalDateAndTime()` to re-combine such values. Otherwise it is very easy to make mistakes related to timezone offsets.

  #### 5. check data at every phase when troubleshooting

  If you're having a problem with round-tripping "datetime" values or "date" values shifting to another day, you need to isolate the problem to a specific layer. Bearing in mind the techniques above for comparing values, you potentially need to look at any/all of the following:

  1. what value do I have on the server-side before it's sent to the client?
  2. what value is being transmitted to the client? (use the RPC Tab of the Developer Console to see the actual data sent)
     - was the value shifted to a different time/date by my serialization approach?
     - does it have the right format? (see above for correct JSON/XML formats)
  3. what value do I have on the client before it gets to any widgets (eg, do a direct call to `DataSource.fetchData()` and inspect the data in the callback)
  4. what value does the FormItem or other editing widget report before saving is attempted?
  5. what value is reported right before the value is serialized for transmission to the server (`DataSource.transformRequest()` is a good place to check)
  6. what value is being transmitted to the server? (use the RPC tab - same concerns as for server-to-client transmission above)
  7. what value does the server have after de-serialization, before saving to the database or other permanent storage?
  8. what value is sent to the database or permanent storage? If generating SQL or another similar query language, does the value in the SQL statement include an explicit timezone? If not, how will the database interpret it?