簡體   English   中英

將字符串轉換為 ISO 8601 持續時間格式

[英]Converting a string to ISO 8601 duration format

我需要允許用戶輸入這樣的字符串:

1m 3w 4d 22h 6m 3s

...然后將其轉換為 ISO 8601 持續時間格式,如下所示:

P1M3W4DT22H6M3S

他們甚至應該被允許寫更短的符號,比如:

10 天 12 小時

我什至不知道從哪里開始,似乎找不到任何有助於這些轉換的庫。 我可以使用 MomentISO 8601 持續時間格式轉換,但不能轉換.

建議?

我試圖只刪除空格,但當然我在時間之前錯過了T

`P${duration.toUpperCase().replace(/\s/g, '')}`

刪除空格並大寫字母后,您可以使用正則表達式\\d+H?\\d*M?\\d*S?$來捕獲輸入的時間部分,如果有的話。 這確定了“T”分隔符的插入點:

 const toDuration = s => "P" + s.toUpperCase(s).replace(/\\s/g, "") .replace(/\\d+H?\\d*M?\\d*S?$/, "T$&"); console.log(toDuration("1m 3w 4d 22h 6m 3s")); console.log(toDuration("10d 12h")); console.log(toDuration("10m")); console.log(toDuration("1y 8w 3d")); console.log(toDuration("2m 12h"));

做了一些假設:

  • 如果輸入對“m”(月或分鍾)的含義有歧義,則將其解釋為分鍾。
  • 輸入中各部分的順序無需更改即可派生有效期間表示法。
  • 輸入遵循示例中給出的格式。 這里沒有輸入驗證。

如果要包含驗證,請像這樣擴展:

 const toDuration = s => /^(\\d+y\\s*)?(\\d+m\\s*)?(\\d+w\\s*)?(\\d+d\\s*)?(\\d+h\\s*)?(\\d+m\\s*)?(\\d+s\\s*)?$/i.test(s) ? "P" + s.toUpperCase(s).replace(/\\s/g, "") .replace(/\\d+H?\\d*M?\\d*S?$/, "T$&") : ""; // indicates bad format console.log(toDuration("1m 3w 4d 22h 6m 3s")); console.log(toDuration("10d 12h")); console.log(toDuration("10m")); console.log(toDuration("1y 8w 3d")); console.log(toDuration("2m 12h")); console.log(toDuration("bad12 format"));

如果您缺少的只是D標記后的T分隔符,只需添加.replace('D', 'DT')}

let duration = '1m 3w 4d 22h 6m 3s'
`P${duration.toUpperCase().replace(/\s/g, '').replace('D', 'DT')}`
// gives 'P1M3W4D22H6M3S'

但這僅適用於靜態輸入格式。


要解析完整和不完整的輸入,您需要按類型解析它們。

 const parseDuration = duration => { const keys = ['Y', 'M', 'W', 'D', 'H', 'MIN', 'S'] if (!duration || typeof duration !== 'string') throw "Empty input" let parsed = {} // split entries by space and process them duration.split(/\\s+/).map(r => { // get length (number) and type for each entry let [_, len, type] = r.match(/^(\\d+)(\\w+)$/) type = type.toUpperCase() // assume M means minutes if either of W, D or H is set if (type === 'M' && (parsed['W'] || parsed['D'] || parsed['H'])) type = 'MIN' // asign length by type if (len && keys.includes(type)) parsed[type] = len }) if (!Object.keys(parsed).length) throw new Error("Empty input") // set all undefined types to zero for (const k of keys) parsed[k] = parseInt(parsed[k]) || 0 // format to ISO 8601 duration return `P${parsed.Y}Y${parsed.M}M${parsed.W}W${parsed.D}DT${parsed.H}H${parsed.MIN}M${parsed.S}S` } try { console.log(parseDuration('1m 3w 4d 22h 6m 3s')) } catch { console.warn('failed to parse') } // P0Y1M3W4DT22H6M3S try { console.log(parseDuration('3w 12h 10m')) } catch { console.warn('failed to parse') } // P0Y0M3W0DT12H10M0S try { console.log(parseDuration('1bullshit')) } catch { console.warn('failed to parse') } // fails try { console.log(parseDuration('')) } catch { console.warn('failed to parse') } // fails

示例編輯為包括基本語法驗證

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM