Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

日時の正規化

More than 3 years have 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

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

digitarhythm
いろいろ作っています。 フルスタックフレームワーク「ViewllerJS」 https://www.digitarhythm.net/viewllerjs ブラウザでWebゲーム開発「enforceIDE」 https://www.prominence.tv/enforceIDE WebブラウザでProcessing「InstaProc」 https://processing.fun/
http://www.digitarhythm.net
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away