Skip to content

Commit

Permalink
add fixes for timezones
Browse files Browse the repository at this point in the history
  • Loading branch information
sixlighthouses committed Aug 16, 2023
1 parent b14835b commit fa31c03
Show file tree
Hide file tree
Showing 7 changed files with 121 additions and 26 deletions.
10 changes: 5 additions & 5 deletions buildprocess/configureWebpack.js
Original file line number Diff line number Diff line change
Expand Up @@ -372,11 +372,11 @@ function configureWebpack(
]
});

// config.module.loaders.push({
// include: [path.resolve(fontAwesomeDir, 'css'), path.resolve(reactMdeDir, 'lib', 'styles', 'css')],
// test: /\.css$/,
// loaders: ['style-loader', 'css-loader']
// });
config.module.rules.push({
include: [path.resolve(terriaJSBasePath, "lib", "styles", "css")],
test: /\.css$/,
loaders: ["style-loader", "css-loader"]
});

// config.module.loaders.push({
// include: path.resolve(fontAwesomeDir, 'fonts'),
Expand Down
73 changes: 73 additions & 0 deletions lib/Core/DateUtils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import dateFormat from "dateformat";
import { JulianDate } from "terriajs-cesium";
import DiscretelyTimeVaryingMixin from "../ModelMixins/DiscretelyTimeVaryingMixin";

/**
* Returns the offset in minutes from UTC for a given timeZone string.
* @param timeZone - String in the format +/-HH:MM or +/-HH offset from UTC Zulu time.
* @returns The offset in minutes from UTC. as a number.
*/

export function getOffsetMinutes(timeZone: string): number {
// use a regex to check if timeZone is in format +/-HH:MM
const regexHHMM = new RegExp(/^([+-])(\d{2}):(\d{2})$/);
const match = timeZone.match(regexHHMM);

if (match) {
const sign = match[1] === "-" ? -1 : 1;
const hours = parseInt(match[2], 10);
const minutes = parseInt(match[3], 10);
return sign * (hours * 60 + minutes);
} else {
// use a regex to check if timeZone is in format +/-HH
const regexHH = new RegExp(/^([+-])(\d{2})$/);
const match = timeZone.match(regexHH);
if (match) {
const sign = match[1] === "-" ? -1 : 1;
const hours = parseInt(match[2], 10);
return sign * hours * 60;
} else {
return 0;
}
}
}

/**
* Returns the adjusted time for a given ctalog item. Uses the traits from
* DateTimeTraits.ts to determine how to adjust the date/time.
* timeZone trait: is in the format +/-HH:MM or +/-HH offset from UTC Zulu time.
* dateFormat trait: defines the display format of the time, see
* https://github.com/felixge/node-dateformat for explanation of available formats.
* isStaticDate: trait is a boolean that determines whether to adjust the time to the
* users local time. if true, the time is not transformed to the local time.
* @param item - DiscretelyTimeVaryingMixin.Instance being loaded into workbench.
* @returns The adjusted time as string.
*/

export function getAdjustedTime(
item: DiscretelyTimeVaryingMixin.Instance
): string {
if (!item.currentDiscreteJulianDate) {
return "";
}

let time = JulianDate.toDate(item.currentDiscreteJulianDate);

if (item.timeZone) {
const offset = getOffsetMinutes(item.timeZone);
time = JulianDate.toDate(
JulianDate.addMinutes(
item.currentDiscreteJulianDate,
offset,
new JulianDate()
)
);
}

if (item.isStaticDate) {
time = new Date(time.getTime() + time.getTimezoneOffset() * 60 * 1000);
}

const format = item.dateFormat || "isoDate";
return dateFormat(time, format);
}
15 changes: 4 additions & 11 deletions lib/ReactViews/BottomDock/Timeline/Timeline.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import dateFormat from "dateformat";
import { observer } from "mobx-react";
import PropTypes from "prop-types";
import React from "react";
Expand All @@ -8,7 +7,7 @@ import JulianDate from "terriajs-cesium/Source/Core/JulianDate";
import CommonStrata from "../../../Models/Definition/CommonStrata";
import withControlledVisibility from "../../HOCs/withControlledVisibility";
import CesiumTimeline from "./CesiumTimeline";
import { formatDateTime } from "./DateFormats";
import { getAdjustedTime } from "../../../Core/DateUtils";
import DateTimePicker from "./DateTimePicker";
import Styles from "./timeline.scss";
import TimelineControls from "./TimelineControls";
Expand Down Expand Up @@ -67,16 +66,10 @@ class Timeline extends React.Component {
}
const { t } = this.props;

const jsDate = JulianDate.toDate(catalogItem.currentTimeAsJulianDate);
const timelineStack = this.props.terria.timelineStack;
let currentTime;
if (defined(timelineStack.top) && defined(timelineStack.top.dateFormat)) {
currentTime = dateFormat(
jsDate,
this.props.terria.timelineStack.top.dateFormat
);
} else {
currentTime = formatDateTime(jsDate, this.props.locale);

if (defined(catalogItem.currentDiscreteJulianDate)) {
currentTime = getAdjustedTime(catalogItem);
}

const discreteTimes = catalogItem.discreteTimesAsSortedJulianDates;
Expand Down
11 changes: 3 additions & 8 deletions lib/ReactViews/Workbench/Controls/DateTimeSelectorSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import { GLYPHS, StyledIcon } from "../../../Styled/Icon";
import Spacing from "../../../Styled/Spacing";
import Text, { TextSpan } from "../../../Styled/Text";
import { formatDateTime } from "../../BottomDock/Timeline/DateFormats";
import { getAdjustedTime } from "../../../Core/DateUtils";
import DateTimePicker from "../../BottomDock/Timeline/DateTimePicker";

interface IState {
Expand Down Expand Up @@ -144,13 +145,7 @@ class DateTimeSelectorSection extends React.Component<IProps, IState> {
}

if (isDefined(item.currentDiscreteJulianDate)) {
const time = JulianDate.toDate(item.currentDiscreteJulianDate);
if (isDefined(item.dateFormat)) {
format = item.dateFormat;
discreteTime = dateFormat(time, item.dateFormat);
} else {
discreteTime = formatDateTime(time);
}
discreteTime = getAdjustedTime(item);
}

const attachedToTimeline = item.terria.timelineStack.contains(item);
Expand All @@ -161,7 +156,7 @@ class DateTimeSelectorSection extends React.Component<IProps, IState> {
{item.timeLabel ?? t("dateTime.selectorLabel")}
</Text>
<Spacing bottom={1} />
<Box fullWidth justifySpaceBetween styledHeight={"30px"} gap>
<Box fullWidth justifySpaceBetween gap>
<Box
backgroundColor="rgba(250, 250, 250, 0.2)"
css={`
Expand Down
30 changes: 30 additions & 0 deletions lib/Traits/TraitsClasses/DateTimeTraits.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import ModelTraits from "../ModelTraits";
import primitiveTrait from "../Decorators/primitiveTrait";

export class DateTimeTraits extends ModelTraits {
@primitiveTrait({
type: "string",
name: "Timezone",
description:
"If the DateTime attribute values do not have timezone information" +
" (e.g. 2018-01-01T00:00:00), specify the ISO timezone with offset from UTC (e.g. +10:00)"
})
timeZone?: string;

@primitiveTrait({
type: "string",
name: "Date format",
description:
"See available formats here https://github.com/felixge/node-dateformat"
})
dateFormat?: string;

@primitiveTrait({
type: "boolean",
name: "Static date",
description: "Do not transform date/time values to users local time."
})
isStaticDate?: boolean;
}

export default DateTimeTraits;
4 changes: 3 additions & 1 deletion lib/Traits/TraitsClasses/DiscretelyTimeVaryingTraits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ import primitiveTrait from "../Decorators/primitiveTrait";
import mixTraits from "../mixTraits";
import ChartTraits from "./ChartTraits";
import TimeVaryingTraits from "./TimeVaryingTraits";
import DateTimeTraits from "./DateTimeTraits";

export default class DiscretelyTimeVaryingTraits extends mixTraits(
ChartTraits,
TimeVaryingTraits
TimeVaryingTraits,
DateTimeTraits
) {
@primitiveTrait({
name: "Mapping from Continuous Time",
Expand Down
4 changes: 3 additions & 1 deletion lib/Traits/TraitsClasses/WebMapServiceCatalogItemTraits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import mixTraits from "../mixTraits";
import ModelTraits from "../ModelTraits";
import { traitClass } from "../Trait";
import CatalogMemberTraits from "./CatalogMemberTraits";
import { DateTimeTraits } from "./DateTimeTraits";
import DiffableTraits from "./DiffableTraits";
import ExportWebCoverageServiceTraits from "./ExportWebCoverageServiceTraits";
import GetCapabilitiesTraits from "./GetCapabilitiesTraits";
Expand Down Expand Up @@ -175,7 +176,8 @@ export default class WebMapServiceCatalogItemTraits extends mixTraits(
MappableTraits,
CatalogMemberTraits,
LegendOwnerTraits,
MinMaxLevelTraits
MinMaxLevelTraits,
DateTimeTraits
) {
@primitiveTrait({
type: "string",
Expand Down

0 comments on commit fa31c03

Please sign in to comment.