JavaScript版strftime（組み込みオブジェクトDateの拡張）

#strftimeって？
PythonやCなどにある、日付オブジェクトのフォーマット関数。あらかじめ決められたキーワードを入力することで、該当箇所が日付のパラメータに置換される。

```python:Python
import datetime

d = datetime.datetime.now()
d.strftime('%Y-%m-%d')
# "2020-06-18"
d.strftime('%c')
# "Thu Jun 18 13:25:31 2020"
```
#使い方

```javascript:JavaScript
var d = new Date();
d.strftime('%Y-%m-%d')
//"2020-06-18"
d.strftime('%c')
//"Thu Jun 18 13:25:31 2020"
```
###対応指定子
|指定子|意味|使用例|
|-----|-----|-----|
|`%a`|ロケールの曜日名を短縮形で表示します。|Sun, Mon, ..., Sat|
|`%A`|ロケールの曜日名を表示します。|Sunday, Monday, ..., Saturday|
|`%w`|曜日を10進表記した文字列を表示します。0 が日曜日で、6 が土曜日を表します。|0, 1, ..., 6|
|`%d`|0埋めした10進数で表記した月中の日にち。|01, 02, ..., 31|
|`%b`|ロケールの月名を短縮形で表示します。|Jan, Feb, ..., Dec|
|`%B`|ロケールの月名を表示します。|January, February, ..., December|
|`%m`|0埋めした10進数で表記した月。|01, 02, ..., 12|
|`%y`|0埋めした10進数で表記した世紀無しの年。|00, 01, ..., 99|
|`%Y`|西暦 (4桁) の 10 進表記を表します。|0001, 0002, ..., 2013, 2014, ..., 9998, 9999|
|`%H`|0埋めした10進数で表記した時 (24時間表記)。|00, 01, ..., 23|
|`%I`|0埋めした10進数で表記した時 (12時間表記)。|01, 02, ..., 12|
|`%p`|ロケールの AM もしくは PM と等価な文字列になります。|AM, PM|
|`%M`|0埋めした10進数で表記した分。|00, 01, ..., 59|
|`%S`|0埋めした10進数で表記した秒。|00, 01, ..., 59|
|`%f`|10進数で表記したマイクロ秒 (左側から0埋めされます)。|000000, 000001, ..., 999999|
|`%j`|0埋めした10進数で表記した年中の日にち。|001, 002, ..., 366|
|`%c`|ロケールの日時を適切な形式で表します。|Tue Aug 16 21:30:00 1988|
|`%z`|UTCオフセットを ±HHMM の形式で表示します|-0400, +0900|
|`%Z`|タイムゾーンの名前を表示します。|"Asia/Irkutsk", "Asia/Seoul", "Asia/Tokyo"|
|`%x`|ロケールの日付を適切な形式で表します。|2020/08/16|
|`%X`|ロケールの時間を適切な形式で表します。|21:30:00|
|`%%`|文字 '%' を表します。|%|

###未対応指定子
|指定子|意味|使用例|
|-----|-----|-----|
|`%U`|0埋めした10進数で表記した年中の週番号 (週の始まりは日曜日とする)。新年の最初の日曜日に先立つ日は 0週に属するとします。|00, 01, ..., 53|
|`%W`|0埋めした10進数で表記した年中の週番号 (週の始まりは月曜日とする)。新年の最初の月曜日に先立つ日は 0週に属するとします。|00, 01, ..., 53|

> https://docs.python.org/ja/3/library/datetime.html#strftime-strptime-behavior

----

#大元のコード
```javascript:JavaScript
Date.prototype.strftime = function(s) {
    var a = {
        y: this.getFullYear(),
        m: this.getMonth() + 1,
        d: this.getDate(),
        a: this.getDay(),
        H: this.getHours(),
        M: this.getMinutes(),
        S: this.getSeconds(),
        MS: this.getMilliseconds(),
        _utc: this.getTimezoneOffset() / -60
    }

    var b = Math.floor((new Date() - new Date(a.y,0,1)) / 24 / 60 / 60 / 1000 + 1);
    var loc = {
        "0": ["Africa/Casablanca", "Atlantic/Reykjavik", "Europe/London", "Etc/GMT"],
        "1": ["Europe/Berlin", "Europe/Paris", "Africa/Lagos", "Europe/Budapest", "Europe/Warsaw", "Africa/Windhoek"],
        "2": ["Europe/Istanbul", "Europe/Kiev", "Africa/Cairo", "Asia/Damascus", "Asia/Amman", "Africa/Johannesburg", "Asia/Jerusalem", "Asia/Beirut"],
        "3": ["Asia/Baghdad", "Europe/Minsk", "Asia/Riyadh", "Africa/Nairobi"],
        "4": ["Europe/Moscow", "Asia/Tbilisi", "Asia/Yerevan", "Asia/Dubai", "Asia/Baku", "Indian/Mauritius"],
        "5": ["Asia/Tashkent", "Asia/Karachi"],
        "6": ["Asia/Almaty", "Asia/Dhaka", "Asia/Yekaterinburg"],
        "7": ["Asia/Bangkok", "Asia/Novosibirsk"],
        "8": ["Asia/Krasnoyarsk", "Asia/Ulaanbaatar", "Asia/Shanghai", "Australia/Perth", "Asia/Singapore", "Asia/Taipei"],
        "9": ["Asia/Irkutsk", "Asia/Seoul", "Asia/Tokyo"],
        "10": ["Australia/Hobart", "Asia/Yakutsk", "Australia/Brisbane", "Pacific/Port_Moresby", "Australia/Sydney"],
        "11": ["Asia/Vladivostok", "Pacific/Guadalcanal"],
        "12": ["Etc/GMT-12", "Pacific/Fiji", "Asia/Magadan", "Pacific/Auckland"],
        "13": ["Pacific/Tongatapu", "Pacific/Apia"],
        "-12": ["Etc/GMT+12"],
        "-11": ["Etc/GMT+11"],
        "-10": ["Pacific/Honolulu"],
        "-9": ["America/Anchorage"],
        "-8": ["America/Santa_Isabel", "America/Los_Angeles"],
        "-7": ["America/Chihuahua", "America/Phoenix", "America/Denver"],
        "-6": ["America/Guatemala", "America/Chicago", "America/Regina", "America/Mexico_City"],
        "-5": ["America/Bogota", "America/Indiana/Indianapolis", "America/New_York"],
        "-4.5": ["America/Caracas"],
        "-4": ["America/Halifax", "America/Asuncion", "America/La_Paz", "America/Cuiaba", "America/Santiago"],
        "-3.5": ["America/St_Johns"],
        "-3": ["America/Sao_Paulo", "America/Godthab", "America/Cayenne", "America/Argentina/Buenos_Aires", "America/Montevideo"],
        "-2": ["Etc/GMT+2"],
        "-1": ["Atlantic/Cape_Verde", "Atlantic/Azores"],
        "3.5": ["Asia/Tehran"],
        "4.5": ["Asia/Kabul"],
        "5.5": ["Asia/Colombo", "Asia/Kolkata"],
        "5.75": ["Asia/Kathmandu"],
        "6.5": ["Asia/Yangon"],
        "9.5": ["Australia/Darwin", "Australia/Adelaide"]
    };
    var dict = {
        d: ("0" + a.d).slice(-2),
        m: ("0" + a.m).slice(-2),
        y: String(a.y).slice(-2),
        Y: String(a.y),
        H: ("0" + a.H).slice(-2),
        I: ("0" + (a.H % 12)).slice(-2),
        p: a.H < 12 ? "AM" : "PM",
        M: ("0" + a.M).slice(-2),
        S: ("0" + a.S).slice(-2),
        f: ("00" + a.MS + "000").slice(-6),
        A: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"][a.a],
        a: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"][a.a],
        B: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"][a.m - 1],
        b: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"][a.m - 1],
        w: String(a.a),
        j: ("00" + b).slice(-3),
        z: (a._utc < 0 ? "-" : "+") + ("0" + Math.floor(a._utc * (a._utc < 0 ? -1 : 1))).slice(-2) + ("0" + (a._utc % 1 * 60)).slice(-2),
        Z: loc[String(a._utc)].join(", "),
        "%": "%"
    };
    dict.c = dict.a + " " + dict.b + " " + dict.d + " " + dict.H + ":" + dict.M + ":" + dict.S + " " + dict.Y;
    dict.x = dict.Y + "/" + dict.m + "/" + dict.d;
    dict.X = dict.H + ":" + dict.M + ":" + dict.S;

    return s.replace(/%([a-zA-Z%])/g, function(a, b) {
        return dict[b] || a;
    });
}
```