More than 1 year has passed since last update.

2017.04.13 仕様変更
作ったそばから仕様変更しました。
マイナスの値に対応しました。
その影響で日付のデリミタを「-」から「/」に変更しました。
そして、日付と時間でマイナスの値は意味がちょっと違います。
日付の場合は、「0」が存在しないので、「0」を指定するとひとつ前のものになります。
なので「-1」だと2つ前になります。

2017/12/00 → 2017/11/30
2017/12/-1 → 2017/11/29

時間の場合はそのまま、

12:00:-1   → 11:59:59
12:-1:00   → 11:59:00

になります。
年のマイナスはナシの方向で…


日時を正規化する

例えば、現在時刻を取得すると「2017-04-11 22:00:00」だったとします。
とあるモジュールに3時間後を渡そうと思うと「25」になります。
しかし、JavaScriptDatePHP等のように自動的に日を進めて12日にはしてくれない。
なので正規化するモジュールを探してみたが見つからず。
しょうがないので作ったので備忘録。

引数は「2017/04/11 25:00:00」のフォーマットで渡します

ちなみにCoffeeScriptです。

normalizeDate = (str)->
    spl = str.split(" ")
    if (spl.length < 2)
        return undefined

    date = spl[0].split("/")
    if (date.length < 3)
        return undefined

    time = spl[1].split(":")
    if (time.length < 3)
        return undefined

    # 年月日の取得
    year   = parseInt(date[0])
    month  = parseInt(date[1])
    day    = parseInt(date[2])
    hour   = parseInt(time[0])
    minute = parseInt(time[1])
    second = parseInt(time[2])

    # 秒の正規化
    key = 60
    addminute = 0
    if (second >= key)
        addminute = Math.floor(second / key)
        second %= key
    else if (second < 0)
        second = key + second
        addminute--

    minute += addminute

    # 分の正規化
    key = 60
    addhour = 0
    if (minute >= key)
        addhour = Math.floor(minute / key)
        minute %= key
    else if (minute < 0)
        ninute = key + minute
        addhour--

    hour += addhour

    # 時の正規化
    key = 24
    addday = 0
    if (hour >= key)
        addday = Math.floor(hour / key)
        hour %= key
    else if (hour < 0)
        hour = key + hour
        addday--

    day += addday

    # 日の正規化
    addmonth = 0
    addyear = 0
    lastday = parseInt((new Date(year, month, 0)).toString().split(' ')[2])
    if (day > lastday)
        while (day > lastday)
            if (day > lastday)
                day -= lastday
                addmonth++
                if ((month + addmonth) > 12)
                    addyear++
                    addmonth -= 12
            lastday = parseInt((new Date(year+addyear, month+addmonth, 0)).toString().split(' ')[2])
    else if (day <= 0)
        checkmonth = month - 1
        checkyear = year
        if (checkmonth < 1)
            checkmonth = 12
            checkyear--
        lastday = parseInt((new Date(checkyear, checkmonth, 0)).toString().split(' ')[2])
        day = lastday + day
        addmonth--

    year += parseInt(addyear)
    month += parseInt(addmonth)

    # 月の正規化
    key = 12
    addyear = 0
    if (month > key)
        addyear = Math.floor(month / key)
        month %= key
    else if (month <= 0)
        month = key + month
        addyear--

    year += addyear

    ret =
        year:year
        month:("00"+parseInt(month)).slice(-2)
        day:("00"+parseInt(day)).slice(-2)
        hour:("00"+parseInt(hour)).slice(-2)
        minute:("00"+parseInt(minute)).slice(-2)
        second:("00"+parseInt(second)).slice(-2)

    return ret

スクリプトの最後を見てもらうと分かりますが、年月日時分秒がオブジェクトで返ってきます。

Sign up for free and join this conversation.
Sign Up
If you already have a Qiita account log in.