moonfire-nvr/ui/src/lib/models/CalendarTSRange.js

242 lines
7.4 KiB
JavaScript

// vim: set et sw=2 ts=2:
//
// This file is part of Moonfire NVR, a security camera network video recorder.
// Copyright (C) 2018 The Moonfire NVR Authors
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// In addition, as a special exception, the copyright holders give
// permission to link the code of portions of this program with the
// OpenSSL library under certain conditions as described in each
// individual source file, and distribute linked combinations including
// the two.
//
// You must obey the GNU General Public License in all respects for all
// of the code used other than OpenSSL. If you modify file(s) with this
// exception, you may extend this exception to your version of the
// file(s), but you are not obligated to do so. If you do not wish to do
// so, delete this exception statement from your version. If you delete
// this exception statement from all source files in the program, then
// also delete it here.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
import Time90kParser from '../support/Time90kParser';
import TimeStamp90kFormatter from '../support/TimeStamp90kFormatter';
import Range90k from './Range90k';
/**
* Class representing a calendar timestamp range based on 90k units.
*
* A calendar timestamp differs from a Range90k in that a date string
* is involved on each end as well.
*
* The range has a start and end property (via getters) and each has three
* contained properties:
* - dateStr: string for date in ISO8601 format
* - timeStr: string for time in ISO8601 format
* - ts90k: Number for the timestamp in 90k units
*/
export default class CalendarTSRange {
/**
* Construct a range with a given timezone for display purposes.
*
* @param {String} timeZone Desired timezone, e.g. 'America/Los_Angeles'
*/
constructor(timeZone) {
this.start_ = {dateStr: null, timeStr: '', ts90k: null};
this.end_ = {dateStr: null, timeStr: '', ts90k: null};
// Don't need to keep timezone, but need parser and formatter
this.timeFormatter_ = new TimeStamp90kFormatter(timeZone);
this.timeParser_ = new Time90kParser(timeZone);
}
/**
* Determine if a valid start date string is present.
*
* @return {Boolean}
*/
hasStart() {
return this.start.dateStr !== null;
}
/**
* Determine if a valid end date string is present.
*
* @return {Boolean}
*/
hasEnd() {
return this.end.dateStr !== null;
}
/**
* Determine if a valid start and end date string is present.
*
* @return {Boolean}
*/
hasRange() {
return this.hasStart() && this.hasEnd();
}
/**
* Return the range's start component.
*
* @return {object} Object containing dateStr, timeStr, and ts90k components
*/
get start() {
return this.start_;
}
/**
* Return the range's end component.
*
* @return {object} Object containing dateStr, timeStr, and ts90k components
*/
get end() {
return this.end_;
}
/**
* Return the range's start component's ts90k property
*
* @return {object} timestamp in 90k units
*/
get startTime90k() {
return this.start.ts90k;
}
/**
* Return the range's end component's ts90k property
*
* @return {object} timestamp in 90k units
*/
get endTime90k() {
return this.end.ts90k;
}
/**
* Determine if the range has a defined start timestamp in 90k units.
*
* @return {Boolean}
*/
get hasStartTime() {
return this.startTime90k !== null;
}
/**
* Return the calendar range in terms of a range over 90k timestamps.
*
* @return {Range90k} Range object or null if don't have start and end
*/
range90k() {
return this.hasRange() ?
new Range90k(this.startTime90k, this.endTime90k) :
null;
}
/**
* Internal function to update either start or end type range component.
*
* Strings are parsed to check if they are valid. Update only takes place
* if they are. Parsing is in accordance with the installed Time90kParser
* which means:
* - HH:MM:ss:FFFFFZ format, where each component may be empty to indicate 0
* - YYYY-MM-DD format for the date
*
* NOTE: This function potentially modifies the content of the range
* argument. This is on purpose and should reflect the new range values
* upon successful parsing!
*
* @param {object} range A range component
* @param {String} dateStr Date string
* @param {String} timeStr Time string
* @param {Boolean} dateOnlyThenEndOfDay True if one should be added to date
* which is only meaningful if there
* is no time specified here, and also
* not present in the range.
* @return {Number} New timestamp if succesfully parsed, null otherwise
*/
setRangeTime_(range, dateStr, timeStr, dateOnlyThenEndOfDay) {
const newTs90k = this.timeParser_.parseDateTime90k(
dateStr,
timeStr,
dateOnlyThenEndOfDay
);
if (newTs90k !== null) {
range.dateStr = dateStr;
range.timeStr = timeStr;
range.ts90k = newTs90k;
return newTs90k;
}
return null;
}
/**
* Set start component of range from date and time strings.
*
* Uses _setRangeTime with appropriate dateOnlyThenEndOfDay value.
*
* @param {String} dateStr Date string
* @return {Number} New timestamp if succesfully parsed, null otherwise
*/
setStartDate(dateStr) {
return this.setRangeTime_(this.start_, dateStr, this.start_.timeStr, false);
}
/**
* Set time of start component of range time string.
*
* Uses _setRangeTime with appropriate dateOnlyThenEndOfDay value.
*
* @param {String} timeStr Time string
* @return {Number} New timestamp if succesfully parsed, null otherwise
*/
setStartTime(timeStr) {
return this.setRangeTime_(this.start_, this.start_.dateStr, timeStr, false);
}
/**
* Set end component of range from date and time strings.
*
* Uses _setRangeTime with appropriate addOne value.
*
* @param {String} dateStr Date string
* @return {Number} New timestamp if succesfully parsed, null otherwise
*/
setEndDate(dateStr) {
return this.setRangeTime_(this.end_, dateStr, this.end_.timeStr, true);
}
/**
* Set time of end component of range time string.
*
* Uses _setRangeTime with appropriate addOne value.
*
* @param {String} timeStr Time string
* @return {Number} New timestamp if succesfully parsed, null otherwise
*/
setEndTime(timeStr) {
return this.setRangeTime_(this.end_, this.end_.dateStr, timeStr, true);
}
/**
* Format a timestamp in 90k units in the manner consistent with
* what the parser of this module expects.
*
* @param {Number} ts90k Timestamp in 90k units
* @return {String} Formatted string
*/
formatTimeStamp90k(ts90k) {
return this.timeFormatter_.formatTimeStamp90k(ts90k);
}
}