2013-03-26 80 views
2

我想使用日曆時區來設置日期對象的時區。我正在尋找適當的技術。我們在全國有幾個基地,每個基地都有自己的日曆和日常活動日曆。我們有多個發佈到日曆的腳本。我想使用日曆的時區來設置日期對象時區,因爲用戶到處移動到不同的基地,他們的計算機可能沒有設置到正確的時區。我們希望避免錯誤的時間設置。如何使用日曆的時區設置日期對象的時區

  1. 腳本的時區應該設置爲UTC嗎?

  2. 這是我在目前我:

    function submitUiTest(e) { 
        var app = UiApp.getActiveApplication(); 
        var cal = CalendarApp.getCalendarById('calendarId'); 
        var timeZone = cal.getTimeZone(); 
    
        var ss = SpreadsheetApp.getActiveSpreadsheet(); 
        var sheet = ss.getSheetByName('Sheet1'); 
    
        var startTime = e.parameter.startDate 
        startTime.setHours(e.parameter.startHour, e.parameter.startMin, 0) 
        startTime = formatTime(startTime, timeZone); 
        Logger.log(startTime) 
    
        var endTime = e.parameter.endDate 
        endTime.setHours(e.parameter.endHour, e.parameter.endMin, 0); 
        endTime = formatTime(endTime, timeZone); 
        Logger.log(endTime) 
    
        cal.createEvent('TimeZone Test', new Date(startTime), new Date(endTime)); 
    
        ss.appendRow([startTime, endTime]); 
    
        return app; 
    } 
    
    function formatTime(time, timeZone){ 
        return Utilities.formatDate(time, (timeZone-time.getTimezoneOffset()), 'M/d/yyyy HH:mm'); 
    } 
    

編輯: 目前有3個日曆,它們不是用戶的日曆,只是每個個體空壓站創建一個單獨的日曆。空中電臺分別位於不同的時區。當這些工作人員在這些工作站工作時,他們會將日常活動發佈到日曆中,並且還有幾個用戶界面腳本,我們將該帖子發佈到相同的日曆前例如。一個飛行日誌。將日曆條目發佈到任何日曆時,時間只與在腳本上設置的時區相關,而不與日曆上的時區相關。當創建日期或時間戳記對象時,如何使用日曆本身設置的時區。

記錄不同時區日期的腳本的最佳做法是什麼? 將腳本時區設置爲UTC並執行轉換? 你用什麼來獲取用戶的時區,或者在這種情況下,我不在乎用戶的時區設置是什麼,我需要使用日曆的時區。

回答

1

好的,這裏是解決問題的方法。我可能走了出路或錯過了一些簡單的東西,但這終於像我希望的那樣工作了。隨意批評。爲簡單起見,我將webapp時區設置爲GMT-0000。

function uiTest() { 
    var app = UiApp.createApplication(); 

    var startDate = app.createDateBox().setName('startDate').setId('startDate').setWidth('75'); 
    var startHour = app.createListBox().setName('startHour').setId('startHour').setWidth('45'); 
    var startMin = app.createListBox().setName('startMin').setId('startMin').setWidth('45'); 

    var endDate = app.createDateBox().setName('endDate').setId('endDate').setWidth('75'); 
    var endHour = app.createListBox().setName('endHour').setId('endHour').setWidth('45'); 
    var endMin = app.createListBox().setName('endMin').setId('endMin').setWidth('45'); 

    for (h=0;h<24;++h){ 
    if(h<10){ 
    var hourstr='0'+h 
    }else{ 
    var hourstr=h.toString() 
    } 
    startHour.addItem(hourstr) 
    endHour.addItem(hourstr) 
    } 
    for (m=0;m<60;++m){ 
    if(m<10){ 
    var minstr='0'+m 
    }else{ 
    var minstr=m.toString() 
    } 
    startMin.addItem(minstr) 
    endMin.addItem(minstr) 
    } 


    var grid = app.createFlexTable().setId('grid'); 
    app.add(grid); 

    grid.setWidget(0, 0, app.createLabel('Start Date')); 
    grid.setWidget(1, 0, startDate); 

    grid.setWidget(0, 1, app.createLabel('Hour')); 
    grid.setWidget(1, 1, startHour); 


    grid.setWidget(0, 2, app.createLabel('Min')); 
    grid.setWidget(1, 2, startMin); 

    grid.setWidget(2, 0, app.createLabel('End Date')); 
    grid.setWidget(3, 0, endDate); 

    grid.setWidget(2, 1, app.createLabel('Hour')); 
    grid.setWidget(3, 1, endHour); 

    grid.setWidget(2, 2, app.createLabel('Min')); 
    grid.setWidget(3, 2, endMin); 



    app.add(app.createButton('Submit', app.createServerHandler('submitUiTest').addCallbackElement(grid))); 

    SpreadsheetApp.getActiveSpreadsheet().show(app); 
} 


function submitUiTest(e) { 
    var app = UiApp.getActiveApplication(); 
    var cal = CalendarApp.getCalendarById('');//Info Sys Calendar set to Central Time 
    //var cal = CalendarApp.getCalendarById('');//Fort Bliss (Mountain Time) 
    var calTimeZone = cal.getTimeZone(); 

    var ss = SpreadsheetApp.getActiveSpreadsheet(); 
    var sheet = ss.getSheetByName('Sheet1'); 


    var startTime = e.parameter.startDate 
    startTime.setHours(gasTimezoneOffset(startTime, e.parameter.startHour, calTimeZone), e.parameter.startMin, 0); 
    Logger.log('startTime: '+Utilities.formatDate(startTime, calTimeZone, 'M/d/yyyy HH:mm z')); 

    var endTime = e.parameter.endDate 
    endTime.setHours(gasTimezoneOffset(endTime, e.parameter.endHour, calTimeZone), e.parameter.endMin, 0); 
    Logger.log('endTime: '+endTime) 

    var timeStamp = Utilities.formatDate(startTime, calTimeZone, 'M/d/yyyy HH:mm z'); 

    cal.createEvent(timeStamp, new Date(startTime), new Date(endTime)); 

    ss.appendRow([startTime, endTime]); 

    return app; 
} 


function gasTimezoneOffset(date, hour, calTimeZone){ 
    var calTz = new Number(Utilities.formatDate(date, calTimeZone, 'Z').substr(1,2)); 
    var sessionTz = new Number(Utilities.formatDate(date, Session.getTimeZone(), 'Z').substr(1,2)); 

    switch (Utilities.formatDate(date, calTimeZone, 'Z').substring(0,1)){ 
    case '+': 
     var timeZoneOffset = sessionTz - calTz; 
     break; 
    case '-': 
     var timeZoneOffset = sessionTz + calTz; 
     break; 
    } 

    hour = new Number(hour); 

    return hour + timeZoneOffset; 
} 
1

編輯:我寫了一個小測試用戶界面,並在2個不同的時區運行2個日曆。 日曆事件在日曆時區中創建,用戶界面顯示用戶值。 Google會在兩個日曆中處理時區設置,並且我沒有注意到任何異常情況:按照我的意願創建的事件,即在日曆時區的用戶界面中顯示的時間。

(截屏)

enter image description here

這裏是我用於測試的代碼:

var tz = [['test_agenda(pacific Time)','test_agenda'],['testencodage(Belgium time)','testencodage']] 

function doGet() { 
    var app = UiApp.createApplication().setStyleAttribute('padding','15PX'); 
    var hpanel = app.createHorizontalPanel(); 
    var dateBox = app.createDateBox().setId('dateBox').setName('dateBox'); 
    var hour = app.createListBox(false).setId('hour').setName('hour') 
    for(h=0;h<25;++h){ 
    if(h/2==parseInt(h/2)){hour.addItem(parseInt(h/2)+':00') 
         }else{ 
          hour.addItem(parseInt(h/2)+':30') 
         } 
    } 
    var amPm = app.createListBox(false).setId('am').setName('amPm') 
    .addItem('AM').addItem('PM'); 
    var dateTimeLabel = app.createLabel('',false).setId('dateTimeLabel'); 
    var submit = app.createButton('Submit').setId('submit'); 
    var tzList = app.createListBox().setName('tzList'); 
    for(var c in tz){tzList.addItem(tz[c][0],tz[c][1])} 
    var handler1 = app.createClientHandler().validateMatches(dateBox, '2','g').forEventSource().setEnabled(false); 
    var handler2 = app.createServerHandler('createE').validateMatches(dateBox, '2','g').addCallbackElement(hpanel).addCallbackElement(tzList); 
    submit.addClickHandler(handler1).addClickHandler(handler2); 
    hpanel.add(dateBox).add(hour).add(amPm) 
    app.add(hpanel); 
    app.add(tzList).add(submit); 
    app.add(dateTimeLabel); 
    return app; 
} 

function createE(e) { 
    var app = UiApp.getActiveApplication(); 
    var date = e.parameter.dateBox; 
    var cal = CalendarApp.getCalendarsByName(e.parameter.tzList)[0] 
    var timeZone = cal.getTimeZone(); 
    var sessionTz = Session.getTimeZone() 
    Logger.log(sessionTz) 
    Logger.log(timeZone) 
    var hour = Number(e.parameter.hour.split(':')[0]); 
    var min = Number(e.parameter.hour.split(':')[1]); 
    var amPm = e.parameter.amPm; 
    if (amPm == 'PM'){hour = hour+12}; // ADD 12 HOURS TO PM HOURS, EXCEPT 12PM 
    if (hour == 24){hour = 0;amPm='AM'}; // HANDLE 12AM HOUR CORRECTLY 
    var newDate=new Date(date) 
    newDate.setHours(hour,min,0,0) 
    Logger.log('start : '+newDate) 
    var newDateString = Utilities.formatDate(newDate, sessionTz, 'MM/dd/yyyy hh:mm aaa'); 
    app.getElementById('dateTimeLabel').setText('tz = '+timeZone+' - '+newDateString); 
    Logger.log('end : '+new Date(newDate.getTime()+3600000)) 
    cal.createEvent('test Event in TZ '+timeZone, newDate, new Date(newDate.getTime()+3600000)) 

    app.getElementById('submit').setEnabled(true); 
    return app; 
} 

首評:

我開始寫評論問你一些問題,但它變得太長了...所以請把它當作評論,而不是回答;-)。 我不確定我是否理解你說'他們的計算機未設置爲正確的時區',他們的計算機的時區與他們使用Google日曆時不相關,這只是Google Cal中的參數問題。如果我明白你的目標是,如果腳本在上午8:00設置了約會,他們將在其日曆的上午8:00看到它顯示在哪裏(上午8:00在他們的「本地」時區),對吧?
所以總結一下,你是從一個地方運行這個腳本,併爲他們自己的日曆中的其他時區的人創建事件?用戶是否在不同的時區移動?這是兩個獨立的問題,並沒有一個單一的解決方案。 如果一個用戶在時區之間移動,除非他不更改GCal參數,否則所有事件都將被移位。但是如果他這樣做了,他將不會在正確的時間得到通知,並且日曆界面將會過時...所以這不是一個合理的解決方案。 我最後一個問題:當你在另一個日曆中創建一個事件(在另一個tz中),它可以是你和這個人之間的約會嗎?換句話說,對你來說是絕對重要的用例?

+0

上面編輯塞爾日,感謝您的時間。 – LennyZ71 2013-03-27 05:11:48

0

可以嘗試爲每個時區部署單獨的Web應用程序。將每個應用的時區設置爲與其鏈接的唯一日曆的時區相匹配。由於您在不同時區只有3個日曆,因此您的情況似乎有效。

3

下面是答案的修改版本,不帶UI的東西:

function gasTimezoneOffset(date, hour){ 
    var cal,calTimeZone,calTz,date,dateString,scriptTimeZone,sessionTz; 

    var testMonth = "March", 
     testDayOfMnth = "26", 
     testYr = "2016", 
     hour = "10:00", 
     timeZoneDiff = 0; 

    Logger.log("Script Time Zone: " + Session.getScriptTimeZone()); 

    dateString = testMonth + " " + testDayOfMnth + ", " + testYr; 
    Logger.log("dateString: " + dateString); 

    date = new Date(dateString); 

    cal = CalendarApp.getDefaultCalendar(); 
    calTimeZone = cal.getTimeZone(); 

    calTimeZone = Utilities.formatDate(date, calTimeZone, 'Z'); 
    scriptTimeZone = Utilities.formatDate(date, Session.getTimeZone(), 'Z'); 

    calTz = Number(calTimeZone.slice(0,3)); 
    sessionTz = Number(scriptTimeZone.slice(0,3)); 

    //If both time zones are the same sign, get the difference between the 
    //two. E.g. -4 and -2. Difference is 2 
    //if each time zone is a different sign, add the absolute values together. 
    //-4 and +1 should be 5 
    if (calTz < 0 && sessionTz > 0 || calTz > 0 && sessionTz < 0){ 
    timeZoneDiff = Math.abs(Math.abs(calTz) + Math.abs(sessionTz)); 
    } else { 
    timeZoneDiff = Math.abs(Math.abs(calTz) - Math.abs(sessionTz)); 
    }; 

    hour = Number(hour.slice(0,2));  
    return hour + timeZoneDiff; 
}; 
+0

謝謝桑迪,五,很有幫助!一個錯字:你計算timeZoneDiff,但最後加上timeZoneOffset。 – 2017-02-09 14:13:46

+0

謝謝。只是修復它。 – 2017-02-09 15:46:40

1

這裏是桑迪的代碼版本,我結束了使用,以創建一個函數,日曆對象和「腳本時間」並返回「日曆時間」:

/** 
* Given a script date object, return the time in the user's calendar 
* 
* Sandy Good's answer to this SO question: 
* 
* http://stackoverflow.com/questions/15645343/how-to-use-timezone-of-calendar-to-set-timezone-for-date-object 
* 
* @param {Date} scriptDateTime 
* @param {Calendar} calendar 
* 
* @return {Date} calendarDateTime 
*/ 

function getCalendarDateTime (scriptDateTime, calendar) { 

    Logger.log('scriptDateTime: ' + scriptDateTime) 

    var calendarTimeZoneString = calendar.getTimeZone() 
    var calendarTimeZone = Utilities.formatDate(scriptDateTime, calendarTimeZoneString, 'Z') 
    var calendarTz = Number(calendarTimeZone.slice(0,3)) 
    Logger.log('calendarTimeZone: %s (%s)', calendarTimeZoneString, calendarTz) 

    var scriptTimeZoneString = Session.getScriptTimeZone() 
    var scriptTimeZone = Utilities.formatDate(scriptDateTime, scriptTimeZoneString, 'Z') 
    var sessionTz = Number(scriptTimeZone.slice(0,3)) 
    Logger.log('scriptTimeZone: %s (%s)', scriptTimeZoneString, sessionTz) 

    // If both time zones are the same sign, get the difference between the 
    // two. E.g. -4 and -2. Difference is 2 
    // 
    // If each time zone is a different sign, add the absolute values together. 
    // -4 and +1 should be 5 

    var timeZoneDiff 

    if (calendarTz < 0 && sessionTz > 0 || calendarTz > 0 && sessionTz < 0) { 

    timeZoneDiff = Math.abs(Math.abs(calendarTz) + Math.abs(sessionTz)) 

    } else { 

    timeZoneDiff = Math.abs(Math.abs(calendarTz) - Math.abs(sessionTz)) 
    } 

    Logger.log('timeZoneDiff: ' + timeZoneDiff) 

    var scriptHour = scriptDateTime.getHours() 
    var calendarHour = scriptHour + timeZoneDiff 

    var calendarDateTime = new Date(
    scriptDateTime.getYear(), 
    scriptDateTime.getMonth(), 
    scriptDateTime.getDate(), 
    calendarHour, 
    scriptDateTime.getMinutes()) 

    Logger.log('calendarDateTime: ' + calendarDateTime) 

    return calendarDateTime 
} 

// Script is PST (GMT-8) and calendar is GMT 

function test_getCalendarDateTime() { 
    var calendar = CalendarApp.getDefaultCalendar() 
    var scriptDateTime = new Date(2017, 0, 30, 12, 0) // 2017-01-30 12:00 PST 
    var calendarDateTime = getCalendarDateTime(scriptDateTime, calendar) // 2017-01-30 20:00 PST 
}