콘텐츠로 건너뛰기

Odoo Datetime Field 완전 정복 가이드

Odoo 데이터 모델에서 Datetime 필드를 완벽하게 이해하려면: 타임스탬프 저장 방식, 시간대(timezone) 처리, 그리고 실제 비즈니스 시나리오에서의 활용법까지 알아야 합니다. 이 가이드는 Datetime 필드의 내부 동작 방식, 데이터베이스에 어떻게 기록되는지, 서버와 사용자 환경에서 시간 계산이 어떻게 달라지는지, 그리고 재고 · 회계 · 예약 등 현업에서 흔히 마주치는 사례별 적용 방법을 한눈에 설명합니다.
2026년 3월 6일 작성자
Odoo Datetime Field 완전 정복 가이드
Dasolo
| 아직 댓글이 없습니다

소개


날짜와 시간 정보는 거의 모든 업무 흐름의 핵심입니다. 주문이 언제 들어왔는지, 배송 약속은 언제인지, 직원이 언제 출근했는지 같은 질문에 답하려면 정확한 시점 정보가 필요합니다. Odoo에서는 이런 시점 데이터를 저장하는 표준 수단으로 Datetime 필드를 사용합니다.


Date 필드는 날짜(연-월-일)만 다루하는 반면, Datetime 필드는 시간(시:분:초)까지 함께 저장합니다. 겉보기엔 사소해 보여도, 여러 시간대에서 사용자가 접속하거나 이벤트를 분 단위로 추적해야 할 때는 시간 정보가 필수적입니다.


이 문서는 Odoo에서 Datetime 필드가 무엇을 담고 어떻게 동작하는지, 데이터 모델 관점과 뷰 표현, Odoo Studio나 파이썬으로의 생성·설정 방법, 그리고 실제 비즈니스 사례까지 한 번에 정리합니다.

Odoo의 Datetime 필드란?


Odoo의 ORM에서는 fields.Datetime으로 초 단위까지 포함한 날짜·시간 값을 취급합니다. 내부적으로는 PostgreSQL의 TIMESTAMP 타입으로 저장되며, 데이터베이스에는 항상 UTC 기준으로 보관됩니다. 화면에 보여줄 때는 활성 사용자의 시간대 설정에 맞춰 자동 변환됩니다.


사용자 인터페이스에서는 Datetime 필드가 달력과 시간 입력이 결합된 선택기 형태로 나타납니다. 목록이나 리포트에서는 사용자의 언어·시간대 설정에 따라 형식화되어 보여지고, 검색 필터에서는 기간 조건(이전, 이후, 사이 등)을 지원합니다.


파이썬 모델에 Datetime 필드를 정의하면 보통 다음처럼 보입니다:

from odoo import fields, models

class SaleOrder(models.Model):
    _inherit = 'sale.order'

    x_confirmed_on = fields.Datetime(
        string='Confirmed On',
        default=fields.Datetime.now,
        readonly=True,
        copy=False,
    )

여기서 string은 화면에 노출되는 라벨을 정하고, default는 레코드 생성 시 자동 입력될 기본값을 지정합니다. readonly는 사용자가 수동으로 바꾸지 못하게 잠그는 설정으로, 감사용 타임스탬프에 자주 사용됩니다.


Odoo Studio에서는 이 필드 타입을 Date & Time이라고 부릅니다. Studio에서 생성하면 내부 이름에 자동으로 x_studio_ 접두사가 붙습니다. 코드나 XML-RPC로 만들 때는 기술적 이름을 직접 지정합니다.

필드 동작 방식


모델에 Datetime 필드를 선언하면 모듈 설치나 업그레이드 과정에서 해당 데이터베이스 컬럼이 자동으로 생성됩니다. 직접 SQL 마이그레이션을 작성할 필요는 없습니다.


많은 개발자와 사용자가 깜짝 놀라는 부분이 시간대 처리 방식입니다. 데이터베이스에는 항상 UTC로 저장됩니다. 예컨대 파리 사용자가 오후 3시로 일정을 저장하면 DB에는 UTC 기준 오후 1시로 들어갑니다. 뉴욕 사용자는 같은 레코드를 보면 자신의 로컬 시간(오전 9시)으로 표시됩니다. 이 변환은 각 사용자의 프로필에 설정된 시간대를 기준으로 ORM이 자동 처리합니다.


주요 필드 속성

Odoo에서 Datetime 필드에 자주 쓰이는 중요 속성은 다음과 같습니다:

  • default: 새 레코드 생성 시 현재 UTC 시각을 자동 채우려면 보통 fields.Datetime.now를 사용합니다.
  • required: 폼과 모델 수준에서 필드를 필수로 만듭니다.
  • readonly: 인터페이스에서 수동 편집을 막습니다. 자동 생성 타임스탬프에 유용합니다.
  • compute: 다른 필드나 로직에 기반해 파이썬 메서드로 값을 계산하도록 연결합니다.
  • store: compute와 함께 쓰면 계산 결과를 DB에 저장해 검색과 리포트에서 사용 가능하게 합니다.
  • copy: 레코드 복제 시 값을 복사할지 여부를 제어합니다. 기본값은 True이며, 이벤트 타임스탬프는 보통 False로 설정합니다.
  • index: 데이터베이스 인덱스를 생성합니다. 대량 테이블에서 일정 필드로 자주 필터링할 때 유용합니다.

뷰에서의 표시 방식

폼 뷰에서는 달력과 시간 입력이 결합된 위젯으로 보입니다. 사용자는 같은 입력에서 날짜와 시간을 설정할 수 있고, 목록 뷰에서는 언어 설정에 맞춘 문자열로 표시됩니다. 검색 뷰에서는 특정 기간 전/후/사이 같은 필터로 조회할 수 있습니다.


또한 date_range 위젯과 함께 사용하면 한 번에 기간 범위를 선택하도록 만들 수 있어, 작업 창이나 시간 기반 스케줄 관리를 구현할 때 편리합니다.


Datetime vs Date: 어떤 필드를 선택할까?

언제 fields.Datetime를 쓰고 언제 fields.Date를 쓸지에 대한 실무 규칙은 단순합니다. 하루 중 ‘시간’ 정보가 중요한 경우 Datetime을, 그렇지 않다면 Date를 사용하세요.

Date를 쓰기 좋은 예: 청구서 지급기한, 생일, 제품 유통기한, 계약 갱신일.


Datetime을 쓰기 좋은 예: 주문 확정 시각, 회의 시작 시간, 근태 출퇴근 기록, 창고 작업 스케줄.

불필요하게 Datetime을 쓰면 시간대 처리 부담만 늘어납니다. 시간 정보가 정말로 비즈니스 프로세스에 의미가 있는지 먼저 확인하세요.

실무 적용 사례


Datetime 필드는 거의 모든 Odoo 모듈에 등장합니다. 다음은 현업에서 자주 쓰이는 다섯 가지 예시입니다.


CRM: 영업 활동 추적

CRM에서는 리드가 진행 상태로 전환된 시점이나 후속 약속 기한 같은 이벤트를 Datetime으로 기록합니다. 이 값으로 응답 속도나 장기 방치된 기회를 파악하고 팀 성과를 리포트합니다. 필요하면 견적 전송 시간이나 특정 통화 시점 같은 사용자 정의 Datetime을 추가해 더 세밀한 로그를 남길 수 있습니다.


영업: 주문 확정 시각 기록

판매 주문의 date_order는 Datetime입니다. 주문이 실제로 확정된 시점을 기록해 시간대별 매출 집계, 처리 소요 시간 분석, 확정 이후의 감사 추적 등에 활용됩니다. 판매 리포트에서 이 필드를 기준으로 필터링하는 경우가 매우 많습니다.


재고: 송장·출고 예정 시각

창고 작업의 scheduled_date는 Datetime으로 입출고 예정 시각을 관리합니다. 자동화된 액션은 이 값을 기준으로 워크플로를 트리거할 수 있습니다. 예를 들어, 배송이 예정 시각을 몇 시간 초과하면 자동으로 알림 이메일을 발송해 고객과의 커뮤니케이션을 선제적으로 할 수 있습니다.


제조: 생산 시작·완료 시간

제조 현장에서는 생산 시작과 완료 시간을 Datetime으로 기록합니다. 이 데이터는 설비 가동률 계산, 효율성 리포트, 교대 근무별 성과 분석에 직접 반영됩니다. 여러 교대가 있는 환경에서는 분 단위의 정확도가 병목 구간을 파악하는 데 필수적입니다.


인사: 근태와 휴가 관리

HR 근태 모듈은 직원 출퇴근을 Datetime으로 기록하고, 휴가의 정확한 시작·종료 시점을 Datetime으로 관리합니다. 급여, 초과근무 계산은 이 값에 의존하므로 분 단위의 정확도가 중요합니다. 누락되거나 어긋난 타임스탬프는 보상 산정에 직결되는 문제입니다.

Datetime 필드 만들기 및 커스터마이즈


Odoo 모델에 Datetime 필드를 추가하는 방법은 사용 환경과 기술 선호도에 따라 크게 세 가지가 있습니다.


Odoo Studio 사용 (코드 없음)

Odoo Studio는 코드 없이 필드를 추가할 수 있는 내장 커스터마이즈 도구입니다. Studio로 Datetime 필드를 추가하려면 다음 단계를 따르세요:

  1. 메인 메뉴에서 Odoo Studio를 엽니다.
  2. 필드를 추가하려는 폼을 엽니다.
  3. 사이드바에서 Date & Time 필드를 폼으로 드래그합니다.
  4. 필드 속성 패널에서 라벨, 필수 여부, 기본값(선택 사항)을 설정합니다.
  5. 저장하고 Studio를 닫습니다.

Studio는 자동으로 x_studio_ 접두사가 붙은 필드를 생성하고 폼에 추가합니다. 데이터베이스 마이그레이션은 Odoo가 처리하므로 별도 작업이 필요 없습니다. 개발자 개입 없이 타임스탬프를 추가해야 하는 비즈니스 사용자는 이 방법을 권장합니다.


파이썬 커스텀 모듈 사용

버전 관리와 배포가 필요한 커스터마이즈는 파이썬 모듈에서 필드를 정의하는 것이 권장됩니다:


from odoo import fields, models

class ResPartner(models.Model):
    _inherit = 'res.partner'

    x_last_contact_date = fields.Datetime(
        string='Last Contact Date',
        default=fields.Datetime.now,
        copy=False,
    )

모델에 필드를 정의한 뒤에는 해당 필드를 뷰 XML에 추가해 UI에 노출해야 합니다. 모듈 설치·업그레이드 시 Odoo가 자동으로 TIMESTAMP 컬럼을 생성합니다. 직접 SQL을 작성할 필요는 없습니다.


XML-RPC API 사용

배포 스크립트나 원격 설정 자동화의 일부로 프로그래밍 방식으로 필드를 생성해야 할 때는 XML-RPC API를 통해 Datetime 필드를 만들 수 있습니다:


field_id = models.execute_kw(
    ODOO_DB, uid, ODOO_API_KEY,
    'ir.model.fields', 'create',
    [{
        'name': 'x_last_contact_date',
        'field_description': 'Last Contact Date',
        'model_id': model_id,
        'ttype': 'datetime',
        'state': 'manual',
    }]
)

ttype: 'datetime'는 Datetime 타입을 생성하겠다는 의미이고, state: 'manual'는 모듈 코드가 아니라 외부에서 수동으로 만든 필드임을 표시합니다. 자동화된 환경에서 원격 필드 생성을 할 때 이 방식이 일반적입니다.

권장 모범 사례


1. default에는 함수 레퍼런스를 쓰세요(괄호 금지)

기본값으로 현재 시각을 넣을 때는 default=fields.Datetime.now처럼 함수 객체를 전달해야 합니다. 괄호를 붙이면 클래스가 로드될 때 한 번만 실행되어 모든 레코드가 동일한 고정 시각을 갖게 됩니다. 괄호 없이 전달하면 레코드가 생성될 때마다 호출되어 정확한 생성 시각이 들어갑니다.


2. 이벤트 타임스탬프는 copy=False로 설정하세요

확정 시각이나 완료 시점처럼 발생한 시점을 기록하는 필드는 copy=False로 두어 복제 시 이전 값이 넘어가지 않게 해야 합니다. 복제된 주문이 원본의 확정일을 그대로 물려받으면 데이터 신뢰성이 깨집니다.


3. API로 쓸 때는 항상 UTC로 쓰세요

XML-RPC 등 API로 레코드를 생성·수정할 때는 Datetime 값을 UTC 기준 문자열(YYYY-MM-DD HH:MM:SS)로 전달하세요. 쓰기 시점에 시간대 변환이 자동으로 되지 않기 때문에 로컬 시간을 그대로 보내면 오프셋 오류가 생겨 나중에 찾기 어렵습니다.


4. 자동 생성 타임스탬프는 readonly로 두세요

시스템 이벤트를 반영하는 타임스탬프는 인터페이스에서 일반 사용자에게 편집 권한을 주지 않는 것이 안전합니다. 수정이 필요하면 필드 수준 보안으로 접근을 통제하세요.


5. 시간이 중요하지 않다면 Date를 선택하세요

지불기한이나 유통기한처럼 하루 단위 날짜만 필요하면 fields.Date를 사용하세요. 불필요한 시간대 처리와 UI 복잡도를 피하는 것이 데이터 모델 관리에 유리합니다.

자주 발생하는 실수


원시 값(UTC)을 직접 읽을 때의 시간대 혼동

Datetime 필드 관련 문제 중 가장 흔한 것은 DB나 API에서 직접 읽은 값이 UTC라는 사실을 간과하는 것입니다. 클라이언트에서 변환하지 않으면 리포트나 연동 결과가 몇 시간씩 어긋나게 됩니다. 외부 시스템에 API 결과를 보여줄 때는 반드시 시간대 변환 단계를 명시적으로 넣으세요.


로컬 시간 문자열을 API로 쓰는 경우

로컬 시간(예: 파리 시간)으로 포맷한 문자열을 API에 그대로 전송하면 DB에는 그 값이 UTC로 저장된 것으로 간주됩니다. 결과적으로 사용자가 보게 될 시간은 일광절약 시간 여부에 따라 한두 시간 차이가 나게 되어 프로덕션에서만 드러나는 버그를 유발합니다.


default=fields.Datetime.now() 같은 괄호 사용 실수

기본값에 괄호를 붙여 호출하면 클래스 로드 시 한 번만 평가되어 이후 만들어지는 모든 레코드가 동일한 타임스탬프를 갖게 됩니다. 초기에 정상처럼 보이지만 생성 시점 분석이 틀어지고 문제를 찾기까지 시간이 오래 걸리는 은밀한 버그입니다.


복제 시 copy=False를 깜빡하는 경우

복제된 레코드에 원본의 모든 Datetime 값이 그대로 남아 있으면 확정일, 생성시간 등 히스토리가 오염됩니다. 감사 추적과 리포트 신뢰도에 큰 악영향을 주므로 이벤트성 타임스탬프에는 반드시 copy=False를 고려하세요.


Date로도 충분한데 Datetime을 쓴 경우

청구서 지급기한처럼 시간 정보가 불필요한 곳에 Datetime을 사용하면 사용자에게 쓸데없는 시간이 표시되고, 화면마다 시간대 변환이 일어나며 시스템 복잡도가 올라가게 됩니다. 항상 비즈니스 요구사항에 맞춰 가장 단순한 타입을 선택하세요.

맺음말


요약하자면 Datetime 필드는 시간 정밀도가 비즈니스에 중요할 때 매우 유용합니다. 리드 오픈 시각, 생산 시작·종료, 근태 기록 등 거의 모든 모듈에서 활용됩니다.


가장 중요한 점은 Odoo가 DB에 UTC로 저장한다는 모델입니다. UI는 사용자 시간대로 보여주지만 외부 읽기·쓰기(API)는 이 점을 명확히 처리해야 시간대 관련 버그를 예방할 수 있습니다. 대부분의 시간대 이슈는 이 오해에서 출발합니다.


또한 올바른 기본값 문법을 사용하고, 이벤트 타임스탬프에는 copy=False를 적용하며, 시간이 필요 없으면 Date를 선택하는 작은 습관들이 데이터 모델을 깔끔하게 유지하고 보고서 신뢰도를 높입니다.

Dasolo는 기업들이 Odoo를 도입·커스터마이즈·최적화하도록 지원합니다. 견고한 데이터 모델 설계, 워크플로우에 맞는 커스텀 필드 추가, 모듈 개발 등 필요한 모든 단계를 도와드립니다. 문의하기 귀사의 Odoo 프로젝트에 대해 이야기해 보세요.

Odoo Datetime Field 완전 정복 가이드
Dasolo 2026년 3월 6일
이 게시물 공유하기
로그인 의견을 남기기