Created
February 13, 2019 13:18
-
-
Save pavan-idapalapati/609e4a0da9d24a946265b31244058cc0 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { combineLatest as observableCombineLatest, of as observableOf, Observable } from 'rxjs'; | |
import { mergeMap, catchError, map, tap } from 'rxjs/operators'; | |
import { Injectable } from '@angular/core'; | |
import { locationService } from './location.service'; | |
import { ApiCallsService } from './apicalls.service'; | |
import * as moment from 'moment'; | |
// import 'moment-timezone'; | |
import { constants } from '../modules/utilities/constants'; | |
// import { communicationService } from './communication.service'; | |
// import { Observable, ReplaySubject, BehaviorSubject } from 'rxjs'; | |
// import { Subject } from 'rxjs/Subject'; | |
@Injectable() | |
export class dateService { | |
dateSettings: any; | |
dateAPicallData; | |
sub_dateSettings: any; | |
locationData: any; | |
moment: any; | |
locationOffsets: any = {}; | |
constructor( | |
// private communicationService : communicationService | |
private location: locationService, | |
private apiCallsService: ApiCallsService, | |
private constants: constants | |
) { | |
this.getDateSettings().subscribe(() => { | |
// | |
}); | |
this.moment = moment; | |
} | |
getDateSettings() { | |
if (!this.sub_dateSettings) { | |
this.sub_dateSettings = this.location | |
.getLocation() | |
.pipe( | |
mergeMap((data: any) => { | |
let date = new Date(); | |
let location = data.location; | |
if (location) { | |
// Get timezone considering daylight time savings | |
return this.getLocalTimeConsideringDayLightSavings({ | |
date: date, | |
latitude: location.latitude, | |
longitude: location.longitude | |
}); | |
} else { | |
return Observable.create((observer) => | |
observer.next({ | |
date: { | |
value: this.getLocalTimeWithoutConsideringDayLightSavings( | |
date | |
) | |
}, | |
useLocaltime: true | |
}) | |
); | |
} | |
}), | |
map((data: any) => { | |
this.dateSettings = data; | |
}) | |
) | |
.pipe( | |
catchError((e) => { | |
let date = new Date(); | |
this.dateSettings = { | |
date: this.getLocalTimeWithoutConsideringDayLightSavings(date), | |
useLocaltime: true | |
}; | |
return Observable.create((observer) => observer.next(this.dateSettings)); | |
}) | |
); | |
} | |
return this.sub_dateSettings; | |
} | |
convertToUTC(date: Date) { | |
let toUTCString = date.toUTCString(); | |
return this.convertToStandardServerFormat(toUTCString); | |
} | |
convertToStandardServerFormat(dateUTCString: string) {} | |
convertToLocalTime(str) { | |
let result: any = {}; | |
let isRe = /(\d{2}:\d{2} (AM|PM) .{3,4})/; | |
if (isRe.test(str)) { | |
// Sometimes from backend the time is coming in 24 hour format though the AM/PM is mentioned | |
// So, normalizing the string | |
str = str.replace(/\d{2}/, ('00' + ((+str.match(/\d{2}/)[0] % 12) + '')).slice(-2)); | |
let localTime = str.match(isRe)[1]; | |
let currentDate = new Date(); | |
let currentDateString = currentDate.toString(); | |
// let tzAbbr = this.getLocalTimezoneAbbr(currentDateString); | |
let re = /(\w{3} \w{3} \d{2} \d{4} )(\d{2}:\d{2}:\d{2} \w{3})(.+$)/; | |
let changedTimeString = currentDateString.replace(re, (a, x, y, z) => x + localTime); | |
let changedDate: any = new Date(changedTimeString); | |
let changedTime = this.getTimeFormat(changedDate); | |
let currentDay = currentDate.getDay() + 1; | |
let changedDay = changedDate.getDay() + 1; | |
result.date = changedDate; | |
result.time = changedTime; | |
result.changedStr = str.replace(/(\d{2}:\d{2} (AM|PM) .{3})/, result.time); | |
} else { | |
result.changedStr = str; | |
result.time = str; | |
result.date = new Date(); | |
} | |
return result; | |
} | |
getLocalTimezoneAbbr(dateString) { | |
let match = dateString.match(/\((.*)\)/); | |
if (match) { | |
return match[1] | |
.split(' ') | |
.map((m) => m.substring(0, 1)) | |
.join(''); | |
} | |
} | |
getTimeFormat(date) { | |
// return moment(date).tz(moment.tz.guess()).format('hh:mm A z'); | |
return moment(date).format('LT') + ' ' + this.getLocalTimezoneAbbr(date.toString()); | |
} | |
getLocal(date: Date): Observable<any> { | |
let $this = this; | |
date = $this.convertToDate(date); | |
if (date) { | |
return $this.location.getLocation().pipe( | |
mergeMap((data: any) => { | |
let location = data.location; | |
if (location) { | |
// Get timezone considering daylight time savings | |
return observableOf( | |
$this.getLocalTimeConsideringDayLightSavings({ | |
date: date, | |
latitude: location.latitude, | |
longitude: location.longitude | |
}) | |
); | |
} else { | |
// Get timezone without considering daylight time savings | |
return Observable.create((observer) => { | |
return observer.next({ | |
date: $this.getLocalTimeWithoutConsideringDayLightSavings(date) | |
}); | |
}); | |
} | |
}) | |
); | |
} else { | |
// return Observable.empty<Response>(); | |
return Observable.create((observer) => { | |
return observer.next(null); | |
}); | |
} | |
} | |
private convertToDate(rawDate) { | |
if (typeof rawDate === 'string') { | |
return new Date(rawDate); | |
} | |
return rawDate; | |
} | |
public getLocalTimeConsideringDayLightSavings(payload: any): Observable<any> { | |
let timestamp = payload.date.getTime() / 1000 + payload.date.getTimezoneOffset() * 60; | |
if (!this.dateAPicallData) { | |
this.dateAPicallData = this.getTimeBasedOnLocation(payload); | |
return this.dateAPicallData; | |
} else if (this.locationData) { | |
return this.formedLocationData({ | |
timestamp: timestamp | |
}); | |
} else { | |
// This case executes when the datesettings observable hasn't yet got response | |
// So, hold the execution till the datesettings comes up | |
return this.dateAPicallData.flatMap(() => | |
this.formedLocationData({ | |
timestamp: timestamp | |
}) | |
); | |
} | |
} | |
public getTimeBasedOnLocation(payload) { | |
payload.apiKey = 'AIzaSyATQwr7_9YNC7bzXDk7EIYzaVqGLkYyOrs'; | |
// reference from http://www.javascriptkit.com/dhtmltutors/local-time-google-time-zone-api.shtml | |
let timestamp = payload.date.getTime() / 1000 + payload.date.getTimezoneOffset() * 60; | |
let date = payload.date.toISOString(); | |
let url = `https://maps.googleapis.com/maps/api/timezone/json?location=${ | |
payload.latitude | |
},${payload.longitude}×tamp=${timestamp}&key=${payload.apiKey}`; | |
return this.apiCallsService | |
.doCall({ | |
url: url, | |
local: true, | |
noHeaders: true | |
}) | |
.pipe( | |
map((data) => { | |
data.localTime = (data.dstOffset + data.rawOffset + timestamp) * 1000; | |
data.date = new Date(data.localTime); | |
data.time = moment(data.date).format('hh:mm A z'); | |
data.useLocaltime = false; | |
let tz_abbr = ''; | |
data.timeZoneName.split(' ').map((name) => { | |
tz_abbr = tz_abbr + name.charAt(0); | |
}); | |
data.tz_abbr = tz_abbr; | |
this.locationData = data; | |
return data; | |
}) | |
) | |
.pipe( | |
catchError((e) => { | |
console.log(e + ' ' + 'timetest'); | |
return Observable.create((observer) => | |
observer.next({ | |
date: this.getLocalTimeWithoutConsideringDayLightSavings(payload.date), | |
useLocaltime: true | |
}) | |
); | |
}) | |
); | |
} | |
formedLocationData(payload) { | |
let timestamp = payload.timestamp; | |
this.locationData.localTime = | |
(this.locationData.dstOffset + this.locationData.rawOffset + timestamp) * 1000; | |
this.locationData.date = new Date(this.locationData.localTime); | |
this.locationData.useLocaltime = false; | |
let tz_abbr = ''; | |
this.locationData.timeZoneName.split(' ').map((name) => { | |
tz_abbr = tz_abbr + name.charAt(0); | |
}); | |
this.locationData.tz_abbr = tz_abbr; | |
return observableOf(this.locationData); | |
} | |
private getLocalTimeWithoutConsideringDayLightSavings(date) { | |
return new Date(date); | |
} | |
getLocalDateAndTime(utcTime, noSeconds?): any { | |
//note IE is not supporting normal date converion because of that we are passing here moment object. | |
utcTime = moment(utcTime); | |
let date = this.getLocalTimeWithoutConsideringDayLightSavings(utcTime); | |
return this.formatDate(date, noSeconds); | |
} | |
formatDate(date, noSeconds?) { | |
let localDate; | |
let localTimestamp; | |
let localTime; | |
let timestamp = date.getTime() / 1000 + date.getTimezoneOffset() * 60; | |
localDate = date; | |
localTimestamp = timestamp * 1000; | |
localTime = this.getTimeFormat(localDate); | |
let formattedDateTime = { | |
timeStamp: localTimestamp, // @WARNING: This is a UTC timestamp | |
date: localDate.toLocaleDateString(), | |
time: localTime, | |
dateObj: date | |
}; | |
return formattedDateTime; | |
} | |
public addTimeZoneTime(timeStamp, timezoneData) { | |
console.log('----------------------------------------------'); | |
console.log('patient-time offset:', timezoneData.rawOffset); | |
timeStamp = this.getLocalTimeWithoutConsideringDayLightSavings(timeStamp); | |
let result = moment(timeStamp) | |
.clone() | |
.add(timezoneData.dstOffset + timezoneData.rawOffset, 'seconds') | |
.utc() | |
.format(); | |
console.log('After adding offset', result); | |
console.log('----------------------------------------------'); | |
return result; | |
} | |
public convertToOtherTimezone(payload) { | |
// payload | |
// - dates (Array of dateStrings) | |
// - removeTimezone | |
// -- lat | |
// -- long | |
// -- offset | |
// -- system (Boolean): If this is present, none of the above are necessary | |
// - addTimezone | |
// -- lat | |
// -- long | |
// -- offset (if this is present, then lat and long are not necessary) | |
// -- system (Boolean): If this is present, none of the above are necessary | |
// | |
let this$ = this; | |
function getOffset(obj: any): Observable<any> { | |
let date: Date = new Date(); | |
if (obj.system) { | |
return observableOf(date.getTimezoneOffset() * -60); | |
} else if (obj.offset !== undefined) { | |
// To handle the case when offset is 0 | |
return observableOf(+obj.offset); | |
} else { | |
// Assuming left over is lat and long | |
// Get the offset through available lat and long | |
return this$ | |
.getTimeBasedOnLocation({ | |
date: date, | |
latitude: obj.lat, | |
longitude: obj.long | |
}) | |
.pipe( | |
mergeMap((data) => { | |
// form the offset | |
let offset = data.dstOffset + data.rawOffset; | |
this$.locationOffsets[obj.lat + obj.long] = offset; | |
return observableOf(offset); | |
}) | |
); | |
} | |
} | |
return observableCombineLatest([ | |
getOffset(payload.removeTimezone), | |
getOffset(payload.addTimezone) | |
]).pipe( | |
mergeMap(([removeTimezone, addTimezone]) => { | |
// Logic to remember: Remove the removeTimezone and Add the addTimezone | |
// This works even if the removeTimezone or addTimezone are negative values | |
var adjustOffset = -removeTimezone + addTimezone; | |
var convertedDates = payload.dates.map((date) => { | |
return moment(date) | |
.clone() | |
.add(adjustOffset, 'seconds') | |
.utc() | |
.format(); | |
}); | |
return Observable.create((obs) => obs.next(convertedDates)); | |
}) | |
); | |
} | |
/** | |
* This function is used to get the nearset 15 minutes. | |
*/ | |
public getNearestTime(date?) { | |
let condiondate = date ? new Date(date) : new Date(); | |
let result = 0; | |
let quarterTime = 15; | |
let minutes = 60; | |
let loop = minutes / quarterTime; | |
let mins = condiondate.getMinutes(); | |
if (mins % quarterTime == 0) { | |
return 0; | |
} | |
for (let i = 1; i <= loop; i++) { | |
let q_mins = i * quarterTime; | |
if (mins <= q_mins) { | |
result = q_mins - mins; | |
break; | |
} | |
} | |
return result; | |
} | |
public combineDateTime(date, time) { | |
// date = new Date(date).toLocaleDateString(); | |
// time = moment(time).format('LT'); | |
let formatedDate = date.format('MM/DD/YYYY'); | |
let dateObj = moment(new Date(formatedDate + ' ' + time)); | |
return dateObj.utc().format(); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment