WMS and WFS have had extensions for Time for sometime, but I found these to be insufficient for my purposes. For one thing, in these extensions, there is no way to query the service for what timesteps are valid. Some services define values for continuous time. Some services have exact values for certain times and interpolate for others. Some services define values over over certain specific times.
To compensate for this, I first added a new call into the Geoanalytics implementations of WFS, WCS, and WMS called GetValiidTimes. Since the time domain can be quite large, the call can be filtered in the same way as a GetFeature, GetCoverage, or GetMap call, including a layers parameter. The return is a JSON(-P) document that contains a list of all valid timesteps and or pairs of times over which a continuous interval is defined. If exact timesteps exist within a continuous interval, these are taken to be exact as opposed to interpolated values.
For example, the following query:
http://localhost/ndfd/wms?service=WMS&request=GetValidTimes&layers=apt&time__gte=2012-01-01&time__lt=2012-01-02
Might return a list like this:
[ { begin: "2012-01-01 00:00:00+0000", end: "2012-01-02 23:59:59+0000" }, "2012-01-01 00:00:00+0000", "2012-01-01 01:00:00+0000", "2012-01-01 02:00:00+0000", ... "2012-01-01 23:00:00+0000" ]
The filtering on the URL includes time__gte and time__lt components. Geoanalytics implements filtering in an alternative way to CQL, using a filtering style found in REST frameworks such as Rails or Django. These bounds bracket the times that will be returned by the webservice, since some webservices could have years of hourly data, causing a download of tens of thousands of dates per year.
While a result-set of that magnitude is fine for some archiving applications, interactive applications using the service would suffer severe lag, so we allow filtering to contrain the set of times returned. Additionally, some layers may have data points defined for only certain times, and this allows a user to interpret time for a given layer context correctly.
From here, it is straightforward to define three more calls, GetValidVersions and GetValidElevations. GetValidElevations works in exactly the same way as GetValidTimes, except it returns numbers instead of strings that can be parsed as dates. Units are not returned, since these are generally specified in the Capabilitles document associated with a web-service.
GetValidVersions returns freeform strings, but never defines continuous fields since these make very little sense. Additionally, because multiple versions may be defined for a single time, and because versioning can be so granular, GetValidVersions returns version strings contrained to specific times like so:
[ "2012-01-01:00:00+0000" : [ "v1", "v2", "v3" ], ... ]
These times, elevations, and versions can then be used in accessing the service with the time, elevation, and version parameters in the GET or POST call.