• openerp学习笔记 日期时间相关操作


    日期格式化字符串:DATE_FORMAT = "%Y-%m-%d"

    日期时间格式字符串:DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"

    日期时间格式字符串(包含毫秒):DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S.%f"

    OpenERP对象中字段赋值为当前日期(字符串):fields.date.context_today,fields.date.context_today(self, cr, uid, context=context),fields.date.today()

    OpenERP对象中字段赋值为当前时间(字符串):fields.datetime.now(),fields.datetime.context_timestamp(cr, uid, datetime.now(), context=context)

    OpenERP官方建议 date/datetime 的默认值的写法是fields.date.context_today,fields.datetime.now()

    字符串转换为日期时间:datetime.datetime.strptime(sale.date, DATE_FORMAT)

    日期时间转换为字符串:datetime.datetime.strftime(datetime.date.today(), DATE_FORMAT)

    python中获取当前日期:datetime.date.today()

    python中获取当前时间:datetime.datetime.now()

    OpenERP fields 单元中对 date/datetime 类中方法定义如下所示:

    复制代码
    class date(_column):
        _type = 'date'
    
        @staticmethod
        def today(*args):
            """ Returns the current date in a format fit for being a
            default value to a ``date`` field.
    
            This method should be provided as is to the _defaults dict, it
            should not be called.
            """
            return DT.date.today().strftime(
                tools.DEFAULT_SERVER_DATE_FORMAT)
    
        @staticmethod
        def context_today(model, cr, uid, context=None, timestamp=None):
            """Returns the current date as seen in the client's timezone
               in a format fit for date fields.
               This method may be passed as value to initialize _defaults.
    
               :param Model model: model (osv) for which the date value is being
                                   computed - automatically passed when used in
                                    _defaults.
               :param datetime timestamp: optional datetime value to use instead of
                                          the current date and time (must be a
                                          datetime, regular dates can't be converted
                                          between timezones.)
               :param dict context: the 'tz' key in the context should give the
                                    name of the User/Client timezone (otherwise
                                    UTC is used)
               :rtype: str 
            """
            today = timestamp or DT.datetime.now()
            context_today = None
            if context and context.get('tz'):
                tz_name = context['tz']  
            else:
                tz_name = model.pool.get('res.users').read(cr, SUPERUSER_ID, uid, ['tz'])['tz']
            if tz_name:
                try:
                    utc = pytz.timezone('UTC')
                    context_tz = pytz.timezone(tz_name)
                    utc_today = utc.localize(today, is_dst=False) # UTC = no DST
                    context_today = utc_today.astimezone(context_tz)
                except Exception:
                    _logger.debug("failed to compute context/client-specific today date, "
                                  "using the UTC value for `today`",
                                  exc_info=True)
            return (context_today or today).strftime(tools.DEFAULT_SERVER_DATE_FORMAT)
    
    class datetime(_column):
        _type = 'datetime'
        @staticmethod
        def now(*args):
            """ Returns the current datetime in a format fit for being a
            default value to a ``datetime`` field.
    
            This method should be provided as is to the _defaults dict, it
            should not be called.
            """
            return DT.datetime.now().strftime(
                tools.DEFAULT_SERVER_DATETIME_FORMAT)
    
        @staticmethod
        def context_timestamp(cr, uid, timestamp, context=None):
            """Returns the given timestamp converted to the client's timezone.
               This method is *not* meant for use as a _defaults initializer,
               because datetime fields are automatically converted upon
               display on client side. For _defaults you :meth:`fields.datetime.now`
               should be used instead.
    
               :param datetime timestamp: naive datetime value (expressed in UTC)
                                          to be converted to the client timezone
               :param dict context: the 'tz' key in the context should give the
                                    name of the User/Client timezone (otherwise
                                    UTC is used)
               :rtype: datetime
               :return: timestamp converted to timezone-aware datetime in context
                        timezone
            """
            assert isinstance(timestamp, DT.datetime), 'Datetime instance expected'
            if context and context.get('tz'):
                tz_name = context['tz']  
            else:
                registry = openerp.modules.registry.RegistryManager.get(cr.dbname)
                tz_name = registry.get('res.users').read(cr, SUPERUSER_ID, uid, ['tz'])['tz']
            if tz_name:
                try:
                    utc = pytz.timezone('UTC')
                    context_tz = pytz.timezone(tz_name)
                    utc_timestamp = utc.localize(timestamp, is_dst=False) # UTC = no DST
                    return utc_timestamp.astimezone(context_tz)
                except Exception:
                    _logger.debug("failed to compute context/client-specific timestamp, "
                                  "using the UTC value",
                                  exc_info=True)
            return timestamp
    复制代码

    应用示例代码: 

        #自动获取日期对应的月份并保存

        def _get_month(self, cr, uid, ids, field_name, arg, context=None):
            res = {}
            if context is None:
                context = {}
            DATETIME_FORMAT = "%Y-%m-%d"
            for sale in self.browse(cr, uid, ids, context=context):
                saledate = datetime.datetime.strptime(sale.date, DATETIME_FORMAT)
                res[sale.id] = saledate.strftime('%Y') + '-' + saledate.strftime('%m')
            return res
       
        _columns={
            'name':fields.char(u'单号', size=64, select=True, required=True, readonly=True),
            'date':fields.date(u'日期', select=True, required=True, readonly=True),
            'month':fields.function(_get_month, method=True, type='char', size=10, string = u'月份', store=True, invisible=True),
        }

        _defaults={
            'name': lambda obj, cr, uid, context: '/',
            'date':fields.date.context_today,
            #'employee_id':_employee_get,
            'state':'draft'
        }

        #自动计算到期日期,按开卡日期加 年数*365 天

        def _get_due_date(self, cr, uid, ids, field_name, arg, context=None):
            res = {}
            if context is None:
                context = {}
            DATE_FORMAT = "%Y-%m-%d"
            for rec in self.browse(cr, uid, ids, context=context):
                category = rec.category
                if category:
                    remaining_times=category.times_limit
                    if rec.active_date:
                        res[rec.id]=(datetime.datetime.strptime(rec.active_date, DATE_FORMAT) +  datetime.timedelta(days=category.age_limit*365)).strftime(DATE_FORMAT)
                    else:
                        res[rec.id]=(datetime.date.today()+  datetime.timedelta(days=category.age_limit*365)).strftime(DATE_FORMAT)
            return res
       
        _columns={
            "name":fields.char("卡号",size=64, required=True, readonly=True, states={'0':[('readonly',False)]}),
            "category":fields.many2one("dispatch.service_card_category","服务卡类型", required=True, readonly=True, states={'0':[('readonly',False)]}),
            'age_limit':fields.related('category', 'age_limit', string=u'年限', type='float', readonly=True, store=True),
            "times_limit":fields.integer(u"初始次数", readonly=True),
            "customer":fields.many2one("dispatch.customer","客户",required=True, select=True, readonly=True, states={'0':[('readonly',False)]}),
            "remaining_times":fields.integer("剩余次数",required=True, readonly=True, states={'0':[('readonly',False)]}),
            "active_date":fields.date("开卡日期",required=True, readonly=True, states={'0':[('readonly',False)]}),
            'due_date':fields.function(_get_due_date, method=True, type='date', string = u'到期日期', store=True),
            'state': fields.selection([('0', u'未开卡'),('1', u'已开卡'),('2', u'已用完'),('3', u'已过期'),('4', u'已锁定')], u'状态',required=True, readonly=True),
            'lock_note': fields.char(u'锁定原因', size=200, invisible=False, readonly=True, states={'1':[('readonly',False)], '4':[('readonly',False)]}),
        }
       

        # TODO: can be improved using resource calendar method
        #计算日期间隔对应的天数
        def _get_number_of_days(self, date_from, date_to):
            """Returns a float equals to the timedelta between two dates given as string."""

            DATETIME_FORMAT = "%Y-%m-%d %H:%M:%S"
            from_dt = datetime.datetime.strptime(date_from, DATETIME_FORMAT)
            to_dt = datetime.datetime.strptime(date_to, DATETIME_FORMAT)
            timedelta = to_dt - from_dt
            diff_day = timedelta.days + float(timedelta.seconds) / 86400
            return diff_day
       
        #对象字段
        _columns = {
                'date_from': fields.datetime(u'起始日期',required=True, readonly=True, states={'draft':[('readonly',False)]}, select=True),
                'date_to': fields.datetime(u'结束日期', readonly=True, states={'draft':[('readonly',False)]}),
                'days': fields.float(u'天数', digits=(8, 2), readonly=True, states={'draft':[('readonly',False)]}),
              }
            
        #更改起始日期,自动计算请假天数
        def onchange_date_from(self, cr, uid, ids, date_to, date_from):
            """
            If there are no date set for date_to, automatically set one 8 hours later than
            the date_from.
            Also update the number_of_days.
            """
            # date_to has to be greater than date_from
            if (date_from and date_to) and (date_from > date_to):
                raise osv.except_osv(_(u'警告!'),_(u'开始日期必须小于结束日期.'))

            result = {'value': {}}

            # No date_to set so far: automatically compute one 8 hours later
            if date_from and not date_to:
                date_to_with_delta = datetime.datetime.strptime(date_from, tools.DEFAULT_SERVER_DATETIME_FORMAT) + datetime.timedelta(hours=8)
                result['value']['date_to'] = str(date_to_with_delta)

            # Compute and update the number of days
            if (date_to and date_from) and (date_from <= date_to):
                diff_day = self._get_number_of_days(date_from, date_to)
                result['value']['days'] = round(math.floor(diff_day))+1
            else:
                result['value']['days'] = 0

            return result
       
        #更改结束日期,自动计算请假天数
        def onchange_date_to(self, cr, uid, ids, date_to, date_from):
            """
            Update the number_of_days.
            """
            # date_to has to be greater than date_from
            if (date_from and date_to) and (date_from > date_to):
                raise osv.except_osv(_(u'警告!'),_(u'开始日期必须小于结束日期.'))

            result = {'value': {}}

            # Compute and update the number of days
            if (date_to and date_from) and (date_from <= date_to):
                diff_day = self._get_number_of_days(date_from, date_to)
                result['value']['days'] = round(math.floor(diff_day))+1
            else:
                result['value']['days'] = 0

            return result

  • 相关阅读:
    scrapy-redis 分布式爬虫
    爬虫-框架-Scrapy
    MongoDB
    爬虫-请求库之-selenium
    通过位异或来交换a,b的值和通过中间变量交换a,b的值
    位运算
    sizeof运算符
    运算符和表达式(类型转换)
    为什么计算机存储的是二进制补码?
    各种进制的学习与转换
  • 原文地址:https://www.cnblogs.com/openerp/p/3305135.html
Copyright © 2020-2023  润新知