Problems with my unix-epoch time converter

2019-08-27 23:06发布

问题:

I wrote a simple function to fill three variables with the current year, month, and day. However, for some reason it is not working correctly, and I can't seem to find the problem.

void getDate(int *year, int *month, int *date)
{
int   epochTime,
      monthLength,
      functionYear,
      functionMonth,
      functionDate;

functionYear   = 1970;
functionMonth  = 1;
functionDate   = 1;

epochTime = time(NULL);
while (epochTime > 1 * 365 * 24 * 60 * 60)
{
   epochTime -= 1 * 365 * 24 * 60 * 60;
   functionYear++;
}
monthLength = findMonthLength(functionYear, functionMonth, false);
while (epochTime > 1 * monthLength * 24 * 60 * 60)
{
   printf("%d\n", epochTime);
   epochTime -= 1 * monthLength * 24 * 60 * 60;
   functionMonth++;
   monthLength = findMonthLength(functionYear, functionMonth, false);      
   printf("functionMonth = %d\n", functionMonth);
}
while (epochTime > 1 * 24 * 60 * 60)
{
   printf("%d\n", epochTime);
   epochTime -= 1 * 24 * 60 * 60;
   functionDate++;
   printf("functionDate = %d\n", functionDate);
}
*year    = functionYear;
*month   = functionMonth;
*date    = functionDate;
}

findMonthLength() returns an integer value which the length of the month it is sent. 1 = January, etc. It uses the year to test if it is a leap year.

It is currently April 3, 2013; however, my function finds April 15, and I can't seem to find where my problem is.

EDIT: I got it. My first problem was that while I remembered to check for leap years when finding the months, I forgot about that when finding each year, which put me several days off. My second problem was that I didn't convert to the local time zone from UTC

回答1:

One problem could in this section:

while (epochTime > 1 * 365 * 24 * 60 * 60)
{
    epochTime -= 1 * 365 * 24 * 60 * 60;
    functionYear++;
} 

Each iteration of this loop, a time in seconds corresponding to one normal year is subtracted. This does not account for leap years, where you need to subtract a time corresponding to 366 days.

For that section, you may want:

int yearLength = findYearLength(functionYear + 1);
while (epochTime > 1 * yearLength * 24 * 60 * 60)
{
    epochTime -= 1 * yearLength * 24 * 60 * 60;
    functionYear++;
    yearLength = findYearLength(functionYear + 1);
}

with findYearLength(int year) being a function that returns the length in days of a given year.

One minor issue is that leap seconds are not accounted for. As only 35 of these have been added, that can be safely ignored in a calculation for a given day.



回答2:

Why not use gmtime() or localtime() and be done with it? They return a structure with everything you need in it.



回答3:

I made the complete solution based on yours, in Python. I hope it will help someone, someday. Cheers!

Use: getDate(unixtime)

def leapYear(year):
        #returns True if the year is a leap year, return False if it isn't
        if year % 400 == 0:
                return True
        elif year % 100 == 0:
                return False
        elif year % 4 == 0: 
                return True
        else:
             return False

def findMonthLength(year, month):
        #returns an integer value with the length of the month it is sent.
        #1 = January, etc. It uses the year to test if it is a leap year.

        months1 = [0,31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
        months2 = [0,31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]

        if (leapYear(year)==True):
                return months2[month]
        else:
                return months1[month]

def findYearLength(year):
        #returns an integer value with the length of the year it is sent.
        #It uses the year to test if it is a leap year.

        if leapYear(year)==True:
                return 366
        else:
                return 365

def getDate(epoch):
        SECONDS_PER_YEAR = 0
        SECONDS_PER_MONTH = 0
        SECONDS_PER_DAY = 24 * 60 * 60
        SECONDS_PER_HOUR = 60*60
        SECONDS_PER_MIN = 60

        epochTime = epoch
        monthLength = 0
        yearLength = 0
        year = 1970
        month = 1
        day = 1
        hour = 0
        minu = 0
        seg = 0

        #Years
        yearLength = findYearLength(year)
        SECONDS_PER_YEAR = yearLength * SECONDS_PER_DAY
        while (epochTime >= SECONDS_PER_YEAR):
                epochTime -= SECONDS_PER_YEAR
                year += 1
                yearLength = findYearLength(year)
                SECONDS_PER_YEAR = yearLength * SECONDS_PER_DAY

        #Months
        monthLength = findMonthLength(year, month)
        SECONDS_PER_MONTH = monthLength * SECONDS_PER_DAY
        while (epochTime >= SECONDS_PER_MONTH):
                epochTime -= SECONDS_PER_MONTH;
                month += 1
                monthLength = findMonthLength(year, month)
                SECONDS_PER_MONTH = monthLength * SECONDS_PER_DAY

        #Days
        while (epochTime >= SECONDS_PER_DAY):
                epochTime -= SECONDS_PER_DAY;
                day += 1

        #Hours
        while (epochTime >= SECONDS_PER_HOUR):
                epochTime -= SECONDS_PER_HOUR;
                hour += 1

        #Minutes
        while (epochTime >= SECONDS_PER_MIN):
                epochTime -= SECONDS_PER_MIN;
                minu += 1

        #Seconds
        seg = epochTime

        print ("%d-%d-%d %d:%d:%d") % (year, month, day, hour, minu, seg)