Search code examples
pythondatetimeunix-timestamp

datetime year out of range


I passed filenames such as abcef-1591282803 into this function and the function worked fine:

def parse_unixtimestamp(filename):
        ts = re.findall(r'\d{10}', filename)[0]
        return ts

However, then I modified the function to this so the it also works when the timestamp is of 13 digits instead of 10. file20-name-1591282803734

def parse_unixtimestamp(filename):
        ts = re.findall(r'\d{13}|\d{10}', filename)[0]
        return ts

It didn't throw an error until here. But in case of 13 digits, I get ts values like this 1591282803734. Now when I pass this value to this function for year:

def get_dateparts(in_unixtimestamp):
    dt_object = datetime.fromtimestamp(int(in_unixtimestamp))

    date_string = dt_object.strftime("%Y-%m-%d")
    year_string = dt_object.strftime("%Y")
    month_string = dt_object.strftime("%m")
    day_string = dt_object.strftime("%d")
    logger.info(f'year_string: {year_string}')
    result = {"date_string": date_string, "year_string": year_string, "month_string": month_string,
              "day_string": day_string}

    return result

I get an error that:

year 52395 is out of range

I wouldn't get this error when the unixtimestamp passed into parse_unixtimestampIs only 10 digits. How can I modify this function such that it works in both cases?


Solution

  • datetime.fromtimestamp requires you to supply the time in seconds. If your string has 13 digits instead of 9 (i.e. it is milliseconds), you should be using:

    >>> datetime.fromtimestamp(1591282803734/1000)
    datetime.datetime(2020, 6, 4, 11, 0, 3, 734000)
    

    To do this in your function, you could check the length of your timestamp before calling datetime.fromtimestamp. Change your function as follows:

    def get_dateparts(in_unixtimestamp):
        if len(in_unixtimestamp) == 13:
            dt_object = datetime.fromtimestamp(int(in_unixtimestamp)/1000)
        else:
            dt_object = datetime.fromtimestamp(int(in_unixtimestamp))
    
        date_string = dt_object.strftime("%Y-%m-%d")
        year_string = dt_object.strftime("%Y")
        month_string = dt_object.strftime("%m")
        day_string = dt_object.strftime("%d")
    
        logger.info(f'year_string: {year_string}')
    
        result = {"date_string": date_string, 
                  "year_string": year_string, 
                  "month_string": month_string,
                  "day_string": day_string}
    
        return result
    
    >>> get_dateparts(parse_unixtimestamp("abcef-1591282803"))
    {'date_string': '2020-06-04',
     'year_string': '2020',
     'month_string': '06',
     'day_string': '04'}
    
    >>> get_dateparts(parse_unixtimestamp("file20-name-1591282803734"))
    {'date_string': '2020-06-04',
     'year_string': '2020',
     'month_string': '06',
     'day_string': '04'}