bcgov / wps

Wildfire Predictive Services to support decision making in prevention, preparedness, response and recovery
Apache License 2.0
36 stars 6 forks source link

Solve time zone problems #1790

Open Sybrand opened 2 years ago

Sybrand commented 2 years ago

Describe the task We keep having issues with dates and times in frontend tickets. To solve this once and for all, create some date class that encapsulates the issues with timezones and date arithmetic.

Acceptance Criteria

Additional context

Maybe something that looks like this:

export class SmartDate {
  /**
   * I propose we use a class that looks like this for all internal represenation of dates.
   * The idea is, that when dealing with this object, you never have to worry about
   * time zones.
   * We happen to represent the date internally using the luxon DateTime object,
   * but that's none of your business.
   */
  private _date: DateTime

  private constructor(date: DateTime) {
    this._date = date
  }

  static fromISODateString(isoDate: string): SmartDate {
    /* Given a date in the format YYYY-MM-DD return a smart date object.

    How we store the object is none of your business. */

    // setZone: true is very important here. We're telling DateTime not to use the local timezone,
    // and to just stick to the offset we've given it. This helps us avoid weird bugs where
    // converting to and fro between iso strings and date objects results in date changes due
    // to timezones. (e.g. the 14th of July in PST could be the 15th of July in UTC depending on
    // the time of day.)
    return new SmartDate(DateTime.fromISO(isoDate + 'T00:00+00:00', { setZone: true }))
  }

  static fromJSDate(jsDate: Date): SmartDate {
    /* Given a JS Date object return a smart date object - we don't care what timezone
    you're in, or what time it is. If you say it's June the 5th, you'll get June the 5th
    back. We throw away the time part of the date, and we throw away the timezone part.

    What we store it as internally is none of your business. */
    return SmartDate.fromISODateString(jsDate.toISOString().substring(0, 10))
  }

  public plus(duration: DurationLike): SmartDate {
    return new SmartDate(this._date.plus(duration))
  }

  public toISODateString(): string {
    /* Return an ISO date string in the format 'YYYY-MM-DD'.
    There is no time, or zone information - you asked for a date, and that's what you get.
    You get what you get and you don't get upset!
    */
    return this._date.toISODate()
  }
}
Sybrand commented 2 years ago

Hey team! Please add your planning poker estimate with ZenHub @andrea-williams @conbrad @JulianForeman

BAAlexK commented 8 months ago

Hey team! Please add your planning poker estimate with Zenhub @brettedw @dgboss