Time zone Handling

When users first connect, we detect their timezone and, more importantly, date (since the actual day in a timezone might of course be different from the server's day) client-side, then use that to create a DayMetadata record for that day. We complement that information with what we can gather from MaxMind's geoip database (the user's lat/long coordinates, usually not very accurate, that we translate to the nearest city, using cities1000 info). Since we have a timezone and a date (in the form of a string), we can compute UTC start and end time in milliseconds for that first day. As users browse dates in the past, we don't know what timezones they have actually wandered in, so we use the initial timezone record, that we "propagate" to browsed dates.

Since, at the very least, we do have the geoip-provided city, we are able to let users immediately see if their detected location is wrong; consequently, we provide them with a means to fix this information. Note that having the timezone wrong can have very bad consequences on the computed time of facets for which time is specified without an explicit time zone (zeo and fitbit data for instance). Users will want to fix this. Note that, for such records that do not have an explicit time zone attached, fluxtream's framework has an AbstractFloatingTimeZoneFacet class that these facets need to extend. It will let the application set the correct timezone on them once the information is available.

Of course, the holy grail of timezone accuracy is Google Latitude information or, soon, other location information such as foursquare, gowalla, coordinates from photos, tweets, etc. When that information comes in, we simply update the DayMetadata record if we have it; otherwise, we create new records.

Location Data is saved as is (with discrete "soft check-ins") and, in a synthesized way, in the DayMetadata records: we want to index city and country names from these entities in order to retrieve entire days (discrete dates) and not instantaneous check-ins when users search for named locations. Indeed, in the case of looking for your last vacation spot, if we had only the individual check-ins, you would retrieve a huge list of hundreds of records, which isn't really interesting. Instead, we want to be able to get a list of dates that we can display to the user in a convenient way.

With the list of cities in the DayMetadata record, we can also make simple assumptions about wether the user is in transit or not (for example, very simply, if number of cities in one day > 20), which is something that we can ask them to confirm or not; we can also deduce that the user is probably travelling (stationary, but abroad), once we know their "base" location.

Finally, as there are potentially many timezones in a single DayMetadata when the user travels by plane, we only store the first and last timezones, in which case we are able to tell the user that we have detected ONE timezone change, and not 4 or 5.