has_key

menu = {"ham" : 1, "cucumber" : -12, "egg" : 100}

if menu.has_key("ham"):
    print "네, 찾는 것이 있네요"
else:
    print "그런 메뉴는 없습니다."

 

파이썬 3을 사용중이면 아래 에러 문구가 나오면 처리되지 않음

  AttributeError: 'dict' object has no attribute 'has_key' 

has_key는 파이썬에서 지양하는 함수로, 파이썬 2를 사용하는 분들도 사용하면 안된다.

  http://stackoverflow.com/questions/1323410/has-key-or-in

get / in

1. get

menu = {"ham" : 1, "cucumber" : -12, "egg" : 100}

if menu.get("ham"):
    print "네, 찾는 것이 있네요"
else:
    print "그런 메뉴는 없습니다."
2. in
menu = {"ham" : 1, "cucumber" : -12, "egg" : 100}

if "ham" in menu:
    print "네, 찾는 것이 있네요"
else:
    print "그런 메뉴는 없습니다."

get은 키에 해당하는 값을 넘겨주기 때문에 값이 있다면 True고 없다면 False(...일 것 같지만 실제로는 None을 리턴한다. None False가 아니긴 하지만.... 어차피 키 값 판별이니 True가 아니므로 없는 메뉴에 대해서는 else로 빠진다.) 가 된다.

 

참고

https://www.pymoon.com/entry/%ED%8C%8C%EC%9D%B4%EC%8D%AC%EC%97%90%EC%84%9C-%EB%94%95%EC%85%94%EB%84%88%EB%A6%AC-%ED%82%A4-%EA%B0%92-%EC%B2%B4%ED%81%AC%ED%95%98%EA%B8%B0

 

replace

일반적으로 한 두개 정도의 간단한 치환

# 대문자를 소문자로
> ex = "Korea is Great"
> ex.replace('K','k').replace('G','g')
'korea is great'

translate

여러 문자를 한번에 치환

유의해야 할점은 maketrans 함수 안에 두 개의 인자의 길이(length)가 똑같아야함

# 모음없애기(소문자 외 대문자까지 한방에 가능하다)
> ex = "Korea is Great"
> table = str.maketrans('aieouAIEOU', '          ')
> ex.translate(table)
'K r    s Gr  t'

> table = str.maketrans('aieouAIEOU', '1234567890')
> ex.translate(table)
'K4r31 2s Gr31t'

 

참고

https://velog.io/@keywookim/Python-translate-%ED%95%9C-%EB%B2%88%EC%97%90-%EC%97%AC%EB%9F%AC-%EB%AC%B8%EC%9E%90-%EC%B9%98%ED%99%98%ED%95%98%EA%B8%B0

에러 문구

too many values to unpack

원인

설정한 변수의 개수와 리턴해 주는 변수의 개수가 차이가 날때 발생

예를 들어 리턴 받는 값의 개수가 3개로 맞춰야 정상인 경우
aa, bb, cc = ss.run([a,b,c])

아래 경우는 오류 발생
bb, cc = ss.run([a,b,c])
> too many values to unpack

해결

리턴 받는 값의 개수를 맞춰주면 해결

 

참고 

https://wotres.tistory.com/entry/too-many-values-to-unpack-%EC%97%90%EB%9F%AC-%ED%95%B4%EA%B2%B0%EB%B2%95

 

조건

flask 환경에서 in 을 사용하여 검색

방법

flask에서 변수를 받을때 리스트 형태( getlist('ip_group[]' )로 받음

sql 쿼리에 매개변수 전달 시, 리스트 형태를 전달

[html]

<select class="select2" multiple="multiple" name="ip_group[]" id="ip_group" />
  <option value="127.0.0.1">127.0.0.1</option>
  <option value="127.0.0.2">127.0.0.2</option>
</select>


[js]

var ip_group = $('#ip_group').val();

$.ajax({
        url:'/project/server_info',
        type:'POST',
        data: {ip_group:ip_group},
        success: function(data){
           showAlert('Server Info', data.info, 2, 2000);
       }     


[python + flask]

@project_blueprint.route('project/server_info', methods=['POST'])
@login_required
def project_server_info():
    ip_group = request.form.getlist('ip_group[]')
    
    ql = text('select a, b, c, d, e from tblServer where ip in :ip_group')
    connection = db.session.connection()
    results = db.engine.execute(sql, ip_group=ip_group)
    
    if results != None:
        details = []
        
        for r in results:
            details.append(r[0])
            details.append(r[1])
            details.append(r[2])
            details.append(r[3])
            details.append(r[4])
            
        return jsonify(details=details)

참고

https://stackoverflow.com/questions/8603088/sqlalchemy-in-clause

commands

telegram 대화창에 /명령 형태로 전달

/dm_oncall 메시지를 python 코드로 확인 후 message 전달

--------------

@bot.message_handler(commands=['dm_oncall'])
    def trigger(message):
        print("## bot.message_handler dm_oncall message => ", message)
        print("## bot.message_handler dm_oncall message.text => ", message.text)

        cmd = message.text
		
		#message send 
		msg_text = """ Select Day """
		bot.send_message(message.chat.id, msg_text)
		
		#button message send 
        button_list = show_button(["Yesterday", "Today", "Tomorrow"],"oncall", 1)
        bot.send_message(message.chat.id, "당직을 확인할 날짜를 선택하세요", reply_markup=button_list)

call_back

telegram의 대화가 출력되는 부분에 버튼 형태로 전달

버튼이름은 대화창에 출력되고, call_back 변수에 지정한 메시지는 대화창에 보여지지 않고 백그라운드에서 python에서 mssage를 캡쳐하여 처리 가능

php 코드로 telegram에 버튼형태로 call_back에 message 추가하여 전달

---------

$body = file_get_contents("php://input");
$obj = json_decode($body);
$bot_query = 'https://api.telegram.org/bot'.$obj->bot_token;
$chat_id = $obj->chat_id;

# send text
$text = 'Keyboard message test !!';

$keyboard = array(
    "inline_keyboard" => array(
        array(
            array(
                "text" => "Manager",
                "callback_data" => "/manager test"
            )
        )
    )
);
$keyboard = json_encode($keyboard, true);

$sendto = $bot_query.'/sendMessage?chat_id='.$chat_id.'&parse_mode=HTML&reply_markup='.$keyboard.'&text='.urlencode($text);

$response = file_get_contents($sendto);

Keyboard Button

telegram의 대화창에 아닌, 메시지 입력창에 버튼형태로 메시지를 전달

 

python 코드로 메시지 입력창에 버튼 형태로 전달

-----------

import telebot
from telegram import InlineKeyboardButton, InlineKeyboardMarkup, KeyboardButton, ReplyKeyboardMarkup

token = '14????????:XXXXXXX_XXXXX-XXXXXXXXXXXXXXX'
bot = telebot.TeleBot(token)


@bot.callback_query_handler(func=lambda c: "manager" in c.data.split(",")[0])
def manager_callback(call):

    print("## bot.callback_query_handler call.data => ", call.data)
    print("## bot.callback_query_handler call.message => ", call.message)

    try:
        data_selected = call.data

        data_oncall_Yesterday = '/dm_oncall ,Yesterday'
        data_oncall_Today = '/dm_oncall ,Today'
        data_oncall_Tomorrow = '/dm_oncall ,Tomorrow'
        data_oncall_Cancel = '/Cancel'

        main_menu_keyboard = {"keyboard":[[data_oncall_Yesterday],[data_oncall_Today],[data_oncall_Tomorrow],[data_oncall_Cancel]],"resize_keyboard": True,"one_time_keyboard": True}
        print("## main_menu_keyboard => ", main_menu_keyboard)

        bot.send_message(chat_id=call.message.chat.id, text='Select Menu.', reply_markup=json.dumps(main_menu_keyboard))

    except BaseException as e:
        print("## [Exception] manager_callback ==> ",str(e))

 

참고

https://blog.psangwoo.com/coding/2018/08/20/python-telegram-bot-4.html

 

용어

계정 : 하나의 주체입니다.  
사용자 혹은 bot등이 여기 해당됩니다.

채널 : 열린 채팅방입니다.
그룹이 단순히 여러명이 모여 대화를 나누는 곳이라면 여기에는 그 이상의 기능이 가능합니다.  
채널을 공개하여 여러 사람이 들어올 수도 있으며 관리자등을 지정하고 이들만 채팅이 가능하도록 하는 등 알림용도로도 사용이 가능합니다.  

BotFather : bot을 생성, 관리할 수 있는 계정(bot 형태)입니다.  
BotFather과 대화로 bot을 생성하고 여러 기능을 설정할 수 있습니다.

telegram 대화상대에서 BotFather를 검색하여 추가해 줍니다

시작

/start

bot 이름 및 아이디 설정

/newbot

순서 : 이름 입력 -> 아이디 입력

이름 : bot의 이름으로, 채팅방에서 보이는 이름입니다. ( 예제는 bill_bot )

아이디 : username으로 변수로 처리되며, 아이디에 있는 @로 시작하는 부분이 username입니다.

           봇을 검색할 때 사용됩니다.

bot 생성 과정

마지막에 검은색 박스로 쳐진 부분이 있습니다.

이 부분은 token(토큰)으로 xxxx:yyyyyy 형태로 이루어 져 있습니다.

토큰이 있으면 해당 계정(여기서는 봇)의 권한을 거의 전부 사용할 수 있다고 보시면 됩니다.

그렇기에 관리를 해주시는 것이 필수입니다.

python으로 넘어가기 전에 한가지 준비를 해주어야 합니다.

현재 봇은 생성되었지만 저에게 메세지를 보낼 수 없습니다.

왜냐하면 제가 누군지 모르니까요.

그렇기에 봇에게 먼저 말을 걸어보고 파이썬으로 넘어가도록 하겠습니다.

BotFather를 추가했던 것 처럼 봇의 아이디를 검색하여 채팅을 시작합니다.

메세지는 아무거나 보내도 됩니다.

 

telegram python api 설치

$ pip install python-telegram-bot --upgrade

python 으로 message 받기

import telegram   #텔레그램 모듈을 가져옵니다.

my_token = '여기에 토큰을 입력해 주세요'   #토큰을 변수에 저장합니다.

bot = telegram.Bot(token = my_token)   #bot을 선언합니다.

updates = bot.getUpdates()  #업데이트 내역을 받아옵니다.

for u in updates :   # 내역중 메세지를 출력합니다.

print(u.message)

응답(메세지는 이렇게 많은 데이터를 담고 있습니다. 일부분은 사생활 보호를 위해(?) 삭제하였습니다.)

{
  'caption':'',
  'text':'봇 테스트',
  'new_chat_title':'',
  'entities':[
  ],
  'delete_chat_photo':False,
  'message_id':6,
  'chat':{
    'username':'보호',
    'title':'',
    'first_name':'보호',
    'id':보호,
    'last_name':'보호',
    'all_members_are_admins':False,
    'type':'private'
  },
  'group_chat_created':False,
  'from':{
    'first_name':'보호',
    'id':보호,
    'last_name':'Park',
    'type':'',
    'username':'bill_park'
  },
  'supergroup_chat_created':False,
  'date':1481120854,
  'migrate_from_chat_id':0,
  'migrate_to_chat_id':0,
  'channel_chat_created':False,
  'new_chat_photo':[
  ],
  'photo':[
  ]
}

u.message에서 텍스트(내용), 누구한테서 왔는지, 발신자의 id(username과 동일하게 사용됩니다.)등을 볼 수 있습니다.

만약 수신한 텍스트(내용)만 보려면 u.message.text 를 사용하면 됩니다.

이제 메세지를 보내볼 차례입니다.

메세지를 보내기 위해서는 보낼 상대의 username - api에서 말하는 chat_id를 알아야 합니다.

bot을 테스트 할 때 메세지를 보내 두었다면 또 위의 예제가 잘 실행되었다면 u.message.chat.id 로 메세지를 보낸 사람의 chat_id를 알아낼 수 있습니다.

chat 그룹 안의 id부분이 chat_id를 나타내고 있습니다.

chat_id = bot.getUpdates()[-1].message.chat.id #가장 최근에 온 메세지의 chat id를 가져옵니다

bot.sendMessage(chat_id = chat_id, text="저는 봇입니다.")

그러면 bot이 메세지를 보낸 것을 확인할 수 있습니다.

참고

https://blog.psangwoo.com/coding/2016/12/08/python-telegram-bot-1.html

Python flask

test edit : db 데이터 수정 이후, 실행 결과를 리턴

test list : db의 table 조회 이후, 여러 행을 리스트 형태로 리턴

test detail : db 데이터 조회 결과가 1건인 경우, json 형태로 리턴

from flask import render_template, request, flash, redirect, url_for, Blueprint, Markup, jsonify, session, make_response
from flask_sqlalchemy import SQLAlchemy
from sqlalchemy import text, update
from sqlalchemy.exc import SQLAlchemyError

@bts_blueprint.route('test/edit', methods=['POST'])
def test_edit():

    print("## test_edit ##")

    try:
        # 처리 변수
        numId = request.form['id']
        strName = request.form['name']

        # 처리 로직
        sql = text('update tblTest set name = :strName where id = :numId')
        connection = db.session.connection()
        db.engine.execute(sql, numId=numId, strName=strName)
                
        return jsonify(message="Edit Success"), 200

    except (RuntimeError, TypeError, NameError, SQLAlchemyError) as e:
        print("#### Edit Failed !! " + str(e))
        db.session.rollback()

        return jsonify(message=str(e)), 1000
        
        
@bts_blueprint.route('test/list', methods=['POST'])
def test_list():

    print("## test_list ##")

    # 처리 변수
    numId = request.form['id']

    # 처리 로직
    sql = text('select a, b, c, d, e from tblTest where id > :numId')
    connection = db.session.connection()
    results = db.engine.execute(sql, numId=numId)
                
    return render_template('test.html', results=list(results))


@bts_blueprint.route('test/detail', methods=['POST'])
def test_detail():

    print("## test_detail ##")

    # 처리 변수
    numId = request.form['id']

    # 처리 로직
    sql = text('select a, b, c from tblTest where id = :numId')
    connection = db.session.connection()
    results = db.engine.execute(sql, numId=numId)

    if results != None:
        results_detail = {}
        for r in results:
            results_detail['a'] = r[0]
            results_detail['b'] = r[1]
            results_detail['c'] = r[2]
            
    return jsonify(results_detail=results_detail)

javascript

funtion test_edit()
{
    // Test edit
    $.ajax({
        url:'/test/edit',
        type:'POST',
        data: {id:id, name:name},
        success: function(data){
            //Success
            showAlert('Edit Successful!!!', '', 2, 2000);
        },
        error: function(xhr, ajaxOptions, thrownError) {
            var err_msg = JSON.parse(xhr.responseText);

            if (thrownError == 'UNKNOWN'){
                fail_msg = err_msg.message + ' (' + xhr.status + ')'
            } else {
                fail_msg = err_msg.message + ' (' + thrownError + ',' + xhr.status + ')';
            }
            showAlert('Edit Fail...','', 4, 3000);
        }
    });
}


funtion test_list()
{
    // Test list
    $.ajax({
        url:'/test/list',
        type:'POST',
        data: {id:id},
        success: function(data){
            //Success
            for(var key in data){
                console.log(key, data[key]);
            }
            
            showAlert('detail Successful!!!', '', 2, 2000);
        },
        error: function(xhr, ajaxOptions, thrownError) {
            var err_msg = JSON.parse(xhr.responseText);

            if (thrownError == 'UNKNOWN'){
                fail_msg = err_msg.message + ' (' + xhr.status + ')'
            } else {
                fail_msg = err_msg.message + ' (' + thrownError + ',' + xhr.status + ')';
            }
            showAlert('list Fail...','', 4, 3000);
        }
    });
}


funtion test_detail()
{
    // Test detail
    $.ajax({
        url:'/test/detail',
        type:'POST',
        data: {id:id},
        success: function(data){
            //Success
            detail_a = data.results_detail.a
            detail_b = data.results_detail.b
            detail_c = data.results_detail.c
            
            showAlert('detail Successful!!!', '', 2, 2000);
        },
        error: function(xhr, ajaxOptions, thrownError) {
            var err_msg = JSON.parse(xhr.responseText);

            if (thrownError == 'UNKNOWN'){
                fail_msg = err_msg.message + ' (' + xhr.status + ')'
            } else {
                fail_msg = err_msg.message + ' (' + thrownError + ',' + xhr.status + ')';
            }
            showAlert('detail Fail...','', 4, 3000);
        }
    });
}

어제

from datetime import datetime, date, timedelta

yesterday = date.today() - timedelta(1)
yesterday_text = yesterday.strftime('%Y-%m-%d 00:00:00')

달의 첫번째 일

from datetime import datetime, date, timedelta
import calendar


now_date = datetime.datetime.now()
month_frist_text = now_date.replace(day = 1).strftime("%Y-%m-%d 00:00:00")

달의 마지막 일

from datetime import datetime, date, timedelta
import calendar

now_date = datetime.datetime.now()
month_last_text = now_date.replace(day = calendar.monthrange(now_date.year, now_date.month)[1]).strftime("%Y-%m-%d 23:59:59")

 

datetime모듈내의 클래스

클래스 내용
datetime.date 일반적으로 사용되는 그레고리안 달력(Gregorian Calendar)의 년, , 일을 나타냄
datetime.time 시간을 시, , , 마이크로초, 시간대(Time zone)로 나타냄
datetime.datetime date클래스와 time클래스의 조합으로 년, , , , , , 마이크로초, 시간대 정보를 나타냄
datetime.timedelta 두 날짜 혹은 시간 사이의 기간을 표현

datetime.date 클래스

datetime.date클래스는 일반적으로 사용되는 년, , 일로 표기되는 그레고리안 달력의 날짜를 표현함

생성자 : datetime.date(year, month, day)

숫자로 년, , 일을 입력받아서 date객체를 생성

- year : 1 ~ 9999

- month : 1 ~ 12

- day : 1 ~ 해당월의 마지막 날짜

>>> import datetime
>>> D=datetime.date(2013,2,18)
>>> D
datetime.date(2013, 2, 18)
>>> print(D)
2013-02-18
>>> D=datetime.date(2013,2,31) #해당월의 최대일수를 넘으면 ValueError발생
Traceback (most recent call last):
  File "<pyshell#194>", line 1, in <module>
    D=datetime.date(2013,2,31)
ValueError: day is out of range for month

datetime.date클래스 속성

속성 내용
year (읽기전용)
month (읽기전용)
day (읽기전용)
max date객체의 최댓값
(9999,12,31)
min date객체의 최솟값
(1,1,1)
>>> import datetime
>>> D=datetime.date(2013,2,18)
>>> D.year #년
2013
>>> D.month #월
2
>>> D.day #일
18
>>> D.max #date객체의 최댓값
datetime.date(9999, 12, 31)
>>> D.min #date객체의 최솟값
datetime.date(1, 1, 1)

today()

현재 시스템의 오늘 날짜 date객체를 반환

>>> import datetime
>>> datetime.date.today()
datetime.date(2013, 3, 29)

replace(year, month, day)

입력된 인자로 변경된 date객체를 반환, 원본객체는 변경되지 않음

변경하려는 속성만 명시적으로 전달할수 있음

>>> import datetime
>>> a=datetime.date.today()
>>> a
datetime.date(2013, 3, 29)
>>> b=a.replace(day=1) #a객체에서 day만 변경
>>> a
datetime.date(2013, 3, 29) #원본은 변경되지 않음
>>> b
datetime.date(2013, 3, 1)

weekday()

요일을 정수로 변환하여 반환

:0, :1, :2, :3, :4, :5, :6

>>> import datetime
>>> a=datetime.date.today()
>>> a.weekday()
4

isoformat()

date객체의 정보를 "YYYY-MM-DD"형태의 문자열로 반환

>>> import datetime
>>> D=datetime.date.today()
>>> D.isoformat()
'2013-03-29'

strftime(format)

지정된 포맷에 맞춰 datetime.date객체의 정보를 문자열로 반환

지시자 내용
%y 연도를 축약하여 표시('13')
%Y 연도를 축약하지 않고 표시('2013')
%b 축약된 월이름('Mar')
%B 축약되지 않은 월 이름('March')
%m 숫자로 표현한 월(01~12)
%d (01~31)
%H 24시를 기준 시(00~23)
%I(아이) 12시를 기준 시(01~12)
%M (00~59)
%S (00~61)
%p 오전(AM)/오후(PM) 표시 ('AM')
%a 축약된 요일 이름('Fri')
%A 축약되지 않은 요일이름('Friday')
%w 요일을 숫자로 표시
(:0, :1, :2, :3, :4, :5, :6)
%j 1 1일부터 누적된 날짜(001~366)

microsecond = %f

time모듈의 strftime메서드와 형식지시자가 같음

>>> import datetime
>>> D=datetime.date(2013,2,18)
>>> D.strftime('%Y %m %d')
'2013 02 18'
>>> D.strftime('%y/%m/%d %H:%M:%S') #시, 분, 초에 대한 정보는 없기때문에 '0'으로 반환됨
'13/02/18 00:00:00'

 

datetime.time클래스

time클래스는 시, , 초와 같은 시간을 표현함

생성자 : datetime.time([hour[, minute[, second[, microsecond[, tzinfo]]]]])

숫자로 시, , , 마이크로초, 시간대정보(Time Zone)을 입력받아서 time객체를 생성하며, 각 인자는 생략하거나 명시적으로 지정할수 있다.

- hour : 0 ~ 23

- minute : 0 ~ 59

- second : 0 ~ 59

- microsecond : 0 ~ 999999

>>> import datetime
>>> datetime.time(23) #시간만 입력
datetime.time(23, 0)
>>> datetime.time(23,15,45,2341) #시, 분, 초 마이크로초 입력
datetime.time(23, 15, 45, 2341)
>>> datetime.time(hour=23,second=5) #인자지정하여 입력
datetime.time(23, 0, 5)
>>> datetime.time(25) #인자허용값을 벗어난경우
Traceback (most recent call last):
  File "<pyshell#42>", line 1, in <module>
    time(25)
ValueError: hour must be in 0..23

datetime.time클래스 속성

속성 내용
hour (읽기전용)
minute (읽기전용)
second (읽기전용)
microsecond 마이크로초(읽기전용)
max time객체가 표현할수 있는 최댓값
(0,0,0,0)
min time객체가 표현할수 있는 최솟값
(23,59,59,999999)
>>> import datetime
>>> T=datetime.time(23,30,15,2904)
>>> T.hour #시
23
>>> T.minute #분
30
>>> T.second #초
15
>>> T.microsecond #마이크로초
2904
>>> T.max #time객체의 최댓값
datetime.time(23, 59, 59, 999999)
>>> T.min #time객체의 최솟값
datetime.time(0, 0)

isoformat()

time객체의 값을 "HH:MM:SS.mmmmmm'형식이나

'HH:MM:SS'형식(micro초가 없는경우)의 문자열을 반환

>>> import datetime
>>> T=datetime.time(23,30,15,3759)
>>> T.isoformat()
'23:30:15.003759'

strftime(format)

지정된 포맷에 맞춰 datetime.time객체의 정보를 문자열로 반환

지시자 내용
%y 연도를 축약하여 표시('13')
%Y 연도를 축약하지 않고 표시('2013')
%b 축약된 월이름('Mar')
%B 축약되지 않은 월 이름('March')
%m 숫자로 표현한 월(01~12)
%d (01~31)
%H 24시를 기준 시(00~23)
%I(아이) 12시를 기준 시(01~12)
%M (00~59)
%S (00~61)
%p 오전(AM)/오후(PM) 표시 ('AM')
%a 축약된 요일 이름('Fri')
%A 축약되지 않은 요일이름('Friday')
%w 요일을 숫자로 표시
(:0, :1, :2, :3, :4, :5, :6)
%j 1 1일부터 누적된 날짜(001~366)

time모듈의 strftime메서드와 형식지시자가 같음

>>> import datetime
>>> T=datetime.time(23,30,15,3759)
>>> T.strftime('%Y %m %d %H:%M:%S:')
'1900 01 01 23:30:15:'

datetime.datetime 클래스

datetime클래스는 date클래스와 time클래스의 조합으로 이루어져 있다.

생성자 : datetime.datetime(yesr, month, day[, hour[, minute[, second[, microsecond[, tzinfo]]]]])

숫자로 각 인자를 받아서 datetime객체를 생성하며, , , 일은 생략이 불가하다.

명시적으로 인자를 지정하여 입력할수 있고, 생략된 인자는 0으로 초기화된다.

- year : 1 ~ 9999

- month : 1 ~ 12

- day : 1 ~ 해당월의 마지막 날짜

- hour : 0 ~ 23

- minute : 0 ~ 59

- second : 0 ~ 59

- microsecond : 0 ~ 999999

>>> import datetime
>>> datetime.datetime(2013,2,18) #년, 월, 일만 입력
datetime.datetime(2013, 2, 18, 0, 0)
>>> datetime.datetime(2013,2,hour=23,second=30,day=18) #명시적으로 인자를 지정
datetime.datetime(2013, 2, 18, 23, 0, 30)
>>> datetime.datetime(2013) #월,일인자가 생략되어 Error발생
Traceback (most recent call last):
  File "<pyshell#89>", line 1, in <module>
    datetime(2013)
TypeError: Required argument 'month' (pos 2) not found

datetime.datetime클래스 속성

속성 내용
year (읽기전용)
month (읽기전용)
day (읽기전용)
hour (읽기전용)
minute (읽기전용)
second (읽기전용)
microsecond 마이크로초(읽기전용)
max datetime객체가 표현할수 있는 최댓값
(9999,12,31,23,59,59,999999)
min datetime객체가 표현할수 있는 최솟값
(1,1,1)

datetime.datetime객체를 생성하는 클래스메서드

>today()

현재 LST 기준의datatime객체를 생성

>>> import datetime
>>> datetime.datetime.today()
datetime.datetime(2013, 3, 29, 4, 30, 17, 967000)

now([tz])

현재 LST기준의 datetime객체를 생성

시간대 정보가 입력되지 않으면 플랫폼의 시간대를 그대로 사용

>>> import datetime
>>> datetime.datetime.now()
datetime.datetime(2013, 3, 29, 4, 33, 3, 498000)

utcnow()

UTC기준의datetime객체를 생성

>>> import datetime
>>> datetime.datetime.utcnow()
datetime.datetime(2013, 3, 28, 19, 36, 38, 170000)

fromtimestamp(timestamp[,tz])

타임스탬프를 지방 기준의 datetime객체를 생성

>>> import datetime,time
>>> datetime.datetime.fromtimestamp(time.time())
datetime.datetime(2013, 3, 29, 4, 43, 48, 201000)

utcfromtimestamp(timestamp)

타임스탬프를 UTC기준의 datetime객체를 생성

>>> import datetime,time
>>> datetime.datetime.utcfromtimestamp(time.time())
datetime.datetime(2013, 3, 28, 19, 44, 46, 358000)

strptime(date_string,format)

시간을 표현한 사용자가 정의한 형식문자열을 이용하여 datetime객체를 생성

지시자 내용
%y 연도를 축약하여 표시('13')
%Y 연도를 축약하지 않고 표시('2013')
%b 축약된 월이름('Mar')
%B 축약되지 않은 월 이름('March')
%m 숫자로 표현한 월(01~12)
%d (01~31)
%H 24시를 기준 시(00~23)
%I(아이) 12시를 기준 시(01~12)
%M (00~59)
%S (00~61)
%p 오전(AM)/오후(PM) 표시 ('AM')
%a 축약된 요일 이름('Fri')
%A 축약되지 않은 요일이름('Friday')
%w 요일을 숫자로 표시
(:0, :1, :2, :3, :4, :5, :6)
%j 1 1일부터 누적된 날짜(001~366)

time모듈의 strftime메서드와 형식지시자가 같음

>>> import datetime,time
>>> timestring=time.ctime(1234567890)
>>> timestring
'Sat Feb 14 08:31:30 2009'
>>> datetime.datetime.strptime(timestring,"%a %b %d %H:%M:%S %Y")
datetime.datetime(2009, 2, 14, 8, 31, 30)

date()

원본객체의 년, , 일 정보를 가지고 있는 date객체를 반환

>>> import datetime
>>> DT=datetime.datetime(2013,2,18,22,30,15)
>>> D=DT.date()
>>> D
datetime.date(2013, 2, 18)

time()

원본객체의 시, , , 마이크로초를 가지고 있는 time객체를 반환

>>> import datetime
>>> DT=datetime.datetime(2013,2,18,22,30,15)
>>> T=DT.time()
>>> T
datetime.time(22, 30, 15)

replace()

입력된 값으로 변경된 datetime객체를 반환, 원본객체는 변경되지 않음

>>> import datetime
>>> DT=datetime.datetime(2013,2,18,22,30,15)
>>> DT_1=DT.replace(year=1987)
>>> DT
datetime.datetime(2013, 2, 18, 22, 30, 15)
>>> DT_1
datetime.datetime(1987, 2, 18, 22, 30, 15)

isoformat()

datetime객체를 'YYYY-MM-DDTHH:MM:SS.mmmmmm'형식으로 변환하여 문자열로 반환

마이크로초가 0인경우 '.mmmmmm'부분은 생략됨

>>> import datetime
>>> DT=datetime.datetime.today()
>>> DT.isoformat()
'2013-03-29T07:57:58.014000'
>>> DT.replace(microsecond=0).isoformat() #마이크로초가 0인경우
'2013-03-29T07:57:58'

strftime(format)

지정된 포맷형식에 맞추어 datetime.datetime객체를 문자열로 반환

지시자 내용
%y 연도를 축약하여 표시('13')
%Y 연도를 축약하지 않고 표시('2013')
%b 축약된 월이름('Mar')
%B 축약되지 않은 월 이름('March')
%m 숫자로 표현한 월(01~12)
%d (01~31)
%H 24시를 기준 시(00~23)
%I(아이) 12시를 기준 시(01~12)
%M (00~59)
%S (00~61)
%p 오전(AM)/오후(PM) 표시 ('AM')
%a 축약된 요일 이름('Fri')
%A 축약되지 않은 요일이름('Friday')
%w 요일을 숫자로 표시
(:0, :1, :2, :3, :4, :5, :6)
%j 1 1일부터 누적된 날짜(001~366)

time모듈의 strftime메서드와 형식지시자가 같음

>>> import datetime
>>> DT=datetime.datetime.today()
>>> DT.strftime('%Y-%m-%d %H:%M:%S %a')
'2013-03-29 08:04:55 Fri'

datetime.timedelta

datetime.timedelta클래스는 두 날짜 혹은 시간 사이의 기간을 표현한다.

인자는 양수인경우 현시점으로부터 이후를 나타내며, 음수인경우 현시점 이전을 나타낸다.

생성자 : datetime.timedelta([days[, seconds[, microseconds[, milliseconds[, minutes[, hours[, weeks]]]]]]]])

>>> import datetime
>>> datetime.timedelta(days=-3) #3일 이전
datetime.timedelta(-3)
>>> datetime.timedelta(hours=7) #7시간 이후
datetime.timedelta(0, 25200)
>>> datetime.timedelta(weeks=2,days=3,hours=-3,minutes=30)
datetime.timedelta(16, 77400)
>>> datetime.timedelta(minutes=3,milliseconds=-20,microseconds=400)
datetime.timedelta(0, 179, 980400)

생성되는 timedelta객체의 값을 확인해보면 생성자에 전달된 값과 다른것을 알수 있다.

그 이유는 동일한 기간을 표현하는 방식이 다양하게 표현(1weeks 7days는 동일함)될수 있기 대문에, 입력된 값을 가지고 timedelta객체에서 정규화과정을 거쳐 유일한 표현방식으로 변경하기 때문이다.

정규화 결과 timedelta객체 저장되는 값은 아래와 같다.

- days : -999999999 ~ 999999999

- seconds : 0 ~ 86399(24시간을 초로 환산하면 86400)

- microseconds : 0 ~ 999999

그렇기 때문에 timedelta객체를 이용하여 표현할수 있는 가장 작은 값으 정규화과정을 거치면 아래와 같다.

>>> datetime.timedelta(microseconds=-1) #현재 이전으로 가장 작은값
datetime.timedelta(-1, 86399, 999999)
>>> datetime.timedelta(microseconds=1) #현재 이후로 가장 작은값
datetime.timedelta(0, 0, 1)

시간, 날짜의 연산

생성된 timedelta클래스객체를 이용하여 아래의 연산을 수행할수 있다.

연산결과로는 모두 timedelta객체가 반환된다.

- timedelta_3 = timedelta_1 + timedelta_2

- timedelta_3 = timedelta_1 - timedelta_2

- timedelta_3 = timedelta_1 * int = int * timedelta_1

- timedelta_2 = timedelta_1 // int

- abs(timedelta)

>>> from datetime import timedelta
>>> td_1 = timedelta(hours=7) #현재로부터 7시간 이후
>>> td_2 = timedelta(days=-3) #현재로부터 3일 이전
>>> td_1 + td_2 #두 timedelta의 합
datetime.timedelta(-3, 25200) #7시간 = 25200초
>>> td_1 - td_2 #두 timedelta의 차
datetime.timedelta(3, 25200)
>>> td_1 * 4 #timedelta와 정수의 곱
datetime.timedelta(1, 14400) #28시간 = 1일4시간 = 1일14400초
>>> td_1 // 3 #25200초 // 3
datetime.timedelta(0, 8400)
>>> abs(td_2) #기간의 절대값
datetime.timedelta(3)

비교 연산

>>> from datetime import timedelta
>>> td_1 = timedelta(hours=7)
>>> td_2 = timedelta(days=-3)
>>> td_1 > td_2
True
>>> td_1 < td_2
False
>>> td_1 = timedelta(hours=24) #24시간 = 86400초
>>> td_2 = timedelta(seconds=86400)
>>> td_1 == td_2
True

생성된 timedelta객체를 이용하여 date, datetime객체를 변경할수 있다. 지원하는 연산은 아래와 같으며, 각 객체간의 비교연산도 가능하다.

- date_2 = date_1 + timedelta

- date_2 = date_1 - timedelta

- timedelta = date_2 - date_1

- datetime_2 = datetime_1 + timedelta

- datetime_2 = datetime_1 - timedelta

- timedelta = datetime_1 - datetime_2

>>> from datetime import timedelta, date
>>> d = date.today()
>>> d
datetime.date(2013, 3, 29)
>>> td=timedelta(days=3) #timedelta를 3일로 설정
>>> d + td #오늘로부터 3일 후
datetime.date(2013, 4, 1)
>>> d - td #오늘로부터 3일 전
datetime.date(2013, 3, 26)

 date객체 사이의 기간(timedelta)을 구하기 위해서는 아래와 같이 '-'연산으로 측정가능하며, date객체간의 비교연산도 가능하다.

>>> from datetime import timedelta, date
>>> d = date.today()
>>> d2 = d.replace(day=20)
>>> d2
datetime.date(2013, 3, 20)
>>> dt = d - d2
>>> dt
datetime.timedelta(9)
>>> d2 > d
False

아래는datetime객체와 관련된 연산의 예제이다

date객체가 지원하는 모든연산이 가능하다.

>>> import datetime
>>> dt=datetime.datetime.today()
>>> dt
datetime.datetime(2013, 4, 1, 23, 41, 52, 154000)
>>> td=datetime.timedelta(days=2,hours=2) #2일 2시간
>>> dt + td #datetime객체에서 timedelta(2일 2시간)을 더함
datetime.datetime(2013, 4, 4, 1, 41, 52, 154000)
>>> dt - td #datetime객체에서 timedelta(2일 2시간)을 뺌
datetime.datetime(2013, 3, 30, 21, 41, 52, 154000)
>>> dt2 = dt.replace(month=1, day=4, hour=7) #dt 객체의 값중 월, 일, 시간을 변경
>>> dt2
datetime.datetime(2013, 1, 4, 7, 41, 52, 154000)
>>> dt- dt2 #datetime객체간의 기간
datetime.timedelta(87, 57600)
>>> dt > dt2 #비교연산
True

참고

https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=dudwo567890&logNo=130165166038

 

Python,module datetime [날짜시간]

-. datetime모듈내의 클래스 클래스 내용 datetime.date 일반적으로 사용되는 그레고리안 달력(Gregorian ...

blog.naver.com

기능

- yyyy-mm-dd HH:mm:ss 형태로 날짜 데이터 입/출력

- python flask에서 get, post 형태로 날짜 데이터 처리

 

js

<!-- jQuery -->
<script src="/ path /plugins/jquery/jquery.min.js"></script>
<!-- Select2 -->
<script src="/ path /plugins/select2/js/select2.full.min.js"></script>
<!-- InputMask -->
<script src="/ path /plugins/moment/moment.min.js"></script>
<!-- Tempusdominus Bootstrap 4 -->
<script src="/ path /plugins/tempusdominus-bootstrap-4/js/tempusdominus-bootstrap-4.min.js"></script>

css

<!-- Font Awesome -->
<link rel="stylesheet" href="/ path /plugins/fontawesome-free/css/all.min.css">
  
<!-- Select2 -->
<link rel="stylesheet" href="/ path /plugins/select2/css/select2.min.css">
<link rel="stylesheet" href="/ path /plugins/select2-bootstrap4-theme/select2-bootstrap4.min.css">
  
<!-- Tempusdominus Bootstrap 4 -->
<link rel="stylesheet" href="/ Path /plugins/tempusdominus-bootstrap-4/css/tempusdominus-bootstrap-4.min.css">

html

datetimepicker ID : search_start_time, search_end_time

datetime text ID : search_start_input, search_end_input

 

<!-- Start Time -->
<div class="form-group col-md-4">
  <div class="input-group">
	<div class="input-group date" id="search_start_time" data-target-input="nearest">
	  <span class="btn btn-warning iw-100">Start Time</span>
	  <input type="text" data-date-format='yyyy-mm-dd' class="form-control datetimepicker-input" id="search_start_input" name="search_start_input" data-target="#search_start_time"/>
	  <div class="input-group-append" data-target="#search_start_time" data-toggle="datetimepicker">
		  <div class="input-group-text"><i class="fa fa-calendar"></i></div>
		</div>
	</div>
  </div>
</div>

<!-- End Time -->
<div class="form-group col-md-4">
  <div class="input-group">
	<div class="input-group date" id="search_end_time" data-target-input="nearest">
	  <span class="btn btn-warning iw-100">End Time</span>
	  <input type="text" data-date-format='yyyy-mm-dd' class="form-control datetimepicker-input" id="search_end_input" name="search_end_input" data-target="#search_end_time"/>
	  <div class="input-group-append" data-target="#search_end_time" data-toggle="datetimepicker">
		  <div class="input-group-text"><i class="fa fa-calendar"></i></div>
		</div>
	</div>
  </div>
</div>

javascript

datetimepicker ID에 icon 및 format 적용

<script type="text/javascript">
    $(function () {
    
        //값 확인
        start_time = $('#search_start_input').val();
        end_time = $('#search_end_input').val();
    
        //Date and time picker
        $('#search_start_time').datetimepicker({ icons: { time: 'far fa-clock' }, format: 'yyyy-MM-DD HH:mm:ss' });
        $('#search_end_time').datetimepicker({ icons: { time: 'far fa-clock' }, format: 'yyyy-MM-DD HH:mm:ss' });
    });
</script>

python flask

datetime text ID로 값을 조회

#get 방식
@bts_blueprint.route('search/datetime_ex', methods=['GET'])
@login_required
def search_datetime_ex(name=''):
    
    #get 방식
    search_start_time = request.args.get('search_start_input')
    search_end_time = request.args.get('search_end_input')

    # 처리 로직
    var results = 0

    return results

#post 방식
@bts_blueprint.route('search/datetime_ex', methods=['POST'])
@login_required
def search_datetime_ex(name=''):

    search_start_time = request.form['search_start_input']
    search_end_time = request.form['search_end_input']
    
    # 처리 로직
    var results = 0
    
    return results

to Top