User:Pedro Oval/UnixToDateTime

From Second Life Wiki
Jump to navigation Jump to search
The printable version is no longer supported and may have rendering errors. Please update your browser bookmarks and please use the default browser print function instead.

Convert a Unix timestamp (e.g. as obtained by llGetUnixTime) to a UTC date and time.

Adapted and optimized from this Ruby version: http://ptspts.blogspot.com/2009/11/how-to-convert-unix-timestamp-to-civil.html

Optimized for size in Mono.

Returns a list with the format [year, month, day, hours, minutes, seconds] (UTC).

This is the shortest version, but it works with positive input only (i.e. with numbers representing dates from 1970 to 2037).

list UnixToDateTime(integer unix)
{
    integer c = unix/86400;
    integer a = (c*4 + 102032)/146097 + 15;
    integer b = c + 2442113 + a + a/(integer)-4;
    c = (b*20 + (integer)-2442)/7305;
    b += c*(integer)-365 + c/(integer)-4;
    a = b*1000/30601;
    b += a*(integer)-30 + a*(integer)-601/1000;

    return (list)((integer)-4716 + c + (a>13))
           + -~((a + 10)%12)
           + b
           + unix/3600%24
           + unix/60%60
           + unix%60;
}

Size in Mono: 492 bytes.

This version also works with negative input:

list UnixToDateTime(integer unix)
{
    integer c = unix/86400;

    // LSL doesn't do floor division as required here, so we have to fix up the result
    if (unix & 0x80000000)
    {
        unix += (integer)-86400*~-c; // we're interested in unix mod 86400 from here on,
                                // but mod doesn't work well with negatives either
        if (unix^86400) --c;    // c needs fixup unless unix%86400 == 0
    }

    integer a = (c*4 + 102032)/146097 + 15;
    integer b = c + 2442113 + a + a/(integer)-4;
    c = (b*20 + (integer)-2442)/7305;
    b += c*(integer)-365 + c/(integer)-4;
    a = b*1000/30601;
    b += a*(integer)-30 + a*(integer)-601/1000;

    return (list)((integer)-4716 + c + (a>13))
           + -~((a + 10)%12)
           + b
           + unix/3600%24
           + unix/60%60
           + unix%60;
}

Size in Mono: 556 bytes.