python 时间和时间戳

一、基础概念

  • UTC time:世界标准时间
    • 东N区的本地时间 = UTC time + N小时
    • 西N区的本地时间 = UTC time - N小时
  • epoch time:时间开始的起点(对Unix而言,epoch time为 1970-01-01 00:00:00 UTC)
  • timestamp:时间戳(也称为Unix时间 或 POSIX时间)
    • 时间戳是个差值,其值与时区无关
    • 1970-01-01 00:00:00 UTC到现在经过的秒数

二、 获取时间戳的方法

  1. 方法一:time直接产生时间戳

    import time
    
    timestamp1 = time.time()
    print(timestamp1)  # 输出=>  1623238666.627778
    
  2. 方法二:time.struct_time转化为时间戳

    import time
    
    struct_time_instance = time.localtime()
    print(struct_time_instance)
    # 输出=> time.struct_time(tm_year=2021, tm_mon=6, tm_mday=9, tm_hour=19, tm_min=46, tm_sec=12, tm_wday=2, tm_yday=160, tm_isdst=0)
    timestamp2 = time.mktime(struct_time_instance)
    print(timestamp2)  # ==> 1623238666.0
    
  3. 方法三:datetime.datetime产生的时间转化为时间戳

    from datetime import datetime
    
    today = datetime.today()
    print(today, type(today))  # 输出=> 2021-06-09 19:54:07.773130 <class 'datetime.datetime'>
    timestamp3 = datetime.timestamp(today)
    print(timestamp3) # 输出=> 1659592438.965032
    

三、时间戳转化为时间

3.1 time类

  1. 方法一:时间戳 => 时间字符串

    import time
    
    local_time1 = time.ctime(1623238666)
    print(local_time1)  # 输出=>  Wed Jun  9 19:37:46 2021
    
  2. 方法二:时间戳 => struct_time对象

    import time
    
    local_time2 = time.localtime(1623238666)
    print(local_time2, type(local_time2))
    # 输出=> time.struct_time(tm_year=2021, tm_mon=6, tm_mday=9, tm_hour=19, tm_min=37, tm_sec=46, tm_wday=2, tm_yday=160, tm_isdst=0)
    
  3. 方法三: => utc时间(与当前时间差8个小时)东八区

    import time
    
    utc_time1 = time.gmtime(1623238666)
    print(utc_time1)
    # 输出=> time.struct_time(tm_year=2021, tm_mon=6, tm_mday=9, tm_hour=11, tm_min=37, tm_sec=46, tm_wday=2, tm_yday=160, tm_isdst=0)
    

3.2 datetime类

  1. 方法四:时间戳 => datetime对象

    from datetime import datetime
    
    local_time4 = datetime.fromtimestamp(1623238666)
    print(local_time4, type(local_time4))  # 输出=> 2021-06-09 19:37:46 <class 'datetime.datetime'>
    
  2. 方法五:时间戳 => utc时间

    from datetime import datetime
    
    utc_time2 = datetime.utcfromtimestamp(1623238666)
    print(utc_time2, type(utc_time2))  # 输出=> 2021-06-09 11:37:46
    

四、格式化时间

  1. 方法一:时间字符串 => struct_time时间对象

    import time
    
    time_str = '2021-6-9 20:20'
    struct_time1 = time.strptime(time_str, '%Y-%m-%d %H:%M')
    print(struct_time1)
    # 输出=> time.struct_time(tm_year=2021, tm_mon=6, tm_mday=9, tm_hour=20,    tm_min=20, tm_sec=0, tm_wday=2, tm_yday=160, tm_isdst=-1)
    
  2. 方法二:struct_time时间对象 => 时间字符串

    import time
    
    struct_time2 = time.localtime(1623238666)
    string_time1 = time.strftime('%Y-%m-%d %H:%M', struct_time2)
    print(string_time1) # =>2021-06-09 19:37
    
  3. 方法三:时间字符串 => datetime

    import datetime
    
    time_str = "2022-08-04 13:51:18.877221"
    date_time = datetime.datetime.strptime(time_str, '%Y-%m-%d %H:%M:%S.%f')
    

五、获取当前时间

  1. 方法一:获取time.struct_time类型的时间

    import time
    
    localtime = time.localtime(time.time())
    print("本地时间为 :", localtime)
    # 输出 => time.struct_time(tm_year=2021, tm_mon=6, tm_mday=18, tm_hour=17,  tm_min=24, tm_sec=9, tm_wday=4, tm_yday=169, tm_isdst=0)
    
  2. 方法二:获取字符串的时间

    import time
    
    localtime = time.asctime(time.localtime(time.time()))
    print("本地时间为 :", localtime, type(localtime))  # => Thu Apr  7 10:29:13 2016
    
  3. 方法三:today() 获取datetime.datetime类型

    from datetime import datetime
    
    localtime = datetime.today()
    print("本地时间为 :", localtime, type(localtime))  # =>2021-06-18 17:30:17.814116
    
  4. 方法四:now() 获取datetime.datetime类型

    from datetime import datetime
    
    localtime = datetime.now()
    print("本地时间为 :", localtime, type(localtime))  # =>2021-06-18 17:31:34.655896
    

六、关于时间的封装的方法

  • 包括的方法:
    • 指定格式的时间字符串 => 时间戳
    • 时间戳 => 指定格式的时间字符串
    • 获取指定时间戳的星期
    • 返回指定时间范围中,每一天的时间戳
    • 获取以本月为中轴,跨度三个月的第一天和最后一天
    • 获取上月第一天及当月最后一天
    • 获取本月第一天和最后一天的时间戳(13位)
    • 获取指定时间范围,经历的每个星期
    • 获取两个月份之间的所有月份
    • 根据时间字符串获取当月的月首和月末
    • 根据时间,当天的数据:年,第几周,星期几
    • 时间的转化:将秒转化为:w d m s 的格式
  • 封装的方法:
    import calendar
    import datetime
    import time
    from typing import Union
    
    import pandas as pd
    
    
    class TimesTool(object):
        start_date = None
        end_date = None
        date_format = '%Y-%m-%d'
        day_format = '%Y-%m-%d %H:%M:%S'
        month_format = '%Y-%m'
    
        @classmethod
        def to_timestamp(cls, time_text, time_format: str = None):
            """指定格式的时间字符串 => 时间戳"""
            if not isinstance(time_text, str):
                return time_text
            time_array = time.strptime(time_text, time_format if time_format else cls.date_format)
            timestamp = int(time.mktime(time_array)) * 1000
            return timestamp
    
        @classmethod
        def to_format(cls, timestamp_param, time_format: str = None):
            """时间戳 => 指定格式的时间字符串"""
            if len(str(timestamp_param)) == 13:
                timestamp_param = timestamp_param / 1000
            time_array = time.localtime(timestamp_param)
            time_str = time.strftime(time_format if time_format else cls.date_format, time_array)
            return time_str
    
        @classmethod
        def format_utc(cls, time_text):
            try:
                time_text = list(time_text)
                time_text.insert(-2, ":")
                time_text = "".join(time_text)
                time_text = datetime.datetime.fromisoformat(time_text).strftime(cls.date_format)
                time_text = cls.to_timestamp(time_text)
            except ValueError:
                pass
            return time_text
    
        @classmethod
        def get_week(cls, timestamp):
            """获取13位时间戳,对应的星期。周一=0"""
            timestamp = timestamp / 1000
            local_time = time.localtime(timestamp)
            date = time.strftime("%Y-%m-%d %H:%M:%S", local_time)
            week = datetime.datetime.strptime(date, "%Y-%m-%d %H:%M:%S").weekday()
            return week
    
        @classmethod
        def get_date_list(cls, begin_date, end_date):
            """返回指定时间范围中,每一天的时间戳
                如:2023-07-01,2023-07-03,返回1号到3号时间戳(13位)
            """
            date_list = [cls.to_timestamp(x.strftime(cls.date_format)) for x in
                         list(pd.date_range(start=begin_date, end=end_date))]
            return date_list
    
        @classmethod
        def get_quarter_start_end(cls):
            """
            时间跨度3个月,
            返回上个月的第一天,下个月的最后一天。如现在7月,返回('2023-06-01', '2023-08-31')
            """
            if cls.start_date and cls.end_date:
                return cls.start_date, cls.end_date
    
            today = datetime.date.today()
            year = today.year
            month = today.month
    
            first_day_of_current_month = datetime.date(year, month, 1)
            last_month_last_day = first_day_of_current_month - datetime.timedelta(days=1)
            last_month_first_day = datetime.date(last_month_last_day.year, last_month_last_day. month, 1)
    
            days_num = calendar.monthrange(first_day_of_current_month.year,     first_day_of_current_month.month)[1]
            next_month_first_day = first_day_of_current_month + datetime.timedelta(days=days_num)
            next_month_days = calendar.monthrange(next_month_first_day.year, next_month_first_day.  month)[1]
            next_month_last_day = next_month_first_day + datetime.timedelta(days=next_month_days    - 1)
    
            last_month_first_day = last_month_first_day.strftime(cls.date_format)
            next_month_last_day = next_month_last_day.strftime(cls.date_format)
            return last_month_first_day, next_month_last_day
    
        @classmethod
        def get_months_start_end(cls):
            """
            获取上月第一天及当月最后一天,
            :return: ('2023-06-01', '2023-07-31')
            """
            if cls.start_date and cls.end_date:
                return cls.start_date, cls.end_date
            today = datetime.date.today()
            year = today.year
            month = today.month
            today = datetime.date.today()
            end_of_last_month = today - datetime.timedelta(today.day)
            last_month_start = datetime.date(end_of_last_month.year, end_of_last_month.month, 1).   strftime(cls.date_format)
            _, day = calendar.monthrange(year, month)
            this_month_end = datetime.date(year, month, day).strftime(cls.date_format)
            return last_month_start, this_month_end
    
        @classmethod
        def get_two_months_start_end(cls):
            """获取之前到现在两个月的日期,两个月前第一天与当前月最后一天
           返回('2023-05-01', '2023-07-31')
            """
            today = datetime.date.today()
            year = today.year
            month = today.month
    
            current_month_first_day = datetime.date(year, month, 1)
            current_month_days = calendar.monthrange(year, month)[1]
            current_month_last_day = datetime.date(year, month, current_month_days)
    
            last_month_last_day = current_month_first_day - datetime.timedelta(days=1)
            last_month_first_day = datetime.date(last_month_last_day.year, last_month_last_day. month, 1)
    
            two_month_ago = last_month_first_day - datetime.timedelta(days=1)
            two_month_ago_first_day = datetime.date(two_month_ago.year, two_month_ago.month, 1)
            return two_month_ago_first_day.__str__(), current_month_last_day.__str__()
    
        @classmethod
        def get_current_month_start_end(cls):
            """获取本月第一天和最后一天的时间戳(13位)"""
            if cls.start_date and cls.end_date:
                return cls.to_timestamp(cls.start_date), cls.to_timestamp(cls.end_date)
    
            today = datetime.date.today()
            year = today.year
            month = today.month
            first_day_of_current_month = datetime.date(year, month, 1)
            days_num = calendar.monthrange(first_day_of_current_month.year,     first_day_of_current_month.month)[1]
            last_day_of_current_month = first_day_of_current_month + datetime.timedelta (days=days_num - 1)
            first_day_stamp = cls.to_timestamp(str(first_day_of_current_month))
            last_day_stamp = cls.to_timestamp(str(last_day_of_current_month))
            return first_day_stamp, last_day_stamp
    
        @classmethod
        def get_today_stamp(cls):
            today_stamp = int(time.mktime(datetime.date.today().timetuple())) * 1000
            return today_stamp
    
        @classmethod
        def get_data_list_week(cls, start_stamp: Union[int, float], end_stamp: Union[int, float])   -> list:
            """
            获取 开始时间到结束时间中,经历的每个星期
            :param start_stamp 开始时间(时间戳)
            :param end_stamp 结束时间
            """
            start_date = cls.to_format(int(start_stamp), cls.date_format)
            end_date = cls.to_format(int(end_stamp), cls.date_format)
            data_list = cls.get_date_list(start_date, end_date)
            week_list = []
            for date_item in data_list:
                week_list.append(cls.get_week(date_item))
            return week_list
    
        @classmethod
        def every_month(cls, start: str, end: str) -> list:
            """
            给定开始时间、结束时间,获取每一个月份的月初与下个月的月初
            :return:
            """
            start = datetime.datetime.strptime(start, cls.date_format)
            end = datetime.datetime.strptime(end, cls.date_format)
            date_list = []
            while start < end:
                temp = cls._add_months(start, 1)
                date_list.append(dict(start=start.strftime(cls.date_format), end=temp.strftime  (cls.date_format)))
                start = temp
            return date_list
    
        @classmethod
        def get_between_month(cls, start_time: (int, str), end_time: (int, str), with_day: bool =   False):
            """
            获取两个月份之间的所有月份:时间戳,-> ['2021-09', '2021-10', '2021-11', '2021-12']
            :param start_time: 开始时间戳(13位时间戳或%Y-%m-%d格式)
            :param end_time: 结束时间戳(13位时间戳或%Y-%m-%d格式)
            :param with_day: 列表中的每一个月份是否具体到【天】,例如['2021-09-01', '2021-10-01']
            :return:
            """
            date_list = []
            if isinstance(start_time, int):
                begin_date = datetime.datetime.strptime(cls.to_format(int(start_time), cls. month_format),
                                                        cls.month_format)
            else:
                begin_date = datetime.datetime.strptime(start_time, cls.date_format)
            if isinstance(end_time, int):
                end_date = datetime.datetime.strptime(cls.to_format(int(end_time), cls. month_format),
                                                      cls.month_format)
            else:
                end_date = datetime.datetime.strptime(end_time, cls.date_format)
            time_format = cls.month_format if not with_day else cls.date_format
            while begin_date <= end_date:
                date_str = begin_date.strftime(time_format)
                date_list.append(date_str)
                begin_date = cls._add_months(begin_date, 1)
            return date_list
    
        @classmethod
        def _add_months(cls, dt, months):
            month = dt.month - 1 + months
            year = dt.year + month // 12
            month = month % 12 + 1
            day = min(dt.day, calendar.monthrange(year, month)[1])
            return dt.replace(year=year, month=month, day=day)
    
        @classmethod
        def get_start_end_stamp(cls, month_text, month_format: str = None):
            """
            根据时间字符串获取当月的月首和月末
            :param month_text: 时间字符串
            :param month_format: 时间格式化
            :return:
            """
            struct_time1 = time.strptime(month_text, month_format if month_format else cls. month_format)
            last_day = calendar.monthrange(struct_time1.tm_year, struct_time1.tm_mon)[1]
            month_start = str(datetime.date(struct_time1.tm_year, struct_time1.tm_mon, 1))
            last_day_str = "{0}-{1}-{2} 23:59:59".format(struct_time1.tm_year, struct_time1.    tm_mon, last_day)
            return cls.to_timestamp(month_start), cls.to_timestamp(last_day_str, cls.day_format)
    
        @classmethod
        def get_time_stamp_week_info(cls, time_text, is_end=False):
            """根据时间,当天的数据:年,第几周,星期几"""
            day_time_text = str(time_text).split(' ')[0]
            time_text = day_time_text + ' 23:59:59' if is_end else day_time_text + ' 00:00:00'
            time_stamp = cls.to_timestamp(str(time_text), cls.day_format)
            date_time = datetime.datetime.fromtimestamp(time_stamp / 1000)
            week_info = date_time.isocalendar()
            return time_stamp, date_time, week_info[0], week_info[1], week_info[2]
    
        @classmethod
        def get_times_until_current(cls, time_type: int = 0, start_date: int = None, end_date:  int = None):
            """
            获取当月第一天到当天的数据
            月的返回:[{'text':'2021-01','start_stamp':0,'end_stamp':1}]
            周的返回:[{'text':'WEEK6','start_stamp':0,'end_stamp':1,'year':'2021'}]
            """
            """
            1.设置start_date参数的作用:计算当月遗留未解决缺陷数时需要传入date_list,
            而原本date_list是从2021-11开始计算,为了只在当前月更新,所以传入当前月的1号时间;
            2.设置end_date参数的作用是:计算当月遗留未解决缺陷数时需要传入date_list,而计算date_list需  要起始时间和截止时间,
            在手动执行扫描而不是定时扫描时,会传入错误的截止时间。例如在2022-08-05手动执行扫描2022-05-01    至2022-05-31范围的缺陷数据,
            那date_list将会生成2022-05-01至2022-08-05的日期列表。
            """
            return_list = []
            if not start_date or not end_date:
                start_stamp = TimesTool.to_timestamp('2021-11', cls.month_format)
                today_stamp = TimesTool.get_today_stamp()
            else:
                start_stamp = start_date
                today_stamp = end_date
            if time_type == 0:
                month_list = TimesTool.get_between_month(start_stamp, today_stamp)
                for month in month_list:
                    start_stamp, end_stamp = TimesTool.get_start_end_stamp(month)
                    month_item = {'text': month, 'start_stamp': start_stamp, 'end_stamp':   end_stamp}
                    return_list.append(month_item)
            else:
                start_text = TimesTool.to_format(start_stamp, cls.day_format)
                start_stamp, start_date, year, week_order, week = TimesTool.    get_time_stamp_week_info(start_text)
                # 获取2021年第一周的开始
                while year < 2021:
                    start_date = start_date + datetime.timedelta(days=1)
                    start_stamp, start_date, year, week_order, week = TimesTool.    get_time_stamp_week_info(start_date)
                week_end_date = start_date + datetime.timedelta(days=7 - week)
                week_end_stamp, week_end_date, _, _, _ = TimesTool.get_time_stamp_week_info(
                    week_end_date, True)
                week_item = {'text': 'WEEK{0}'.format(week_order), 'start_stamp': start_stamp,  'end_stamp': week_end_stamp,
                             'year': year}
                return_list.append(week_item)
                # 遍历获取到目前为止的每一周
                while week_end_stamp < today_stamp:
                    start_date = week_end_date + datetime.timedelta(days=1)
                    start_stamp, start_date, year, week_order, week = TimesTool.    get_time_stamp_week_info(start_date)
                    week_end_date = start_date + datetime.timedelta(days=7 - week)
                    week_end_stamp, week_end_date, _, _, _ = TimesTool.get_time_stamp_week_info(
                        week_end_date, True)
                    week_item = {'text': 'WEEK{0}'.format(week_order), 'start_stamp': start_stamp,
                                 'end_stamp': week_end_stamp, 'year': year}
                    return_list.append(week_item)
            return return_list
    
        @classmethod
        def check_time_in_the_same_month(cls, start: int, end: int):
            """
            判断两个时间戳是否在同一月,在同一月则返回为False,否则返回True。
            :param start: 开始时间。
            :param end: 结束时间。
            :return:
            """
            start_date = cls.to_format(start, '%Y%m')
            end_date = cls.to_format(end, '%Y%m')
            if start_date >= end_date:
                return False
            return True
    
        @classmethod
        def seconds_to_hour(cls, seconds: int):
            return cls.round(seconds / 60 / 60)
    
        @classmethod
        def covert_time(cls, seconds):
            """时间的转化:将秒转化为:w d m s 的格式
            :param seconds: 时间,单位:秒
            """
            if seconds <= 0:
                return ''
            if seconds < 60:
                return f"{seconds}s "
            minute = int(seconds / 60)
            if minute < 60:
                time_str = f"{minute}m "
                time_str += TimesTool.covert_time(seconds - minute * 60)
                return time_str
            hour = int(minute / 60)
            if hour < 8:
                time_str = f"{hour}h "
                time_str += TimesTool.covert_time(seconds - hour * 3600)
                return time_str
            day = int(hour / 8)
            if day < 5:
                time_str = f"{day}d "
                time_str += TimesTool.covert_time(seconds - day * 28800)
            else:
                week = int(day / 5)
                time_str = f"{week}w "
                time_str += TimesTool.covert_time(seconds - week * 144000)
            return time_str
    
    
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,684评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 87,143评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,214评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,788评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,796评论 5 368
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,665评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,027评论 3 399
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,679评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,346评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,664评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,766评论 1 331
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,412评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,015评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,974评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,073评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,501评论 2 343

推荐阅读更多精彩内容