Skip to content

Commit ac04600

Browse files
committedMay 22, 2017
added more TimeZone update. hopefully fixes most of bugs related to TimeZone. closes #140
1 parent 8e5bcc3 commit ac04600

15 files changed

+681
-199
lines changed
 

‎src/js/ComplexProperties/TimeZones/TimeZoneDefinition.ts

+125-121
Original file line numberDiff line numberDiff line change
@@ -81,79 +81,81 @@ export class TimeZoneDefinition extends ComplexProperty {
8181
standardPeriod.Name = TimeZonePeriod.StandardPeriodName;
8282
standardPeriod.Bias = new TimeSpan(-timeZoneInfo.BaseUtcOffset.TotalMilliseconds);
8383

84-
let adjustmentRules: TimeZoneInfo.AdjustmentRule[] = timeZoneInfo.GetAdjustmentRules();
84+
//ref: very complex to calculate timezone rules and transitions. it works without adding those elements as they are optional, need to find scenario where it is mandatory.
8585

86-
let transitionToStandardPeriod: TimeZoneTransition = new TimeZoneTransition(this, standardPeriod);
86+
// let adjustmentRules: TimeZoneInfo.AdjustmentRule[] = []; // = timeZoneInfo.GetAdjustmentRules();
8787

88-
if (adjustmentRules.length == 0) {
89-
this.periods.Add(standardPeriod.Id, standardPeriod);
88+
// let transitionToStandardPeriod: TimeZoneTransition = new TimeZoneTransition(this, standardPeriod);
9089

91-
// If the time zone info doesn't support Daylight Saving Time, we just need to
92-
// create one transition to one group with one transition to the standard period.
93-
let transitionGroup: TimeZoneTransitionGroup = new TimeZoneTransitionGroup(this, "0");
94-
transitionGroup.Transitions.push(transitionToStandardPeriod);
90+
// if (adjustmentRules.length == 0) {
91+
// this.periods.Add(standardPeriod.Id, standardPeriod);
9592

96-
this.transitionGroups.Add(transitionGroup.Id, transitionGroup);
93+
// // If the time zone info doesn't support Daylight Saving Time, we just need to
94+
// // create one transition to one group with one transition to the standard period.
95+
// let transitionGroup: TimeZoneTransitionGroup = new TimeZoneTransitionGroup(this, "0");
96+
// transitionGroup.Transitions.push(transitionToStandardPeriod);
9797

98-
let initialTransition: TimeZoneTransition = new TimeZoneTransition(this, transitionGroup);
98+
// this.transitionGroups.Add(transitionGroup.Id, transitionGroup);
9999

100-
this.transitions.push(initialTransition);
101-
}
102-
else {
103-
for (let i = 0; i < adjustmentRules.length; i++) {
104-
let transitionGroup: TimeZoneTransitionGroup = new TimeZoneTransitionGroup(this, this.transitionGroups.Count.toString());
105-
transitionGroup.InitializeFromAdjustmentRule(adjustmentRules[i], standardPeriod);
100+
// let initialTransition: TimeZoneTransition = new TimeZoneTransition(this, transitionGroup);
106101

107-
this.transitionGroups.Add(transitionGroup.Id, transitionGroup);
102+
// this.transitions.push(initialTransition);
103+
// }
104+
// else {
105+
// for (let i = 0; i < adjustmentRules.length; i++) {
106+
// let transitionGroup: TimeZoneTransitionGroup = new TimeZoneTransitionGroup(this, this.transitionGroups.Count.toString());
107+
// transitionGroup.InitializeFromAdjustmentRule(adjustmentRules[i], standardPeriod);
108108

109-
let transition: TimeZoneTransition;
109+
// this.transitionGroups.Add(transitionGroup.Id, transitionGroup);
110110

111-
if (i == 0) {
112-
// If the first adjustment rule's start date in not undefined (DateTime.MinValue)
113-
// we need to add a dummy group with a single, simple transition to the Standard
114-
// period and a group containing the transitions mapping to the adjustment rule.
115-
if (adjustmentRules[i].DateStart > DateTime.MinValue.Date) {
116-
let transitionToDummyGroup: TimeZoneTransition = new TimeZoneTransition(
117-
this,
118-
this.CreateTransitionGroupToPeriod(standardPeriod));
111+
// let transition: TimeZoneTransition;
119112

120-
this.transitions.push(transitionToDummyGroup);
113+
// if (i == 0) {
114+
// // If the first adjustment rule's start date in not undefined (DateTime.MinValue)
115+
// // we need to add a dummy group with a single, simple transition to the Standard
116+
// // period and a group containing the transitions mapping to the adjustment rule.
117+
// if (adjustmentRules[i].DateStart > DateTime.MinValue.Date) {
118+
// let transitionToDummyGroup: TimeZoneTransition = new TimeZoneTransition(
119+
// this,
120+
// this.CreateTransitionGroupToPeriod(standardPeriod));
121121

122-
let absoluteDateTransition: AbsoluteDateTransition = new AbsoluteDateTransition(this, transitionGroup);
123-
absoluteDateTransition.DateTime = adjustmentRules[i].DateStart;
122+
// this.transitions.push(transitionToDummyGroup);
124123

125-
transition = absoluteDateTransition;
126-
this.periods.Add(standardPeriod.Id, standardPeriod);
127-
}
128-
else {
129-
transition = new TimeZoneTransition(this, transitionGroup);
130-
}
131-
}
132-
else {
133-
let absoluteDateTransition: AbsoluteDateTransition = new AbsoluteDateTransition(this, transitionGroup);
134-
absoluteDateTransition.DateTime = adjustmentRules[i].DateStart;
124+
// let absoluteDateTransition: AbsoluteDateTransition = new AbsoluteDateTransition(this, transitionGroup);
125+
// absoluteDateTransition.DateTime = adjustmentRules[i].DateStart;
135126

136-
transition = absoluteDateTransition;
137-
}
127+
// transition = absoluteDateTransition;
128+
// this.periods.Add(standardPeriod.Id, standardPeriod);
129+
// }
130+
// else {
131+
// transition = new TimeZoneTransition(this, transitionGroup);
132+
// }
133+
// }
134+
// else {
135+
// let absoluteDateTransition: AbsoluteDateTransition = new AbsoluteDateTransition(this, transitionGroup);
136+
// absoluteDateTransition.DateTime = adjustmentRules[i].DateStart;
138137

139-
this.transitions.push(transition);
140-
}
138+
// transition = absoluteDateTransition;
139+
// }
141140

142-
// If the last adjustment rule's end date is not undefined (DateTime.MaxValue),
143-
// we need to create another absolute date transition that occurs the date after
144-
// the last rule's end date. We target this additional transition to a group that
145-
// contains a single simple transition to the Standard period.
146-
let lastAdjustmentRuleEndDate: DateTime = adjustmentRules[adjustmentRules.length - 1].DateEnd;
141+
// this.transitions.push(transition);
142+
// }
147143

148-
if (lastAdjustmentRuleEndDate < DateTime.MaxValue.Date) {
149-
let transitionToDummyGroup: AbsoluteDateTransition = new AbsoluteDateTransition(
150-
this,
151-
this.CreateTransitionGroupToPeriod(standardPeriod));
152-
transitionToDummyGroup.DateTime = lastAdjustmentRuleEndDate.AddDays(1);
144+
// // If the last adjustment rule's end date is not undefined (DateTime.MaxValue),
145+
// // we need to create another absolute date transition that occurs the date after
146+
// // the last rule's end date. We target this additional transition to a group that
147+
// // contains a single simple transition to the Standard period.
148+
// let lastAdjustmentRuleEndDate: DateTime = adjustmentRules[adjustmentRules.length - 1].DateEnd;
153149

154-
this.transitions.push(transitionToDummyGroup);
155-
}
156-
}
150+
// if (lastAdjustmentRuleEndDate < DateTime.MaxValue.Date) {
151+
// let transitionToDummyGroup: AbsoluteDateTransition = new AbsoluteDateTransition(
152+
// this,
153+
// this.CreateTransitionGroupToPeriod(standardPeriod));
154+
// transitionToDummyGroup.DateTime = lastAdjustmentRuleEndDate.AddDays(1);
155+
156+
// this.transitions.push(transitionToDummyGroup);
157+
// }
158+
// }
157159
}
158160
}
159161

@@ -287,71 +289,73 @@ export class TimeZoneDefinition extends ComplexProperty {
287289
ToTimeZoneInfo(service?: ExchangeService): TimeZoneInfo {
288290
this.Validate();
289291

290-
let result: TimeZoneInfo;
291-
292-
// Retrieve the base offset to UTC, standard and daylight display names from
293-
// the last transition group, which is the one that currently applies given that
294-
// transitions are ordered chronologically.
295-
let creationParams: TimeZoneTransitionGroup.CustomTimeZoneCreateParams =
296-
this.transitions[this.transitions.length - 1].TargetGroup.GetCustomTimeZoneCreationParams();
297-
298-
let adjustmentRules: TimeZoneInfo.AdjustmentRule[] = [];
299-
300-
let startDate: DateTime = DateTime.MinValue;
301-
let endDate: DateTime;
302-
let effectiveEndDate: DateTime;
303-
304-
for (let i = 0; i < this.transitions.length; i++) {
305-
if (i < this.transitions.length - 1) {
306-
endDate = (this.transitions[i + 1] as AbsoluteDateTransition).DateTime;
307-
effectiveEndDate = endDate.AddDays(-1);
308-
}
309-
else {
310-
endDate = DateTime.MaxValue;
311-
effectiveEndDate = endDate;
312-
}
313-
314-
// OM:1648848 Due to bad timezone data from clients the
315-
// startDate may not always come before the effectiveEndDate
316-
if (startDate < effectiveEndDate) {
317-
let adjustmentRule: TimeZoneInfo.AdjustmentRule = this.transitions[i].TargetGroup.CreateAdjustmentRule(startDate, effectiveEndDate);
318-
319-
if (adjustmentRule != null) {
320-
adjustmentRules.push(adjustmentRule);
321-
}
322-
323-
startDate = endDate;
324-
}
325-
else {
326-
// service.TraceMessage(
327-
// TraceFlags.EwsTimeZones,
328-
// string.Format(
329-
// "The startDate '{0}' is not before the effectiveEndDate '{1}'. Will skip creating adjustment rule.",
330-
// startDate,
331-
// effectiveEndDate));
332-
}
333-
}
334-
335-
if (adjustmentRules.length == 0) {
336-
// If there are no adjustment rule, the time zone does not support Daylight
337-
// saving time.
338-
result = TimeZoneInfo.CreateCustomTimeZone(
339-
this.Id,
340-
creationParams.BaseOffsetToUtc,
341-
this.Name,
342-
creationParams.StandardDisplayName);
343-
}
344-
else {
345-
result = TimeZoneInfo.CreateCustomTimeZone(
346-
this.Id,
347-
creationParams.BaseOffsetToUtc,
348-
this.Name,
349-
creationParams.StandardDisplayName,
350-
creationParams.DaylightDisplayName,
351-
adjustmentRules);
352-
}
353-
354-
return result;
292+
return TimeZoneInfo.CreateFromTimeZoneName(this.Id);
293+
//ref: skipped creation based on server data, directly creating using TimeZone Mapping data. complex to translate Windows TimeZoneInfo subclasses to javascript.
294+
// let result: TimeZoneInfo;
295+
296+
// // Retrieve the base offset to UTC, standard and daylight display names from
297+
// // the last transition group, which is the one that currently applies given that
298+
// // transitions are ordered chronologically.
299+
// let creationParams: TimeZoneTransitionGroup.CustomTimeZoneCreateParams =
300+
// this.transitions[this.transitions.length - 1].TargetGroup.GetCustomTimeZoneCreationParams();
301+
302+
// let adjustmentRules: TimeZoneInfo.AdjustmentRule[] = [];
303+
304+
// let startDate: DateTime = DateTime.MinValue;
305+
// let endDate: DateTime;
306+
// let effectiveEndDate: DateTime;
307+
308+
// for (let i = 0; i < this.transitions.length; i++) {
309+
// if (i < this.transitions.length - 1) {
310+
// endDate = (this.transitions[i + 1] as AbsoluteDateTransition).DateTime;
311+
// effectiveEndDate = endDate.AddDays(-1);
312+
// }
313+
// else {
314+
// endDate = DateTime.MaxValue;
315+
// effectiveEndDate = endDate;
316+
// }
317+
318+
// // OM:1648848 Due to bad timezone data from clients the
319+
// // startDate may not always come before the effectiveEndDate
320+
// if (startDate < effectiveEndDate) {
321+
// let adjustmentRule: TimeZoneInfo.AdjustmentRule = this.transitions[i].TargetGroup.CreateAdjustmentRule(startDate, effectiveEndDate);
322+
323+
// if (adjustmentRule != null) {
324+
// adjustmentRules.push(adjustmentRule);
325+
// }
326+
327+
// startDate = endDate;
328+
// }
329+
// else {
330+
// // service.TraceMessage(
331+
// // TraceFlags.EwsTimeZones,
332+
// // string.Format(
333+
// // "The startDate '{0}' is not before the effectiveEndDate '{1}'. Will skip creating adjustment rule.",
334+
// // startDate,
335+
// // effectiveEndDate));
336+
// }
337+
// }
338+
339+
// if (adjustmentRules.length == 0) {
340+
// // If there are no adjustment rule, the time zone does not support Daylight
341+
// // saving time.
342+
// result = TimeZoneInfo.CreateCustomTimeZone(
343+
// this.Id,
344+
// creationParams.BaseOffsetToUtc,
345+
// this.Name,
346+
// creationParams.StandardDisplayName);
347+
// }
348+
// else {
349+
// result = TimeZoneInfo.CreateCustomTimeZone(
350+
// this.Id,
351+
// creationParams.BaseOffsetToUtc,
352+
// this.Name,
353+
// creationParams.StandardDisplayName,
354+
// creationParams.DaylightDisplayName,
355+
// adjustmentRules);
356+
// }
357+
358+
// return result;
355359
}
356360

357361
/**

‎src/js/Core/EwsLogging.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import {StringHelper} from "../ExtensionMethods";
1+
import { StringHelper } from "../ExtensionMethods";
22
declare var window: any;
33
var isNode = (typeof window === 'undefined')
44
var util: any = undefined;
@@ -17,8 +17,8 @@ else {
1717

1818
export class EwsLogging {
1919
static DebugLogEnabled: boolean = true;
20-
static Assert(condition: boolean, caller: string, message: string): void {
21-
if (this.DebugLogEnabled && !condition)
20+
static Assert(condition: boolean, caller: string, message: string, always: boolean = false): void {
21+
if ((this.DebugLogEnabled || always) && !condition)
2222
console.log(StringHelper.Format("[{0}] {1}", caller, message));
2323
}
2424

‎src/js/Core/EwsUtilities.ts

+8-5
Original file line numberDiff line numberDiff line change
@@ -465,22 +465,25 @@ export class EwsUtilities {
465465
// }
466466
}
467467
//static GetSimplifiedTypeName(typeName: string): string{ throw new Error("EwsUtilities.ts - static GetSimplifiedTypeName : Not implemented.");}
468-
static IsLocalTimeZone(timeZone: TimeZoneInfo): boolean { return TimeZoneInfo.IsLocalTimeZone(timeZone); }
468+
static IsLocalTimeZone(timeZone: TimeZoneInfo): boolean {
469+
return (TimeZoneInfo.Local == timeZone) || (TimeZoneInfo.Local.Id == timeZone.Id && TimeZoneInfo.Local.HasSameRules(timeZone));
470+
}
469471
//static Parse(value: string): any{ throw new Error("EwsUtilities.ts - static Parse : Not implemented.");}
470472
static ParseEnum(value: string, ewsenum): any { throw new Error("EwsUtilities.ts - static Parse : Not implemented."); }
471473
static ParseAsUnbiasedDatetimescopedToServicetimeZone(dateString: string, service: ExchangeService): DateTime {
472474
// Convert the element's value to a DateTime with no adjustment.
473-
var tempDate: DateTime = DateTime.Parse(dateString + "Z");
475+
//var tempDate: DateTime = DateTime.Parse(dateString + "Z");
474476

475477
// Set the kind according to the service's time zone
476478
if (service.TimeZone == TimeZoneInfo.Utc) {
477-
return new DateTime(tempDate.TotalMilliSeconds, DateTimeKind.Utc);
479+
return DateTime.Parse(dateString, DateTimeKind.Utc);
478480
}
479481
else if (EwsUtilities.IsLocalTimeZone(service.TimeZone)) {
480-
return new DateTime(tempDate.TotalMilliSeconds, DateTimeKind.Local);
482+
return DateTime.Parse(dateString, DateTimeKind.Local);
481483
}
482484
else {
483-
return new DateTime(tempDate.TotalMilliSeconds, DateTimeKind.Unspecified);
485+
return DateTime.DateimeStringToTimeZone(dateString, service.TimeZone.IanaId);
486+
//return DateTime.Parse(dateString, DateTimeKind.Unspecified);
484487
}
485488
}
486489
static ParseEnumValueList<T>(list: any[], value: string, separators: string, enumType: any): void {

‎src/js/Core/ExchangeService.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -260,7 +260,7 @@ export class ExchangeService extends ExchangeServiceBase {
260260
PreferredCulture: any = null;//System.Globalization.CultureInfo;
261261
DateTimePrecision: DateTimePrecision = DateTimePrecision.Default;
262262
FileAttachmentContentHandler: IFileAttachmentContentHandler = null;
263-
get TimeZone(): TimeZoneInfo {// System.TimeZoneInfo;
263+
get TimeZone(): TimeZoneInfo {
264264
return this.timeZone;
265265
}
266266
get UnifiedMessaging(): UnifiedMessaging {

‎src/js/Core/ExchangeServiceBase.ts

+6-3
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ import { Uri } from "../Uri";
2121
import { XHRFactory } from "../XHRFactory";
2222

2323
export class ExchangeServiceBase {
24-
24+
2525
static AccountIsLocked: any /*System.Net.systemnet.HttpStatusCode*/ = 456;
2626

2727
AcceptGzipEncoding: boolean;
@@ -41,7 +41,9 @@ export class ExchangeServiceBase {
4141
static SessionKey: any[];//System.Byte[];
4242
SuppressXmlVersionHeader: boolean;
4343
Timeout: number;
44-
get TimeZone(): TimeZoneInfo { return this.timeZone; }//System.TimeZoneInfo;
44+
get TimeZone(): TimeZoneInfo {
45+
return this.timeZone;
46+
}
4547
get TimeZoneDefinition(): TimeZoneDefinition {
4648
if (this.timeZoneDefinition == null) {
4749
this.timeZoneDefinition = new TimeZoneDefinition(this.TimeZone);
@@ -72,7 +74,8 @@ export class ExchangeServiceBase {
7274
private sendClientLatencies: boolean;
7375
private serverInfo: ExchangeServerInfo;
7476
private timeout: number;
75-
protected timeZone: TimeZoneInfo = TimeZoneInfo.Utc;//System.TimeZoneInfo;//ref: switching to utc instead of local in c# version.
77+
protected timeZone: TimeZoneInfo = TimeZoneInfo.Local;
78+
7679
private timeZoneDefinition: TimeZoneDefinition;
7780
private traceEnabled: boolean;
7881
private traceFlags: TraceFlags;

0 commit comments

Comments
 (0)
Please sign in to comment.