整合營銷服務商

          電腦端+手機端+微信端=數據同步管理

          免費咨詢熱線:

          從零開始學Qt(31):時間日期組件的使用

          間日期數據類型

          時間日期是經常遇到的數據類型,Qt中時間日期類型的類如下。

          • QTime:時間數據類型,僅表示時間,如15:23:13。
          • QDate:日期數據類型,僅表示日期,如2017-4-5。
          • QDateTime:日期時間數據類型,表示日期和時間,如2017-03-23 08:12:43。

          時間日期轉換為字符串使用QDateTime的toString()函數,分別用不同的格式顯示時間、日期、日期時間。toString()的函數原型是:

          QString QDateTime::toString(const QString &format) const

          它將日期時間數據按照format指定的格式轉換為字符串。format是一個字符串,包含一些特定的字符,表示日期或時間的各個部分,下圖是用于日期時間顯示的常用格式符。

          在設置日期時間顯示字符串格式時,還可以使用填字符,甚至使用漢字。例如,日期顯示格式可以設置為:toString ("yyyy年MM月dd日"),這樣得到的字符串格式是“2023年03月15日”。

          同樣的,也可以將字符串轉換為QTime、QDate或QDateTime類型,使用靜態函數QDateTime::fromString(),其函數原型為:

          QDateTime QDateTime::fromString(const QString &string, const QString &format)

          其中,第1個參數string是日期時間字符串形式,第2個參數format是字符串表示的格式。

          時間日期界面組件

          Qt中有專門用于日期、時間編輯和顯示的界面組件,介紹如下。

          • QTimeEdit:編輯和顯示時間的組件。
          • QDateEdit:編輯和顯示日期的組件。
          • QDateTimeEdit:編輯和顯示日期時間的組件。
          • QCalendarWidget:一個用日歷形式選擇日期的組件。

          QDateEdit和QTimeEdit都從QDateTimeEdit繼承而來,實現針對日期或時間的特定顯示功 能。實際上,QDateEdit和QTimeEdit的顯示功能都可以通過QDateTimeEdit實現,只需設置好屬性即可。

          QDateTimeEdit類的主要屬性的介紹如下。

          示例

          在圖中窗體左上方的“日期時間”中,使用QTimeEdit、QDateEdit、QDateTimeEdit組件作為時間、日期、日期時間編輯器;在其下方,放置一個QLineEdit組件用于字符串顯示日期時間。界面如下圖。

          1. 日期時間數據的獲取與轉換為字符串

          “讀取當前日期時間”按鈕的clicked()信號的槽函數代碼如下:

          void Widget::on_btnGetTime_clicked()
          {
            QDateTime curDateTime=QDateTime::currentDateTime();
            ui->timeEdit->setTime(curDateTime.time());
            ui->dateEdit->setDate(curDateTime.date());
            ui->dateTimeEdit->setDateTime(curDateTime);
            ui->edtDateTime->setText (curDateTime.toString("yyyy-MM-dd hh:mm:ss"));
          }

          首先用QDateTime類的靜態函數currentDateTime()獲取當前日期時間,并賦值給變量curDateTime。

          然后用curDateTime變量設置界面上3個日期、時間編輯器的時間或日期值,利用了 QDateTime的time()和date()分別提取時間和日期。

          最后,將curDateTime表示的日期時間數據轉換為字符串然后在LineEdit編輯框上顯示。

          2. 字符串轉換為日期時間

          在程序運行時,手工修改“字符串顯示”后面文本框里的日期時間字符串,單擊“設置日期時間”按鈕,可以將文本框里的字符串轉換為QDateTime變量,并設置為組件的日期時間數據,代碼如下:

          void Widget::on_btnSetTime_clicked()
          {
            QString str=ui->edtDateTime->text();
            str=str.trimmed();
            if(!str.isEmpty())
            {
              QDateTime datetime=QDateTime::fromString(str,"yyyy-MM-dd hh:mm:ss");
              ui->timeEdit->setTime(datetime.time());
              ui->dateEdit->setDate(datetime.date());
              ui->dateTimeEdit->setDateTime(datetime);
            }
          }

          3. QCalendarWidget日歷組件

          圖中窗體右側是一個QCalendarWidget組件,它以日歷的形式顯示日期,可以用于日期選擇。

          QCalendarWidget有一個信號selectionChanged(),在日歷上選擇的日期變化后會發射此信號,為此信號創建槽函數,編寫代碼如下:

          移動Web頁面,受移動網絡網速和終端性能影響,我們經常要關注首屏內容展示時間(以下簡稱首屏時間)這個指標,它衡量著我們的頁面是否能在用戶耐心消磨完之前展示出來,很大程度影響著用戶的使用滿意度。

          怎么獲取首屏時間呢?

          我們經常要先問自己:頁面是怎么加載數據?

          A:加載完靜態資源后通過Ajax請求去后臺獲取數據,數據回來后渲染內容

          在每個點打上一個時間戳,首屏時間 = 點8 – 點1

          B:使用后臺直出,返回的html已經帶上內容了

          此時首屏時間 = 點4 – 點1。

          注:1. 打了這么多個點,是因為當我們收集到首屏時間之后,要去分析到底是哪一段是性能瓶頸,哪一段還有優化空間,所以我們需要收集 點2 – 點1、點3 – 點1 ……這些時間以作分析。

          2. 打點1我們一般是在html文件head標簽的開頭打個時間戳。

          3. 在css文件加載前一般沒有別的加載處理,所以打點1和打點2一般可以合并。

          到此我們就收集到首屏相關各種數據,可以做各種針對性優化。Wait!在你大刀闊斧優化前,你要了解一些細節,它們有利于你做更準確的分析和更細致的優化。

          細節1:js后面的點 – js前面的點 ≠ js的加載時間

          JsEndTime – JsStartTime = js文件的加載時間,對嗎?

          不對!明顯地,這個等式忽略了js的執行時間。js執行代碼是需要花費時間的,特別是做一些復雜的計算或頻繁的dom操作,這個執行時間有時會達到幾百毫秒。

          那么,JsEndTime – JsStartTime = js文件的加載執行時間?

          依然不對!因為CSS文件的加載執行帶來了干擾。覺得很奇怪對吧,別急,我們來做個試驗:我們找一個demo頁面,在chrome里面打開,然后啟動控制臺,模擬低網速,讓文件加載時間比較久:

          先在正常情況下收集 JsEndTime – JsStartTime 的時間,然后使用fiddler阻塞某一條css請求幾秒鐘:

          然后再恢復請求,拿到此時的 JsEndTime – JsStartTime 結果,會發現第一次的時間是幾百毫秒將近1s,而第二次的時間低于100ms甚至接近為0(我的示例,時間視讀者具體的js文件決定),兩者的差距非常明顯。

          這是什么原理?這就是我們常說的“加載是并行的,執行是串行的”的結果。html開始加載的時候,瀏覽器會將頁面外聯的css文件和js文件并行加載,如果一個文件還沒回來,它后面的代碼是不會執行的。剛剛我們的demo,我們阻塞了css文件幾秒,此時js文件因為并行已經加載回來,但由于css文件阻塞住,所以后面 JsStartTime 的賦值語句是不執行的!當我們放開阻塞,此時才會運行到 JsStartTime 的賦值、js文件的解析、JsEndTime的賦值,由于大頭時間加載早已完成,所以 JsEndTime 和 JsStartTime 的差值非常小。

          知道這個有何用?

          1、別再把 JsEndTime – JsStartTime 的結果成為js文件的加載執行時間(除非你沒有外聯css文件),不然會被內行人取笑滴。

          2、Css文件的阻塞會影響后面js代碼的執行,自然也包括html代碼的執行,即是說此時你的頁面就是空白的。所以css文件盡量內聯,你可以讓構建工具幫你忙。

          3、如果真想要知道js文件的加載時間,最正確的姿勢是使用 Resource Timing API,不過這個API移動端只能在Android4.4及以上的版本拿到數據,也就在業務PV大的場景才夠我們做分析用。

          當然,那兩個打點留著還是可以做分析用的。

          細節2:html里面外聯的js文件,前一個文件的加載會阻塞下一個文件的執行;而如果a.js負責渲染并會動態拉取js、拉取cgi并做渲染,會發現它后面的js文件再怎么阻塞也不會影響到它的處理

          前半部分的結論在細節1里面已經證明,因為瀏覽器的執行是串行的。這說明,我們負責渲染內容的js代碼要等到它前面所有的js文件加載執行完才會執行,即使那些代碼跟渲染無關的代碼如數據上報:

          而后半部分的結論很好驗證,我們在負責渲染的js文件后面外聯一個別的js文件并把它阻塞住,你會發現渲染相關的js不管是動態拉取新的js文件、拉取渲染相關內容都一切正常,頁面內容順利渲染出來,它們的執行并不需要等被阻塞的這個文件。

          知道這個有何用?

          1、無關緊要”的js不要放在負責渲染的js前面,這里的“無關緊要”是指和首屏渲染無關,如數據上報組件。我們可以選擇將要上報的數據臨時存起來,先繼續執行渲染的js,等負責渲染的js執行完再加載上報組件再上報。甚至連zepto之類的庫我們也可以放后面,把渲染相關的代碼抽離出來并用原生js書寫,放到最前面。

          2、可以看到,動態加載的js的執行是不會受到html后面外聯的js的阻塞的影響,即是說,它的執行和后面js的執行順序是不確定的。因此我們要小心處理好文件的依賴關系。當然還可以采用最不容易出錯的方法:負責動態加載js的文件是html里面外聯的最后一個文件。

          細節3:如果html的返回頭包含chunk,則它是邊返回邊解析的,不然就是一次性返回再解析。這個是在服務器配置的

          打點1一般寫在html里head標簽的最前面,時常有朋友拿直出時的 點4 – 點1 的時間和非直出時 點8 – 點1 的時候做對比,來說明直出優化了多少多少毫秒,我倒覺得不一定。要知道直出的情況html文件包含渲染后的內容和dom節點,文件大小一般比非直出大,有時甚至大個幾十K都有,那我覺得要說明直出優化了多少就要把html的加載時間考慮進去了。那上面的計算方法是否考慮上html的加載時間?

          那就要看html文件的返回頭是否包含chunk:

          如果包含這個返回頭,那html文件是邊返回邊解析的,此時上面的計算方法是合理的。如果不包含這個頭,則html文件是整一個返回來后才開始解析,此時上面的計算方法就少算了html的加載時間,也就不夠精準。這個返回頭是由后臺控制的。

          知道這個有何用?

          1、如果我們想說明直出的優化程度,最好先瞧瞧你的html返回頭。如果不包含chunk返回頭,考慮拿HTML5 performance里面的 navigationStart 作為打點1(這個API也是Android4.4及以上才支持),要不就要評估文件大小變化做點修正了。

          2、對于沒有啟用chunk的html,建議不要inline太多跟渲染首屏內容無關的js在里面,這樣會影響渲染時間

          細節4:寫在html里面的script節點的加載和解析會影響 domContentLoaded 事件的觸發時間

          我們有時會用 domContentLoaded 事件代替 onload 事件,在頁面準備好的時候做一些處理。然而要知道domContentLoaded里面的dom不止包含我們常說的普通dom節點,還包括script節點。

          試驗一下,我們將頁面里面外聯的一個js文件阻塞住一段時間再放開,我們看下chrome控制臺:

          很明顯,js文件的加載時間會影響這個事件的觸發事件。那js代碼的解析時間會不會影響?我們在最后一個外聯JS文件后面打了一個點,它的時間是:

          所以js文件加載執行會影響domContentLoaded事件的執行時機。

          知道這個有何用

          1、如果我們打算在domContentLoaded、onLoad 事件里面做一些特殊處理且這些處理比較重要(如跟渲染有關),那我們最好就不要在html里面直接外聯一些跟渲染無關的js文件,可以考慮改用動態加載。

          總結

          研究首屏時間和資源加載是一件挺有意思的事情,大家利用好chrome控制臺(特別是里面的network標簽)以及fiddler可以挖掘出很多有趣的小細節小結論。別以為這是在沒事找事,理解好這些對大家做首屏性能優化、定位因為js文件執行順序錯亂導致報錯等場景是非常有好處的。

          文章轉載自 AlloyTeam:http://www.alloyteam.com/2016/01/points-about-resource-loading/

          更多技術干貨請關注聽云博客 blog.tingyun.com

          近在編程中遇到了時間與時區相關的問題,整理在這里

          我的程序是一個在hadoop上運行的分布式程序,從mysql數據庫中取數據,經過處理之后輸出

          一. 基本概念

          時區 :time zone 1884年國際經線會議規定,全球按經度分為24個時區,每區各占經度15°。

          以本初子午線為中央經線的時區為零時區,由零時區向東、西各分12區,東、西12區都是半時區,共同使用180°經線的地方時。

          CST :China Standard Time UTC+8:00 中國標準時間(北京時間),在東八區

          UTC :Universal Time Coordinated,世界協調時間,又稱世界標準時間、世界統一時間。UTC 提供了一種與時區無關(或非特定于時區)的時間。

          世界上的所有時區都可以表示為 UTC 加上或減去一個偏移量。

          因此,UTC是0時區的時間,如北京為早上八點(東八區),UTC時間就為零點,時間比北京時晚八小時

          GMT :Greenwich Mean Time格林威治標準時間,指位于英國倫敦郊區的皇家格林尼治天文臺的標準時間,因為本初子午線被定義在通過那里的經線。

          Unix timestamp :Unix時間戳,或稱Unix時間(Unix time)、POSIX時間(POSIX time),是一種時間表示方式,

          定義為從格林威治時間(UTC/GMT的午夜)1970年01月01日00時00分00秒起至現在的總秒數。

          可以這么說:

          UTC和GMT幾乎是同一概念,兩者的區別是GMT是一個天文上的概念,UTC是基于原子鐘。

          GMT=UTC

          GMT + 8 = UTC + 8 = CST

          UTC+時間差=本地時間 (時間差東為正,西為負,東八區記為 +0800)

          二. 從數據庫取數據的過程

          mysql>select auction_id,startsfrom auctions where auction_id=88888;
          ±------------±--------------------+
          | auction_id | starts |
          ±------------±--------------------+
          | 88888 | 2011-10-24 20:32:58 |
          ±------------±--------------------+
          1 rowin set (0.00 sec)
          mysql> show columnsfrom auctions;
          ±-------------------------------±--------------±-----±----±--------±------+
          | Field | Type |Null | Key| Default | Extra |
          ±-------------------------------±--------------±-----±----±--------±------+
          |starts | datetime | YES | MUL |NULL | |

          可見:數據庫的時間字段starts存的是datetime類型,它是一個和時區相關的string(顯然:string都是和時區相關的)

          而且數據庫是按照CST時區存的時間

           程序中從數據庫取數據用的sql語句:
          mysql>select auction_id,DATE_FORMAT(starts,’%Y%m%d%H%i%S’)from auctions where auction_id=88888;
          ±------------±-----------------------------------+
          | auction_id | DATE_FORMAT(starts,’%Y%m%d%H%i%S’) |
          ±------------±-----------------------------------+
          | 88888 | 20111024203258 |
          ±------------±-----------------------------------+
          1 rowin set (0.00 sec)

          這里只是簡單的用DATE_FORMAT函數把datetime類型的starts字段轉換為我們需要的格式 %Y%m%d%H%i%S 而已

          三、java代碼

          看這樣一段轉換時間的java代碼:

          // 將字符串時間轉化為秒數(yyyyMMddHHmmss)
          staticpublic long getUnixTimestamp(String srcTime)
          {
          SimpleDateFormat sdf =new SimpleDateFormat(“yyyyMMddHHmmss”);
          Date result_date;
          longresult_time = 0;
          try{
          result_date = sdf.parse(srcTime);
          //返回的是毫秒數故除以1000
          result_time = result_date.getTime()/1000;
          }catch (Exception e) {
          //出現異常時間賦值為20000101000000
          result_time =946684800;
          }
          returnresult_time;
          }

          計算結果:

          getUnixTimestamp(“20111204212224”) =1323004944

          說明:java.util.Date中的getTime函數定義如下:

          java.util.Date代表一個時間點,其值為距公元1970年1月1日 00:00:00的毫秒數。所以它是沒有時區和Locale概念的。

          public long getTime() 返回自 1970 年 1 月 1 日 00:00:00 GMT 以來此 Date 對象表示的毫秒數

          java中通過如下形式取得當前時間點: 

          Date now =new Date(); //這個時間點與本地系統的時區無關

          而正因為其與時區的無關性,才使得我們的存儲數據(時間)是一致的(時區一致性)。
            一般的我們將now存儲于數據庫中,當我們需要展現數據時,將now格式化成想要的格式,如:2011-12-04 21:22:24
            而這個功能一般交由java.text.DateFormat來實現。例如:

          SimpleDateFormat sdf =new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
          String snow = sdf.format(now);

          我們發現snow是帶時間(如2011-12-04 21:22:24)的字符串,那么 2011-12-04 21:22:24 這個時間是哪個時區的時間呢?

          默認情況下,SimpleDateFormat 取得本地系統的時區(我的時區為GMT+8北京),然后按照 pattern(“yyyy-MM-dd HH:mm:ss”)格式化now,
            此時輸出的就是 GMT+8 區的時間了。如果想支持國際化時間,則先指定時區,然后再格式化date數據。例如:

          SimpleDateFormat sdf =new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
          sdf.setTimeZone(TimeZone.getTimeZone(“GMT+8”));
          String snow = sdf.format(now);// snow = 2011-12-04 21:22:24
          sdf.setTimeZone(TimeZone.getTimeZone(“GMT+7”));
          String snow2 = sdf.format(now);// snow2 = 2011-12-04 20:22:24 (可見:東八區比東七區早一個小時)

          另外,你可以通過如下代碼修改本地時區信息:

          TimeZone.setDefault(TimeZone.getTimeZone(“GMT+8”));

          在windows操作系統中,是通過桌面右下角,也可以指定操作系統的時區。

          在linux系統中,通過如下命令可以得到當前時區

          [admin@localhost]$ date -R
          Sun,04 Dec 201122:49:00+0800

          四、結論:

          getTime()返回的已經是一個UTC的unix timestamp秒數了,與時區無關;而轉換為字符串后,就和時區相關了
            對于這個秒數,不同時區的人,按照自己所在的時區去解析,就可以得到正確的時間了

          [admin@localhost]$ date -d@1323004944
          2011年12月 04日 星期日21:22:24CST
          [admin@localhost]$ date -d@1323004944 -u
          2011年12月 04日 星期日13:22:24UTC

          對于涉及到時間轉換的程序來說,如果代碼里面沒有強行指定時區,那就會依賴于操作系統的時區。

          特別是對于分布式程序,如果不同機器上系統時區不一樣,那就會出現不一致的數據了!

          五、對unix timestamp和時區概念的曲解和誤用

          由于歷史原因,發現程序中有這樣一段代碼:

          // 將字符串時間轉化為秒數(yyyyMMddHHmmss),有8個小時的時差
          staticpublic long getLongTime(String srcTime)
          {
          SimpleDateFormat sdf =new SimpleDateFormat(“yyyyMMddHHmmss”);
          Date result_date;
          longresult_time = 0;
          try{
          result_date = sdf.parse(srcTime);
          //返回的是毫秒數故除以1000
          result_time = result_date.getTime()/1000+ 8 * 3600; // 這里加了八個小時
          }catch (Exception e) {
          //出現異常時間賦值為20000101000000
          result_time =946684800;
          }
                  returnresult_time;

          }

          計算結果:

          getUnixTimestamp(“20111204212224”) =1323033744
          顯然,這個時間比上面通過 getUnixTimestamp(“20111204212224”) = 1323004944 得到的時間多了8個小時
          1323033744 - 1323004944 = 28800 = 8 * 3600 = 8h

          如果用戶將得到的 1323033744 按照自己所在的時區解析后得到的結果是:

          [admin@localhost]$ date -d@1323033744
          2011年12月 05日 星期一05:22:24CST

          得到了一個完全錯誤的結果!

          但如果用戶將這個 1323033744 按照UTC時區來解析后得到的結果是:

          [admin@localhost]$ date -d@1323033744 -u
          2011年12月 04日 星期日21:22:24UTC

          為了方便對比,把 1323004944 的解析結果也拿來對比

          [admin@localhost]$ date -d@1323004944
          2011年12月 04日 星期日21:22:24CST
          [admin@localhost]$ date -d@1323004944 -u
          2011年12月 04日 星期日13:22:24UTC

          可以看到,這個代碼中得到的秒數時間是比UTC的unix timestamp秒數多了八個小時

          這個時間 1323033744 可以理解為北京時區得到的秒數,但是不是unix timstamp時間!

          unix timestamp秒數是與時區無關的,不管是在哪個時區得到的unix timestamp都是一樣的

          我們可以驗證一下,用北京時間“20111204212224”減去“19700000000000”得到的秒數,就是 1323033744

          SimpleDateFormat df =new SimpleDateFormat(“yyyy-MM-dd HH:mm:ss”);
          java.util.Date end = df.parse(“2011-12-04 21:22:24”);
          java.util.Date start = df.parse(“1970-01-01 00:00:00”);
          longdelta = (end.getTime() - start.getTime())/1000;
          System.out.println(“delta=”+ delta); // delta=1323033744

          或者用shell命令來求時間差

          [admin@localhost]$ date -d"2011-12-04 21:22:24" +%s
          1323004944
          [admin@localhost]$ date -d"1970-01-01 0:0:0" +%s
          -28800
          [admin@localhost]$ date -d"2011-12-04 21:22:24" +%s -u
          1323033744
          [admin@localhost]$ date -d"1970-01-01 0:0:0" +%s -u
          0
          1323004944 + 28800 = 1323033744

          對于東八區的人來說,1323033744 這個時間按照UTC時間可以解析正確。不能按照自己所在的時區去解析,不然就是錯的

          但是如果是東七區的人呢?需要按照UTC時間解析后,自己去減1個小時的時差,so ugly!

          所以,用戶在解析1323033744 這個數據的時候:

          (1) 按照UTC時間來解析得到北京時間,然后根據時間差換算成自己所在時區的時間

          (當然,一般都是在北京時區了,所以不用換算,按UTC時間來解析就能得到正確的時間)

          (2) 將這個時間減去8小時得到unix timestamp,然后按照自己所在的時區去解析就可以了

          總結:這段代碼是對unix timestamp和時區的曲解和誤用。

          六、從數據庫獲取unix timestamp時間


          主站蜘蛛池模板: 日韩精品无码视频一区二区蜜桃| 色偷偷久久一区二区三区| 国产成人精品久久一区二区三区av| 成人丝袜激情一区二区| 亚洲一区二区三区首页| AA区一区二区三无码精片| 怡红院一区二区三区| 福利片免费一区二区三区| 国产凹凸在线一区二区| 亚洲日韩AV一区二区三区四区| 福利一区二区三区视频午夜观看| 国产伦精品一区二区三区视频猫咪| 国产亚洲一区二区三区在线| 国产电影一区二区| 九九无码人妻一区二区三区| 精品在线一区二区三区| 国产精品亚洲一区二区三区在线| 亚洲欧美日韩国产精品一区| 精品一区二区三区水蜜桃| 久久久久久人妻一区精品| 狠狠做深爱婷婷久久综合一区 | 黑人大战亚洲人精品一区| 黑人一区二区三区中文字幕| 国模大尺度视频一区二区| 精品动漫一区二区无遮挡| 亚洲国产成人精品久久久国产成人一区二区三区综 | 大屁股熟女一区二区三区| 亚洲福利视频一区| 激情综合丝袜美女一区二区| 亚洲综合一区二区国产精品| 成人免费一区二区无码视频| 不卡一区二区在线| 国产在线一区二区三区av| 2021国产精品一区二区在线| 国产高清在线精品一区小说| 毛片无码一区二区三区a片视频| 日韩人妻无码一区二区三区综合部 | 国产亚洲一区二区三区在线| 美日韩一区二区三区| 色偷偷av一区二区三区| 少妇无码AV无码一区|