Skip to content

Discussion: Formalizing approach to storing date and time values #1397

@dpaquette

Description

@dpaquette

Current Situation

AllReady stores campaign/event/task dates as the .NET DateTimeOffset type

  • DateTimeOffset is a .NET Framework type that represents a particular point in time relative to UTC. It is a Date and Time with an Offset relative to UTC. (https://msdn.microsoft.com/en-us/library/system.datetimeoffset.aspx)
  • Each Campaign has a Windows/.NET TimeZoneID specifying the timezone where the campaign is located. For example, a campaign in Seattle would have the TimeZoneID = "Pacific Standard Time"
  • An Event within a campaign also has a TimeZoneID specifying the timezone where the event is located. The default TimeZoneID is the same as the campaign but can differ when events are located across the country.
  • All Tasks for an event inherit the TimeZoneID from the event.
  • A Campaign / Event / Task start and end date / time is stored as a DateTimeOffset with the offset set to the UTC offset according to the TimeZoneID of the campaign.
  • For example, consider the following campaign located in Seattle
Event Start Date Time with Offset End Date Time with Offset
Event 1 10/23/2016 5:00 PM -7:00 10/23/2016 8:00 PM -7:00
Event 2 12/20/2016 5:00 PM -8:00 12/20/2016 8:00 PM -8:00
  • Note the offset is different depending of whether or not the date and time falls during daylight savings time for the Seattle area. AllReady calculates this offset whenever date/time values are saved by calling TimeZoneInfo.GetUtcOffset for date/time that was specified by the user.
  • //TODO: Add example here of how and why the offset if adjusted when values are saved

Potential Risks
Thank you to Jon Skeet for pointing out the following potential problems

  • Since the offset for a particular DateTimeOffset is calculated and stored when a user creates (or modifies) a Campaign / Event / Task, there is the potential that changes to time zone rules could cause problems. As an example, if an event were scheduled several months in advance and changes to the daylight savings time rules for that timezone changed after the event was created, the offset for that event might not be stored correctly.
  • AllReady uses Windows timezones which are updated via regular Windows Updates. These updates happen regularly but updates are typically not as timely as the IANA timezone database which is used by the Noda Time framework
  • Both these issues could be resolved if we used the Noda time framework, stored values as local date time values and did time zone conversions on every read. // TODO: Add example if we decide this is the path forward
  • Noda Time framework currently does not support .NET Core. Version 2.0 of Noda Time does support .NET core but it is currently in Alpha. It is considered stable but we should expect some API changes.

Display Campaign / Event / Task date time values

  • The default behavior in AllReady is to display Campaign / Event / Task dates in the timezone where the campaign is located. Since the values are stored as a DateTimeOffset, this means we simply display the value using .ToString(). No additional timezone adjustments are necessary.
  • To avoid confusing, we display the TimeZone after any date/time values as shown here:
    image
  • Optionally, a user can specify their local TimeZone in their user profile. If a user has specified their local timezone, we also display the Campaign / Event / Task datetimes in their local timezone as shown here:
    image
    • TODO: // Add example code showing how this conversion happens

Date Time formats

  • AllReady currenlty only supports the en-US culture, meaning that DateTime values are always displayed in MM/dd/yyyy format. This includes the input fields where users enter DateTime values.
    From Startup.cs
 // Configure the HTTP request pipeline.
var usCultureInfo = new CultureInfo("en-US");
app.UseRequestLocalization(new RequestLocalizationOptions
{
     SupportedCultures = new List<CultureInfo>(new[] { usCultureInfo }),
     SupportedUICultures = new List<CultureInfo>(new[] { usCultureInfo })
});
  • This can be extended in the future by adding more supported cultures at startup. The challenge here however is in aligning ASP.NET's request culture (and associated DateTime format) with the momentjs DateTime format used by the eonasdan-bootstrap-datetimepicker UI component for datetime input fields.
  • Currently, the datetimepicker is setup to display in the 'L' format for Dates and 'L LT' formats for DateTime. Since we don't include any additional momentjs locales, this forces the DateTime pictures to use the MM/dd/yyyy format.
 $(".datepicker").datetimepicker({
    format: 'L',
    showClose: false,
    toolbarPlacement: 'bottom'
});

$(".datetimepicker").datetimepicker({
    format: 'L LT',
    showClose: false,
    sideBySide: true,
   toolbarPlacement: 'bottom'
});

Metadata

Metadata

Assignees

No one assigned

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions