@jaricardodev/ews-javascript-api
Version:
EWS Managed api in JavaScript
558 lines (488 loc) • 19.9 kB
text/typescript
import * as moment from 'moment-timezone';
import { ArgumentOutOfRangeException, ArgumentException } from "./Exceptions/ArgumentException";
import { DayOfWeek } from "./Enumerations/DayOfWeek";
import { IOutParam } from "./Interfaces/IOutParam";
import { StringHelper } from "./ExtensionMethods";
import { TimeSpan } from "./TimeSpan";
const ticksToEpoch: number = 621355968000000000; //can be used when calculating ticks/ms from Windows date to unix date
export const msToEpoch: number = 62135596800000;
const invalidDateTimeMessage = {
"years": "year is less than 1 or greater than 9999.",
"months": "month is less than 1 or greater than 12.",
"days": "day is less than 1 or greater than the number of days in month.",
"hours": "hour is less than 0 or greater than 23.",
"minutes": "minute is less than 0 or greater than 59.",
"seconds": "second is less than 0 or greater than 59.",
"milliseconds": "millisecond is less than 0 or greater than 999."
};
export enum DateTimeKind {
Unspecified = 0,
Utc = 1,
Local = 2,
}
/**
* DateTime - basic date time based on moment.js
*/
export class DateTime {
private static readonly DaysToMonth365: number[] = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365];
private static readonly DaysToMonth366: number[] = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366];
kind: DateTimeKind = DateTimeKind.Unspecified;
get MomentDate(): moment.Moment { return this.momentDate; }
get currentUtcOffset(): number { return this.momentDate.utcOffset(); }
private get momentDate(): moment.Moment { return this.getMomentDate(); }
private getMomentDate: Function
private setMomentDate: Function
private originalDateInput: any = null;
public static get Now(): DateTime {
return new DateTime(moment());
}
public static get UtcNow(): DateTime {
return new DateTime(moment.utc());
}
get TotalMilliSeconds(): number {
return this.momentDate.valueOf()
}
constructor(ms: number);
constructor(date: DateTime);
constructor(momentInput: moment.MomentInput);
constructor(ms: number, kind: DateTimeKind);
constructor(year: number, month: number, day: number);
constructor(year: number, month: number, day: number, hour: number, minute: number, second: number);
constructor(year: number, month: number, day: number, hour: number, minute: number, second: number, millisecond: number);
constructor(year: number, month: number, day: number, hour: number, minute: number, second: number, millisecond: number, kind: DateTimeKind);
constructor(msOrDateOrMomentOrYear?: number | DateTime | moment.MomentInput,
monthOrKind?: number | DateTimeKind,
day?: number,
hour?: number,
minute?: number,
second?: number,
millisecond?: number,
kind: DateTimeKind = DateTimeKind.Unspecified) {
let argsLength = arguments.length;
let momentdate: moment.Moment = moment();
this.kind = kind;
if (argsLength === 1) {
if (msOrDateOrMomentOrYear instanceof DateTime) {
momentdate = msOrDateOrMomentOrYear.MomentDate.clone();
this.kind = msOrDateOrMomentOrYear.kind;
}
else {
momentdate = moment(msOrDateOrMomentOrYear);
this.originalDateInput = msOrDateOrMomentOrYear;
}
}
else if (argsLength === 2) {
if (monthOrKind === DateTimeKind.Utc && !(msOrDateOrMomentOrYear instanceof moment)) {
momentdate = moment.utc(<any>msOrDateOrMomentOrYear);
}
else {
momentdate = moment(<any>msOrDateOrMomentOrYear);
}
this.kind = monthOrKind;
if (this.kind === DateTimeKind.Unspecified && !(msOrDateOrMomentOrYear instanceof moment)) {
this.originalDateInput = msOrDateOrMomentOrYear;
}
}
else {
let momentInput: moment.MomentInputObject = {};
if (argsLength >= 3) {
momentInput.year = <number>msOrDateOrMomentOrYear;
momentInput.month = monthOrKind - 1;
momentInput.day = day;
}
if (argsLength >= 6) {
momentInput.hour = hour;
momentInput.minute = minute;
momentInput.second = second;
}
if (argsLength >= 7) {
momentInput.millisecond = millisecond;
}
momentdate = moment(momentInput);
}
if (momentdate && !momentdate.isValid()) {
let invalid = momentdate.invalidAt();
throw new ArgumentOutOfRangeException(momentValidity[invalid], invalidDateTimeMessage[momentValidity[invalid]]);
}
// if (momentdate.isUtc()) {
// this.kind = DateTimeKind.Utc
// }
// else if (momentdate.isLocal()) {
// this.kind = DateTimeKind.Local;
// }
this.getMomentDate = () => momentdate;
this.setMomentDate = (value) => momentdate = value;
}
Add(ts: TimeSpan, ): DateTime;
Add(quantity: number, unit: moment.unitOfTime.Base): DateTime;
Add(quantity: number | TimeSpan, unit: moment.unitOfTime.Base = "ms"): DateTime {
if (typeof quantity !== 'number') {
quantity = quantity.TotalMilliseconds;
unit = "ms"
}
var date: moment.Moment = moment(this.momentDate);
date.add(quantity, unit);
return new DateTime(date);
}
static Compare(x: DateTime, y: DateTime): number {
var diff: number = x.momentDate.diff(y.momentDate);
if (diff === 0) return 0;
if (diff < 0) return -1;
return 1;
}
CompareTo(toDate: DateTime): number {
return DateTime.Compare(this, toDate);
}
Difference(toDate: DateTime): TimeSpan {
return new TimeSpan(toDate.momentDate.diff(this.momentDate));
}
Format(formatting: string): string {
return this.momentDate.format(formatting);
}
private static getKindfromMoment(m: moment.Moment): DateTimeKind {
if (m.isUTC()) {
return DateTimeKind.Utc;
}
if (m.isLocal()) {
return DateTimeKind.Local;
}
return DateTimeKind.Unspecified;
}
static Parse(value: any, kind: DateTimeKind = DateTimeKind.Unspecified): DateTime {
let mdate = moment(value);
let tempDate: DateTime = null;
if (mdate.isValid()) {
switch (kind) {
case DateTimeKind.Local:
tempDate = new DateTime(mdate.local());
tempDate.kind = kind;
return tempDate;
case DateTimeKind.Utc:
tempDate = new DateTime(moment.utc(value));
tempDate.kind = kind;
return tempDate;
default:
tempDate = new DateTime(mdate);
tempDate.originalDateInput = value;
tempDate.kind = kind;
return tempDate;
}
}
else {
throw new ArgumentException("invalid date value");
}
}
ToISOString(): string {
return this.momentDate.toISOString();
}
toString(): string {
return this.momentDate.toString();
}
utcOffset(value: number) {
this.momentDate.utcOffset(value);
}
static DateimeStringToTimeZone(dtStr: string, zoneStr: string): DateTime {
return new DateTime(moment.tz(dtStr, zoneStr));
}
static DateTimeToXSDateTime(dateTime: DateTime): string {
var format = 'YYYY-MM-DDTHH:mm:ss.SSSZ';//using moment format for c#->"yyyy-MM-ddTHH:mm:ss.fff";
// switch (dateTime.Kind) {
// case DateTimeKind.Utc:
// format += "Z";
// break;
// case DateTimeKind.Local:
// format += "zzz";
// break;
// default:
// break;
// }
// Depending on the current culture, DateTime formatter will replace ':' with
// the DateTimeFormatInfo.TimeSeparator property which may not be ':'. Force the proper string
// to be used by using the InvariantCulture.
return dateTime.Format(format);//, CultureInfo.InvariantCulture);
}
static DateTimeToXSDate(date: DateTime): string {
var format = 'YYYY-MM-DDZ';//using moment format for c#->"yyyy-MM-dd";
// switch (date.Kind) {
// case DateTimeKind.Utc:
// format = "yyyy-MM-ddZ";
// break;
// case DateTimeKind.Unspecified:
// format = "yyyy-MM-dd";
// break;
// default: // DateTimeKind.Local is remaining
// format = "yyyy-MM-ddzzz";
// break;
// }
// Depending on the current culture, DateTime formatter will
// translate dates from one culture to another (e.g. Gregorian to Lunar). The server
// however, considers all dates to be in Gregorian, so using the InvariantCulture will
// ensure this.
return date.Format(format);//, CultureInfo.InvariantCulture);
}
static MinValue: DateTime = new DateTime('0001-01-01T00:00:00+00:00');
static MaxValue: DateTime = new DateTime("9999-12-31T23:59:59.9999999+00:00");
/* c# DateTime properties */
public get Date(): DateTime {
if (this === DateTime.MaxValue || this === DateTime.MinValue) {
return new DateTime(this.momentDate.utc().format("YYYY-MM-DD"))
}
return new DateTime(this.momentDate.format("YYYY-MM-DD"));
}
public get Day(): number {
return this.momentDate.date();
}
public get DayOfWeek(): DayOfWeek {
return this.momentDate.day();
}
public get DayOfYear(): number {
return this.momentDate.dayOfYear();
}
public get Hour(): number {
return this.momentDate.hour();
}
public get Kind(): DateTimeKind {
return this.kind;
}
public get Millisecond(): number {
return this.momentDate.millisecond();
}
public get Minute(): number {
return this.momentDate.minute();
}
public get Month(): number {
return this.momentDate.month() + 1;
}
public get Second(): number {
return this.momentDate.second();
}
// public get Ticks(): {
// return this.
// }
public get TimeOfDay(): TimeSpan {
return TimeSpan.FromMilliseconds(this.momentDate.millisecond());
}
public get Today(): DateTime {
return new DateTime(moment(this.momentDate.format("LL"), "LL"));
}
public get Year(): number {
return this.momentDate.year();
}
/* c# DateTime Methods */
//CompareTo
public AddDays(days: number): DateTime {
return this.Add(days, unitOfTime.days);
}
public AddHours(hours: number): DateTime {
return this.Add(hours, unitOfTime.hours);
}
public AddMilliseconds(ms: number): DateTime {
return this.Add(ms, unitOfTime.ms);
}
public AddMinutes(minutes: number): DateTime {
return this.Add(minutes, unitOfTime.minutes);
}
public AddMonths(months: number): DateTime {
return this.Add(months, unitOfTime.months);
}
public AddSeconds(seconds: number): DateTime {
return this.Add(seconds, unitOfTime.seconds);
}
// public AddTicks(ticks: number): DateTime {
// return this.Add(ticks, unitOfTime.);
// }
public AddYears(years: number): DateTime {
return this.Add(years, unitOfTime.years);
}
public static DaysInMonth(year: number, month: number) {
if (month < 1 || month > 12)
throw new ArgumentOutOfRangeException("month", invalidDateTimeMessage["months"]);
// IsLeapYear checks the year argument
let days: number[] = DateTime.IsLeapYear(year) ? DateTime.DaysToMonth366 : DateTime.DaysToMonth365;
return days[month] - days[month - 1];
}
Equals(value: any | DateTime): boolean {
if (value instanceof DateTime) {
return value.TotalMilliSeconds === this.TotalMilliSeconds;
}
return false;
}
public static Equals(t1: DateTime, t2: DateTime): boolean {
return t1.TotalMilliSeconds === t2.TotalMilliSeconds;
}
// FromBinary
// FromFileTime
// FromFileTimeUtc
// FromOADate
// GetHashCode
IsDaylightSavingTime(): boolean {
return this.momentDate.isDST();
}
/**
* Checks whether a given year is a leap year. This method returns true if year is a leap year, or false if not.
* @param {number} year
*/
public static IsLeapYear(year: number): boolean {
if (year < 1 || year > 9999) {
throw new ArgumentOutOfRangeException("year", invalidDateTimeMessage["years"]);
}
return year % 4 == 0 && (year % 100 != 0 || year % 400 == 0);
}
// ParseExact
public static SpecifyKind(value: DateTime, kind: DateTimeKind) {
return new DateTime(value.TotalMilliSeconds, kind);
}
Subtract(date: DateTime): TimeSpan;
Subtract(ts: TimeSpan): DateTime;
Subtract(dateTime: DateTime | TimeSpan): DateTime | TimeSpan {
if (dateTime instanceof DateTime) {
return new TimeSpan(this.TotalMilliSeconds - dateTime.TotalMilliSeconds);
}
else {
return new DateTime(this.TotalMilliSeconds - dateTime.TotalMilliseconds);
}
}
// ToBinary
// ToFileTime
// ToFileTimeUtc
ToLocalTime(): DateTime {
return new DateTime(this.momentDate.local());
}
ToLongDateString(): string {
return this.momentDate.format("dddd, MMMM D, YYYY");
}
ToLongTimeString(): string {
return this.momentDate.format("LTS");
}
// ToOADate
ToShortDateString(): string {
return this.MomentDate.format("l");
}
ToShortTimeString(): string {
return this.MomentDate.format("LT");
}
ToString(): string {
return this.toString();
}
ToUniversalTime(): DateTime {
return new DateTime(this.MomentDate.utc());
}
static TryParse(s: string | moment.MomentInput, outDate: IOutParam<DateTime>) {
try {
outDate.outValue = DateTime.Parse(s);
outDate.outValue.kind = this.getKindfromMoment(outDate.outValue.momentDate);
return true;
} catch (error) {
outDate.exception = error;
}
return false;
}
// TryParseExact
valueOf(): number {
return this.TotalMilliSeconds;
}
}
//
// Summary:
// Defines the formatting options that customize string parsing for some date and
// time parsing methods.
export enum DateTimeStyles {
//
// Summary:
// Default formatting options must be used. This value represents the default style
// for the System.DateTime.Parse(System.String), System.DateTime.ParseExact(System.String,System.String,System.IFormatProvider),
// and System.DateTime.TryParse(System.String,System.DateTime@) methods.
None = 0,
//
// Summary:
// Leading white-space characters must be ignored during parsing, except if they
// occur in the System.Globalization.DateTimeFormatInfo format patterns.
AllowLeadingWhite = 1,
//
// Summary:
// Trailing white-space characters must be ignored during parsing, except if they
// occur in the System.Globalization.DateTimeFormatInfo format patterns.
AllowTrailingWhite = 2,
/**
* Summary:
* Extra white-space characters in the middle of the string must be ignored during
* parsing, except if they occur in the System.Globalization.DateTimeFormatInfo
* format patterns.
*/
AllowInnerWhite = 4,
/**
* Summary:
* Extra white-space characters anywhere in the string must be ignored during parsing,
* except if they occur in the System.Globalization.DateTimeFormatInfo format patterns.
* This value is a combination of the System.Globalization.DateTimeStyles.AllowLeadingWhite,
* System.Globalization.DateTimeStyles.AllowTrailingWhite, and System.Globalization.DateTimeStyles.AllowInnerWhite
* values.
*/
AllowWhiteSpaces = 7,
//
// Summary:
// If the parsed string contains only the time and not the date, the parsing methods
// assume the Gregorian date with year = 1, month = 1, and day = 1. If this value
// is not used, the current date is assumed.
NoCurrentDateDefault = 8,
//
// Summary:
// Date and time are returned as a Coordinated Universal Time (UTC). If the input
// string denotes a local time, through a time zone specifier or System.Globalization.DateTimeStyles.AssumeLocal,
// the date and time are converted from the local time to UTC. If the input string
// denotes a UTC time, through a time zone specifier or System.Globalization.DateTimeStyles.AssumeUniversal,
// no conversion occurs. If the input string does not denote a local or UTC time,
// no conversion occurs and the resulting System.DateTime.Kind property is System.DateTimeKind.Unspecified.
AdjustToUniversal = 16,
//
// Summary:
// If no time zone is specified in the parsed string, the string is assumed to denote
// a local time.
AssumeLocal = 32,
//
// Summary:
// If no time zone is specified in the parsed string, the string is assumed to denote
// a UTC.
AssumeUniversal = 64,
//
// Summary:
// The System.DateTimeKind field of a date is preserved when a System.DateTime object
// is converted to a string using the "o" or "r" standard format specifier, and
// the string is then converted back to a System.DateTime object.
RoundtripKind = 128
}
export var unitOfTime = {
"year": <moment.unitOfTime.Base>"year",
"years": <moment.unitOfTime.Base>"years",
"y": <moment.unitOfTime.Base>"y",
"month": <moment.unitOfTime.Base>"month",
"months": <moment.unitOfTime.Base>"months",
"M": <moment.unitOfTime.Base>"M",
"week": <moment.unitOfTime.Base>"week",
"weeks": <moment.unitOfTime.Base>"weeks",
"w": <moment.unitOfTime.Base>"w",
"day": <moment.unitOfTime.Base>"day",
"days": <moment.unitOfTime.Base>"days",
"d": <moment.unitOfTime.Base>"d",
"hour": <moment.unitOfTime.Base>"hour",
"hours": <moment.unitOfTime.Base>"hours",
"h": <moment.unitOfTime.Base>"h",
"minute": <moment.unitOfTime.Base>"minute",
"minutes": <moment.unitOfTime.Base>"minutes",
"m": <moment.unitOfTime.Base>"m",
"second": <moment.unitOfTime.Base>"second",
"seconds": <moment.unitOfTime.Base>"seconds",
"s": <moment.unitOfTime.Base>"s",
"millisecond": <moment.unitOfTime.Base>"millisecond",
"milliseconds": <moment.unitOfTime.Base>"milliseconds",
"ms": <moment.unitOfTime.Base>"ms",
}
enum momentValidity {
years,
months,
days,
hours,
minutes,
seconds,
milliseconds,
}