JavaScript 時間與日期處理實戰:你肯定被坑過

標準時間

GMT即「格林威治標準時間」(Greenwich Mean Time,簡稱G.M.T.),指位於英國倫敦郊區的×××格林威治天文臺的標準時間,因爲本初子午線被定義爲通過那裏的經線。然而由於地球的不規則自轉,導致GMT時間有誤差,因此目前已不被當作標準時間使用。UTC是主要的世界時間標準,是經過平均太陽時(以格林威治時間GMT爲準)、地軸運動修正後的新時標以及以「秒」爲單位的國際原子時所綜合精算而成的時間。UTC比GMT來得更加精準。其誤差值必須保持在0.9秒以內,若大於0.9秒則由位於巴黎的國際地球自轉事務中央局發佈閏秒,使UTC與地球自轉週期一致。不過日常使用中,GMT與UTC的功能與度是沒有差別的。協調世界時區會使用“Z”來表示。而在航空上,所有使用的時間劃一規定是協調世界時。而且Z在無線電中應讀作“Zulu”(可參見北約音標字母),協調世界時也會被稱爲“Zulu time”。

TimeZone&UTC Offsets:時區與偏移

人們經常會把時區與UTC偏移量搞混,UTC偏移量代表了某個具體的時間值與UTC時間之間的差異,通常用HH:mm形式表述。而TimeZone則表示某個地理區域,某個TimeZone中往往會包含多個偏移量,而多個時區可能在一年的某些時間有相同的偏移量。譬如America/Chicago, America/Denver, 以及 America/Belize在一年中不同的時間都會包含 -06:00 這個偏移。

時間戳

Unix時間戳表示當前時間到1970年1月1日00:00:00 UTC對應的秒數。注意,JavaScript內的時間戳指的是當前時間到1970年1月1日00:00:00 UTC對應的毫秒數,和unix時間戳不是一個概念,後者表示秒數,差了1000倍。

時間數字字符串格式

RFC2822

JavaScript

YYYY/MM/DD HH:MM:SS ± timezone(時區用4位數字表示)
// eg 1992/02/12 12:23:22+0800

ISO 8601

國際標準化組織的國際標準ISO 8601是日期和時間的表示方法,全稱爲《數據存儲和交換形式·信息交換·日期和時間的表示方法》。目前新爲第三版ISO8601:2004,版爲ISO8601:1988,第二版爲ISO8601:2000。年由4位數組成,以公曆公元1年爲0001年,以公元前1年爲0000年,公元前2年爲-0001年,其他以此類推。應用其他紀年法要換算成公曆,但如果發送和接受信息的雙方有共同一致同意的其他紀年法,可以自行應用。

JavaScript

YYYY-MM-DDThh:mm:ss ± timezone(時區用HH:MM表示)
1997-07-16T08:20:30Z
// “Z”表示UTC標準時區,即"00:00",所以這裏表示零時區的1997年7月16日08時20分30秒
//轉換成位於東八區的北京時間則爲1997年7月17日16時20分30秒
1997-07-16T19:20:30+01:00
// 表示東一區的1997年7月16日19時20秒30分,轉換成UTC標準時間的話是1997-07-16T18:20:30Z

Reference

JS原生Date類型方法的一些冷知識
阮一峯 JavaScript標準參考教程 Date對象
Date

JavaScript爲我們提供了不是很好用的Date對象作爲時間日期對象,Date()直接返回當前時間字符串,不管參數是number還是任何string。而new Date()則是會根據參數來返回對應的值,無參數的時候,返回當前時間的字符串形式;有參數的時候返回參數所對應時間的字符串。new Date()對參數不管是格式還是內容都要求,且只返回字符串,標準的構造Date對象的方法有:

JavaScript

// 不帶new操作符,像一個函數一樣調用。它將忽略所有傳入的參數,並返回當前日期和時間的一個字符串表示。
new Date();
// 可接受一個數字參數,該參數表示設定時間與1970年1月1日0點之間的毫秒數。
new Date(value);
// 可接受一個字符串參數,參數形式類似於Date.parse()方法。但parse()方法返回的是一個數字,而Date()函數返回的是一個對象。
new Date(dateString);
// 可接受參數形式類似於Date.UTC()方法的參數,但Date.UTC()方法返回是一個毫秒數,且是UTC時間,而Date()函數返回是一個對象,且是本地時間。
new Date(year, month[, day[, hour[, minutes[, seconds[, milliseconds]]]]]);

year:四位年份,如果寫成兩位數,則加上1900
month:表示月份,0表示一月,11表示12月
date:表示日期,1到31
hour:表示小時,0到23
minute:表示分鐘,0到59
second:表示秒鐘,0到59
ms:表示毫秒,0到999
這裏需要注意的是,月份month參數,其計數方式從0開始,而天day參數,其計數方式從1開始。

JavaScript

new Date();
//Fri Aug 21 2015 15:51:55 GMT+0800 (中國標準時間)
new Date(1293879600000);
new Date('2011-01-01T11:00:00')
new Date('2011/01/01 11:00:00')
new Date(2011,0,1,11,0,0)
new Date('jan 01 2011,11 11:00:00')
new Date('Sat Jan 01 2011 11:00:00')
//Sat Jan 01 2011 11:00:00 GMT+0800 (中國標準時間)
new Date('sss');
new Date('2011/01/01T11:00:00');
new Date('2011-01-01-11:00:00')
new Date('1293879600000');
//Invalid Date
new Date('2011-01-01T11:00:00')-new Date('1992/02/11 12:00:12')
//596069988000
Parse:解析

TimeStamp:時間戳

如果需要從當前的時間對象獲取其相應的時間戳,我們可以使用getTime或者valueOf(),返回距離1970年1月1日0點的毫秒數:

JavaScript

var date1 = new Date(2007,0,1);
var date2 = new Date(2007,1,1);
console.log(date1 > date2);//false
console.log(date1 < date2);//true
// ECMAScript5新增了now()方法,該方法返回當前時間距離1970年1月1日0點UTC的毫秒數。該方法不支持傳遞參數
Date.now = function(){
return (new Date()).getTime()
// ECMAScript5新增了now()方法,該方法返回當前時間距離1970年1月1日0點UTC的毫秒數。該方法不支持傳遞參數
Date.now = function(){
return (new Date()).getTime()
}
另外Date對象還有一個靜態方法同樣返回給定日期的毫秒數。但其參數並不是一個字符串,而是分別代表年、月、日、時、分、秒、毫秒的數字參數:

JavaScript

console.log(Date.UTC(1970));//NaN
console.log(Date.UTC(1970,0));//0
console.log(Date.UTC(1970,0,2));//86400000
console.log(Date.UTC(1970,0,1,1));//3600000
console.log(Date.UTC(1970,0,1,1,59));//714000
console.log(Date.UTC(1970,0,1,1,59,30));//717000
還是需要強調下,JavaScript內的時間戳指的是當前時間到1970年1月1日00:00:00 UTC對應的毫秒數,和unix時間戳不是一個概念,後者表示秒數,差了1000倍。new Date(timestamp)中的時間戳必須是number格式,string會返回Invalid Date。所以比如new Date('11111111')這種寫法是錯的。

DateTimeString:時間日期字符串

JavaScript原生Date對於時間字符串的解析真的是槽點滿滿,假設我們希望以DD/MM/YYYY的格式進行解析,那麼它是無法識別的:

JavaScript

var a = new Date('01/12/2016'); //December 1 2016 in DD/MM/YYYY format
//"Tue Jan 12 2016 00:00:00 GMT-0600 (Central Standard Time)"
1
2
var a = new Date('01/12/2016'); //December 1 2016 in DD/MM/YYYY format
//"Tue Jan 12 2016 00:00:00 GMT-0600 (Central Standard Time)"
另外,在ES5的標準中,其對ISO 8601標準的字符串進行了一個神奇的斷言:所有沒有提供時區的字符串默認爲標準時區。換言之,你會發現你解析出來的時間和你預期中的不一樣,而且它打印的時候是按照本地時區又進行了轉換:

JavaScript

//US local format
var a = new Date('1/1/2016');
//"Fri Jan 01 2016 00:00:00 GMT-0600 (Central Standard Time)"

//ISO 8601
var a = new Date('2016-01-01');
//"Thu Dec 31 2015 18:00:00 GMT-0600 (Central Standard Time)"
ES 2015標準中則是修復了該Bug,不過還是會讓人覺得頭大,畢竟你不知道你代碼的終運行環境會是ES5還是ES6。Date對象也有一個parse方法,用於解析一個日期字符串,參數是一個包含待解析的日期和時間的字符串,返回從1970年1月1日0點到給定日期的毫秒數。該方法會根據日期時間字符串格式規則來解析字符串的格式,除了標準格式外,以下格式也支持。如果字符串無法識別,將返回NaN。

‘月/日/年’ 如6/13/2004
‘月 日,年’ 如January 12,2004或Jan 12,2004
‘星期 月 日 年 時:分:秒 時區’ Tue May 25 2004 00:00:00 GMT-0700
JavaScript

console.log(Date.parse('6/13/2004'));//1087056000000
console.log(Date.parse('January 12,2004'));//1073836800000
console.log(Date.parse('Tue May 25 2004 00:00:00 GMT-0700'));//1085468400000
console.log(Date.parse('2004-05-25T00:00:00'));//1085443200000
console.log(Date.parse('2016'));//1451606400000
console.log(Date.parse('T00:00:00'));//NaN
console.log(Date.parse());//NaN
在ECMAScript5中,如果使用標準的日期時間字符串格式規則的字符串中,數學前有前置0,則會解析爲UTC時間,時間沒有前置0,則會解析爲本地時間。其他情況一般都會解析爲本地時間

JavaScript

console.log(Date.parse('7/12/2016'));//1468252800000
console.log(Date.parse('2016-7-12'));//1468252800000
console.log(Date.parse('2016-07-12'));//1468281600000
Manipulate:時間對象操作

Get&Set

Date對象提供了一系列get*方法,用來獲取實例對象某個方面的值。具體的Get函數列表詳見附錄:

JavaScript

var d = new Date('January 6, 2013');

d.getDate() // 6
d.getMonth() // 0
d.getYear() // 113
d.getFullYear() // 2013
d.getTimezoneOffset() // -480
同樣的,Date對象還提供了一系列的Set方法:

JavaScript

var d1 = new Date('January 6, 2013');

d1.setDate(32) // 1359648000000
d1 // Fri Feb 01 2013 00:00:00 GMT+0800 (CST)

var d2 = new Date ('January 6, 2013');

d.setDate(-1) // 1356796800000
d // Sun Dec 30 2012 00:00:00 GMT+0800 (CST)

我們可以巧用Set方法的特性,set*方法的參數都會自動折算。以setDate爲例,如果參數超過當月的大天數,則向下一個月順延,如果參數是負數,表示從上個月的後一天開始減去的天數。

JavaScript

var d1 = new Date('January 6, 2013');

d1.setDate(32) // 1359648000000
d1 // Fri Feb 01 2013 00:00:00 GMT+0800 (CST)

var d2 = new Date ('January 6, 2013');

d.setDate(-1) // 1356796800000
d // Sun Dec 30 2012 00:00:00 GMT+0800 (CST)

var d = new Date();

// 將日期向後推1000天
d.setDate( d.getDate() + 1000 );

// 將時間設爲6小時後
d.setHours(d.getHours() + 6);

// 將年份設爲去年
d.setFullYear(d.getFullYear() - 1);

類型轉換時,Date對象的實例如果轉爲數值,則等於對應的毫秒數;如果轉爲字符串,則等於對應的日期字符串。所以,兩個日期對象進行減法運算,返回的就是它們間隔的毫秒數;進行加法運算,返回的就是連接後的兩個字符串。

JavaScript

var d1 = new Date(2000, 2, 1);

var d2 = new Date(2000, 3, 1);

d2 - d1
// 2678400000
d2 + d1
// "Sat Apr 01 2000 00:00:00 GMT+0800 (CST)Wed Mar 01 2000 00:00:00 GMT+0800 (CST)"

Display:時間展示

Format:格式化

Date對象提供了一系列的to*方法來支持從Date對象轉化爲字符串,具體的函數列表詳見附錄:

JavaScript

var d = new Date(2013, 0, 1);

d.toString()
// "Tue Jan 01 2013 00:00:00 GMT+0800 (CST)"

d.toUTCString()
// "Mon, 31 Dec 2012 16:00:00 GMT"

d.toISOString()
// "2012-12-31T16:00:00.000Z"

d.toJSON()
// "2012-12-31T16:00:00.000Z"

d.toDateString() // "Tue Jan 01 2013"

d.toTimeString() // "00:00:00 GMT+0800 (CST)"

d.toLocaleDateString()
// 中文版瀏覽器爲"2013年1月1日"
// 英文版瀏覽器爲"1/1/2013"

d.toLocaleTimeString()
// 中文版瀏覽器爲"上午12:00:00"
Durations:時長

JavaScript

const nMS = 1320; //以毫秒單位表示的差值時間
var nD = Math.floor(nMS/(1000 60 60 24));
var nH = Math.floor(nMS/(1000
6060)) % 24;
var nM = Math.floor(nMS/(1000
60)) % 60;
var nS = Math.floor(nMS/1000) % 60;
i18n:國際化

瀏覽器獲取當前用戶所在的時區等信息只和系統的日期和時間設置裏的時區以及時間有關。區域和語言設置影響的是瀏覽器默認時間函數(Date.prototype.toLocaleString等)顯示的格式,不會對時區等有影響。Date有個Date.prototype.toLocaleString()方法可以將時間字符串返回用戶本地字符串格式,這個方法還有兩個子方法Date.prototype.toLocaleDateString和Date.prototype.toLocaleTimeString,這兩個方法返回值分別表示日期和時間,加一起就是Date.prototype.toLocaleString的結果。這個方法的默認參數會對時間字符串做一次轉換,將其轉換成用戶當前所在時區的時間,並按照對應的系統設置時間格式返回字符串結果。然而不同瀏覽器對用戶本地所使用的語言格式的判斷依據是不同的。

IE:獲取系統當前的區域和語言-格式中設置的格式,依照其對應的格式來顯示當前時間結果;IE瀏覽器實時查詢該系統設置(即你在瀏覽器窗口打開後去更改系統設置也會引起返回格式變化)。假設系統語言爲 ja-JP,系統unicode語言爲zh-CN日期格式爲nl-NL,瀏覽器語言設置(accept-language)爲de,瀏覽器界面語言爲en-US(其他條件不變,瀏覽器界面語言改爲zh-CN的時候結果也是一樣),
JavaScript

window.navigator.language
//"nl-NL"
window.navigator.systemLanguage
//"zh-CN"(設置中的非unicode程序所使用語言選項)
window.navigator.userLanguage
//"nl-NL"
window.navigator.browserLanguage
//"ja-JP"(系統菜單界面語言)
window.navigator.languages
//undefined
FF:獲取方式和結果與IE瀏覽器相同,區別在於FF只會在瀏覽器進程次啓動的時候獲取一次系統設置,中間不管怎麼系統設置怎麼變化,FF都無法獲取到當前系統設置。除非重啓FF瀏覽器。當瀏覽器界面語言爲zh-CN,accept-language位爲en-US的時候:
JavaScript

window.navigator.language
//'en-US'
window.navigator.languages
//["en-US", "zh-CN", "de", "zh", "en"]
//當界面語言改爲"en-US",accept-language位爲zh-CN的時候
window.navigator.language
//'zh-CN'(accept-language選值)
window.navigator.languages
//["zh-CN", "de", "zh", "en-US", "en"]

Chrome:獲取方式和以上兩個都不同。chrome無視系統的區域和語言-格式格式,只依照自己瀏覽器的界面設置的菜單語言來處理。(比如英文界面則按系統’en-US’格式返回字符串,中文界面則按系統’zh-CN’格式返回結果)。當瀏覽器界面語言爲zh-CN,accept-language位爲en-US的時候:
JavaScript

window.navigator.language
//'zh-CN'
window.navigator.languages
//["en-US", "en", "zh-CN", "zh", "ja", "zh-TW", "de-LI", "de", "pl"]
//當界面語言改爲"en-US"時
window.navigator.language
//'en-US'(瀏覽器界面語言)

//'en-US'(瀏覽器界面語言)
Calendar:日曆操作

Moment.js
Moment.js爲JavaScript Date對象提供了封裝與統一好的API接口,並且提供了更多的功能。先需要了解的是,Moment提供的moment對象是可變的,即當我們對該對象執行類似於增減或者設置的時候,其對象本身的值會發生變化,譬如下面這段代碼:

JavaScript

var a = moment('2016-01-01');
var b = a.add(1, 'week');
a.format();
"2016-01-08T00:00:00-06:00"

而如果我們不希望改變原有的值,特別是在需要創建多個時間日期對象的時候,我們可以利用clone方法:

JavaScript

var a = moment('2016-01-01');
var b = a.clone().add(1, 'week');
a.format();
"2016-01-01T00:00:00-06:00"

筆者是習慣在Webpack中進行打包,類似於Node下的安裝方式:

JavaScript

//安裝
npm install moment
//使用
var moment = require('moment');
moment().format();

如果你需要引入某個語言包,那麼可以用如下方式:

JavaScript

var moment = require('moment');
require('moment/locale/cs');
console.log(moment.locale()); // cs

TimeStamp

JavaScript

//毫秒
var day = moment(1318781876406);
//秒
var day = moment.unix(1318781876);

JavaScript

moment("2010-10-20 4:30", "YYYY-MM-DD HH:mm"); // parsed as 4:30 local time
moment("2010-10-20 4:30 +0000", "YYYY-MM-DD HH:mm Z"); // parsed as 4:30 UTC

moment("2010 13", "YYYY MM").isValid(); // false (not a real month)
moment("2010 11 31", "YYYY MM DD").isValid(); // false (not a real day)
moment("2010 2 29", "YYYY MM DD").isValid(); // false (not a leap year)
moment("2010 notamonth 29", "YYYY MMM DD").isValid(); // false (not a real month name)
Manipulate

Get/Set

JavaScript

moment().seconds(30) === new Date().setSeconds(30);
moment().seconds() === new Date().getSeconds();

moment().get('year');
moment().get('month'); // 0 to 11
moment().get('date');
moment().get('hour');
moment().get('minute');
moment().get('second');
moment().get('millisecond');
JavaScript

moment().set('year', 2013);
moment().set('month', 3); // April
moment().set('date', 1);
moment().set('hour', 13);
moment().set('minute', 20);
moment().set('second', 30);
moment().set('millisecond', 123);

moment().set({'year': 2013, 'month': 3});
Add&Subtract

JavaScript

moment().add(Number, String);
moment().add(Duration);
moment().add(Object);

moment().add(7, 'days');

moment().subtract(Number, String);
moment().subtract(Duration);
moment().subtract(Object);

moment().subtract(7, 'days');
Comparison

JavaScript

moment().isBefore(Moment|String|Number|Date|Array);
moment().isBefore(Moment|String|Number|Date|Array, String);

moment('2010-10-20').isBefore('2010-12-31', 'year'); // false
moment('2010-10-20').isBefore('2011-01-01', 'year'); // true

Diff

JavaScript

moment().diff(Moment|String|Number|Date|Array);
moment().diff(Moment|String|Number|Date|Array, String);
moment().diff(Moment|String|Number|Date|Array, String, Boolean);

var a = moment([2007, 0, 29]);
var b = moment([2007, 0, 28]);
a.diff(b, 'days') // 1

Display

Format

JavaScript

moment().format(); // "2014-09-08T08:02:17-05:00" (ISO 8601)
moment().format("dddd, MMMM Do YYYY, h:mm:ss a"); // "Sunday, February 14th 2010, 3:25:50 pm"
moment().format("ddd, hA"); // "Sun, 3PM"
moment('gibberish').format('YYYY MM DD'); // "Invalid date"

JavaScript

moment([2007, 0, 29]).fromNow(); // 4 years ago
moment([2007, 0, 29]).fromNow(true); // 4 years

Duration

JavaScript

moment.duration(1, "minutes").humanize(); // a minute
moment.duration(2, "minutes").humanize(); // 2 minutes
moment.duration(24, "hours").humanize(); // a day

i18n

附錄

Date APIs

Date 對象用於處理日期和時間。其核心的方法如下列表所示:

方法 描述
Date() 返回當日的日期和時間。
getDate() 從 Date 對象返回一個月中的某一天 (1 ~ 31)。
getDay() 從 Date 對象返回一週中的某一天 (0 ~ 6)。
getMonth() 從 Date 對象返回月份 (0 ~ 11)。
getFullYear() 從 Date 對象以四位數字返回年份。
getYear() 請使用 getFullYear() 方法代替。
getHours() 返回 Date 對象的小時 (0 ~ 23)。
getMinutes() 返回 Date 對象的分鐘 (0 ~ 59)。
getSeconds() 返回 Date 對象的秒數 (0 ~ 59)。
getMilliseconds() 返回 Date 對象的毫秒(0 ~ 999)。
getTime() 返回 1970 年 1 月 1 日至今的毫秒數。
getTimezoneOffset() 返回本地時間與格林威治標準時間 (GMT) 的分鐘差。
getUTCDate() 根據世界時從 Date 對象返回月中的一天 (1 ~ 31)。
getUTCDay() 根據世界時從 Date 對象返回週中的一天 (0 ~ 6)。
getUTCMonth() 根據世界時從 Date 對象返回月份 (0 ~ 11)。
getUTCFullYear() 根據世界時從 Date 對象返回四位數的年份。
getUTCHours() 根據世界時返回 Date 對象的小時 (0 ~ 23)。
getUTCMinutes() 根據世界時返回 Date 對象的分鐘 (0 ~ 59)。
getUTCSeconds() 根據世界時返回 Date 對象的秒鐘 (0 ~ 59)。
getUTCMilliseconds() 根據世界時返回 Date 對象的毫秒(0 ~ 999)。
parse() 返回1970年1月1日午夜到指定日期(字符串)的毫秒數。
setDate() 設置 Date 對象中月的某一天 (1 ~ 31)。
setMonth() 設置 Date 對象中月份 (0 ~ 11)。
setFullYear() 設置 Date 對象中的年份(四位數字)。
setYear() 請使用 setFullYear() 方法代替。
setHours() 設置 Date 對象中的小時 (0 ~ 23)。
setMinutes() 設置 Date 對象中的分鐘 (0 ~ 59)。
setSeconds() 設置 Date 對象中的秒鐘 (0 ~ 59)。
setMilliseconds() 設置 Date 對象中的毫秒 (0 ~ 999)。
setTime() 以毫秒設置 Date 對象。
setUTCDate() 根據世界時設置 Date 對象中月份的一天 (1 ~ 31)。
setUTCMonth() 根據世界時設置 Date 對象中的月份 (0 ~ 11)。
setUTCFullYear() 根據世界時設置 Date 對象中的年份(四位數字)。
setUTCHours() 根據世界時設置 Date 對象中的小時 (0 ~ 23)。
setUTCMinutes() 根據世界時設置 Date 對象中的分鐘 (0 ~ 59)。
setUTCSeconds() 根據世界時設置 Date 對象中的秒鐘 (0 ~ 59)。
setUTCMilliseconds() 根據世界時設置 Date 對象中的毫秒 (0 ~ 999)。
toSource() 返回該對象的源代碼。
toString() 把 Date 對象轉換爲字符串。
toTimeString() 把 Date 對象的時間部分轉換爲字符串。
toDateString() 把 Date 對象的日期部分轉換爲字符串。
toGMTString() 請使用 toUTCString() 方法代替。
toUTCString() 根據世界時,把 Date 對象轉換爲字符串。
toLocaleString() 根據本地時間格式,把 Date 對象轉換爲字符串。
toLocaleTimeString() 根據本地時間格式,把 Date 對象的時間部分轉換爲字符串。
toLocaleDateString() 根據本地時間格式,把 Date 對象的日期部分轉換爲字符串。
UTC() 根據世界時返回 1970 年 1 月 1 日 到指定日期的毫秒數。
valueOf() 返回 Date 對象的原始值。
時間日期格式參數

(1)年月日

Input Example Description
YYYY 2014 4 or 2 digit year
YY 14 2 digit year
Y -25 Year with any number of digits and sign
Q 1..4 Quarter of year. Sets month to first month in quarter.
M MM 1..12 Month number
MMM MMMM Jan..December Month name in locale set by moment.locale()
D DD 1..31 Day of month
Do 1st..31st Day of month with ordinal
DDD DDDD 1..365 Day of year
X 1410715640.579 Unix timestamp
x 1410715640579 Unix ms timestamp
(2)時分秒

Input Example Description
H HH 0..23 24 hour time
h hh 1..12 12 hour time used with a A.
a A am pm Post or ante meridiem (Note the one character a p are also considered valid)
m mm 0..59 Minutes
s ss 0..59 Seconds
S SS SSS 0..999 Fractional seconds
Z ZZ +12:00 Offset from UTC as +-HH:mm, +-HHmm, or Z
深圳網站建設https://www.sz886.com

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章