使用Bootstrap 3 Datepicker v4所引發的moment JS的RFC2822錯誤

Bootstrap 3 Datepicker v4是一個非常好用強大的套件,不過在日前我在前端Debug時,意識到我的Browser Console竟然有一個關於這個套件所引發的警告(這個警告你在Localhost下是看不到的)。如果你引用的Bootstrap 3 Datepicker v4也有出現下列雷同的訊息,放心,這並不是你的問題,而是Bootstrap 3 Datepicker v4的作者自己沒有把說明文件寫清楚所致。

要證明這個問題很簡單,我們去看作者本身的網站(Bootstrap 3 Datepicker v4 Docs)就可以知道,連作者自己的說明文件程式碼,也犯了一樣的錯誤。按下右鍵幫忙除錯一下,就可以發現問題在哪了。以下是該網站的截圖:

上面這一張圖想要表示的是,作者自己的文件就已經寫錯了。

上面這一張圖想要表示的是,自己用JS中斷一下,就可以發現錯誤訊息跳出來了。

moment.js的RFC2822錯誤訊息

Deprecation warning: value provided is not in a recognized RFC2822 or ISO format. moment construction falls back to js Date(), which is not reliable across all browsers and versions. Non RFC2822/ISO date formats are discouraged and will be removed in an upcoming major release.
-----
Deprecation warning: moment construction falls back to js Date. This is discouraged and will be removed in upcoming major release.

要解除這個錯誤訊息很簡單,其實moment.js有跟你提供非常詳細的訊息,詳見這個網址:moment.js / string-format,大致上就是你不要讓moment.js自己去猜你給定的日期格式,請在一開始建構時就給定格式,否則moment.js引發解析失敗後,回去調用底層的JS Data()函式,這下就糟糕了,有可能會因為各地的使用者的瀏覽器之不同,而讓你的JS程式碼出現崩潰。

從上面這一段描述,就可以知道JS這語言多麼的鳥。(很草率,連i18n的觀點也沒有實作,要靠各個外圍插件來修補...啊!離題了。)

修補方式

知道錯誤是一個問題,修補又是另外一個問題,這問題會讓我有一點煩躁是因為單獨用JS調用defaultDate時,並不會引發錯誤,而是要同一個頁面連續設定多重屬性時,才會引爆錯誤,這一點我並沒有去看GitHub原始碼,如果細追應該可以查問題提點。總而言之,如果你的頁面有用到複雜的JS設定,那就要連同下面各屬性都要一起考慮,缺一不可(這點讓我浪費了快一小時):

defaultDate: moment("2018/04/30 00:00:00", "YYYY/MM/DD HH:mm:ss")
minDate: moment("2018/04/30 00:00:00","YYYY/MM/DD HH:mm:ss")
maxDate: moment("2018/04/30 00:00:00","YYYY/MM/DD HH:mm:ss")

此外,若有自己寫的JS賦值方法,也要記得一起改:

$("#YourElementID").data("DateTimePicker").date(moment(cDateTime, "YYYY/MM/DD HH:mm:ss"));

最後想要抱怨...

其實也沒啥好抱怨的,畢竟自己並不是開源的程式工作者,要用人家的元件就自己懶趴掐緊一點。只是對於作者這種作法,倒是引發另外一套自己心中的哲學討論就是了。我對於開源並不想投入,是因為如果我今天釋出一套元件,我就會想要把它做到盡善盡美,然而,世間萬物啟有盡善盡美的可能?

如果有任何人提出Issues我的心中就會卡一項工作清單,沒有完善不痛快,但這樣的個性,一定會影響到我的正常生活,而我不願意讓程式設計佔據我工作之外的時間,讓我的其他生活樂趣喪失,這就是我不喜歡玩開源的原因。

那麼,如果你一旦選擇了開源,你要做到怎樣的程度?你又要用甚麼樣的態度去面對自己的作品?

畢竟...提出Issues的甚多,Contributors甚少!

Bootstrap 3 Datepicker v4所引發的moment JS的RFC2822錯誤在網路上討論的篇幅不算少,而在GitHub上面回報的Issues也非常之多,作者Eonasdan在回覆人家的提問時,其實應該要深思一下自己是不是哪裡造成了使用者的誤解,但作者反而是採用一種「這不是我的錯,是你自己沒有用moment.js在引入時把日期物件正規化吧?!」的態度來回應。可是我們都知道:

  1. DateTimePicker創建的時候,你是允許使用者自訂格式的(Custom Formats),如果你稍微改一下物件實例化過程的程式碼,其實這個錯誤完全可以自動消失。
  2. 官方連自己的說明文件都會產生錯誤了(範例格式寫錯),且在Issues中,亦有人向作者反映文件寫錯,所以作者不會不知道這點。
  3. 退回原點來說,如果自己寫的範例也出錯了,那用責難的口氣回應反應者是?以下是該位作者回應某位反應者的意見口氣:
Eonasdan commented on 16 Feb 2015

the docs on date and defaultDate states that the function will take "string, Date, moment, boolean:false". Therefore, the docs are correct. If you don't want the error, construct the date with a moment or js Date object

原來will take不代表taken後不會報警告,筆記。他山之石可以攻錯,藉由這篇文章反省自己,若有朝一日想不開也弄些開源專案嘉惠人群,千萬要注意自己的心態並維持初衷啊!

Bootstrap Datetimepicker DatePicker Error Bug Moment.js IsoFormat RFC2822 FallsBackToJsDate()