服務端讀取Comment表並將結果集返回給調用者,調用者使用json.dumps將結果集轉成json字串列表返回給WEB前端。datetime欄位dumps之後變成描述日期的字串,例如'2012-4-1 12:31:01' JS無法操作這個日期,例如在該時間的基礎上加減N天或者N個小時,再比如對兩個時間進行比較。找出較早的時間,所以服務端先把datetime轉成bigint,再傳給用戶端(如果是日期是MYSQL的timestamp類型就不需要轉換,因為timestamp就是bigint)
#webpy架構
import web,time,datetime
def getList(self,db,noteId):
try:
sql = "SELECT * FROM Comment where noteId=$noteId"
rs = db.query(sql,vars=locals()).list()
for r in rs:
if r.postTime == None:
r.postTime = 0
continue
r.postTime = int(time.mktime(r.postTime.timetuple()))
d = time.localtime(r.postTime)
s = time.strftime('%Y-%m-%d %H:%M:%S', d)
return rs
except:
raise
JS的Date物件建構函數有多個重載版本,有一個版本可以根據int類型描述的時間產生Date對象(自1970年以來的微秒數,0就是1970-1-1 08:00:00 0000),不過datetime存的是1970以後的秒數,因此初始化時還需要*1000。
服務端使用的時間是標準時區,用戶端還需要根據本地時區對服務端的時間做矯正,例如北京時間的10:00提交了一個評論到伺服器,這個時間是標準時間的02:00,所以伺服器存的也是02:00,從伺服器直接讀回來就不是使用者提交時的本地時間,使用者就會覺得奇怪,因此WEB端使用JS去讀取使用者時區,根據使用者所在時區和標準時區的差來矯正結果,例如北京時間就需要在資料庫時間上+8個小時,還原到使用者提交時的本地時間。
/*
JavaScript允許通過prototype擴充標準庫對象的方法,該函數就是給Date對象增加一個format方法,該方法根據使用者的參數描述的時間格式返回一個字串
var d = new Date();
s=d.format("yyyy-MM-dd HH:mm:ss");
alert(s);
*/
Date.prototype.format=function(fmt) {
var o = {
"M+" : this.getMonth()+1, //月份
"d+" : this.getDate(), //日
"h+" : this.getHours()%12 == 0 ? 12 : this.getHours()%12, //小時
"H+" : this.getHours(), //小時
"m+" : this.getMinutes(), //分
"s+" : this.getSeconds(), //秒
"q+" : Math.floor((this.getMonth()+3)/3), //季度
"S" : this.getMilliseconds() //毫秒
};
var week = {
"0" : "\u65e5",
"1" : "\u4e00",
"2" : "\u4e8c",
"3" : "\u4e09",
"4" : "\u56db",
"5" : "\u4e94",
"6" : "\u516d"
};
if(/(y+)/.test(fmt)){
fmt=fmt.replace(RegExp.$1, (this.getFullYear()+"").substr(4 - RegExp.$1.length));
}
if(/(E+)/.test(fmt)){
fmt=fmt.replace(RegExp.$1, ((RegExp.$1.length>1) ? (RegExp.$1.length>2 ? "\u661f\u671f" : "\u5468") : "")+week[this.getDay()+""]);
}
for(var k in o){
if(new RegExp("("+ k +")").test(fmt)){
fmt = fmt.replace(RegExp.$1, (RegExp.$1.length==1) ? (o[k]) : (("00"+ o[k]).substr((""+ o[k]).length)));
}
}
return fmt;
}
function convertUTCTolocalTime(serverTime)
{
var d = new Date();
//getTimezoneOffset()可以取得JS運行環境的時區和標準時區的分鐘差
var localZone = d.getTimezoneOffset();
serverTime = parseInt(serverTime)
if(serverTime == 0)
return ""
if(localZone == 0)
{
//伺服器存的時間是秒需要*1000變成微秒
return new Date(parseInt(serverTime)*1000).format("yyyy-MM-dd HH:mm:ss")
}
if(localZone < 0)
{
localZone = Math.abs(localZone);
localTime = new Date(parseInt(serverTime)*1000).valueOf();
//標準時間 + (1000 * 60 是1分鐘 * 偏差分鐘數) == JS環境的本地時間
localTime = localTime + (1000 * 60 * localZone);
return new Date(localTime).format("yyyy-MM-dd HH:mm:ss")
}
if(localZone > 0)
{
localZone = Math.abs(localZone);
localTime = new Date(parseInt(serverTime)*1000).valueOf();
//標準時間 - (1000 * 60 是1分鐘 * 偏差分鐘數) == JS環境的本地時間
localTime = localTime - (1000 * 60 * localZone);
return new Date(localTime).format("yyyy-MM-dd HH:mm:ss")
}
return "tntime.js: convertUTCTolocalTime has error"
}