Skip to content

Store all timestamps as timezone-aware timestamps #20

Description

@dpfens

Stopwatch data should include timezone data, to ensure the originating timezone can be tracked. If a stopwatch has a valid timezone/timezoneOffset value, the stopwatch data will be rendered in that timezone.

Store all stopwatch values as timezone-aware dates:

class TZDate {
  private utcTimestamp: number;  // Milliseconds since Unix epoch in UTC
  private timezone: string;
  private timezoneOffset: number;

  constructor(utcTimestamp: number, timezoneOffset: number | null, timezone: string | null) {
    this.utcTimestamp = utcTimestamp;
    this.timezoneOffset = timezoneOffset || (new Date).getTimezoneOffset();
    this.timezone = timezone || Intl.DateTimeFormat().resolvedOptions().timeZone;
  }

  toOriginalDate(): Date {
    var date = new Date(this.utcTimestamp),
        utcMinutes = date.getUTCHours() * 60 + date.getUTCMinutes(),
        localMinutes = (utcMinutes + this.timezoneOffset + 1440) % 1440;
    date.setUTCHours(Math.floor(localMinutes / 60), localMinutes % 60);
    return date;
  }

  toLocalDate(): Date {
    return new Date(this.utcTimestamp);
  }

  static now(): TZDate {
    var now: number = Date.now(),
        timezoneOffset = (new Date).getTimezoneOffset(),
        timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
    return new TZDate(now, timezoneOffset, timezone);
  }
}

interface CreationModificationDates {
  readonly createdAt: TZDate;
  lastModified: TZDate | null;
}

interface StopWatchMetadata {
  readonly createdAt: TZDate;
  startedAt: TZDate | null;
  stoppedAt: TZDate | null;
  resumedAt: TZDate | null;
  resetAt: TZDate | null;
  lastModified: TZDate | null;
}

class Split {
  public value: TZDate;
  public metadata: CreationModificationDates;

  constructor(value: number, metadata: CreationModificationDates) {
    this.value = value;
    this.metadata = metadata;
  }
}

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions