Difference between revisions of "User:Pedro Oval/UnixToDateTime"

From Second Life Wiki
Jump to navigation Jump to search
(Use the newly discovered sign trick to make it more readable)
m (<lsl> tag to <source>)
 
Line 8: Line 8:


This is the shortest version, but it works with positive input only (i.e. with numbers representing dates from 1970 to 2037).
This is the shortest version, but it works with positive input only (i.e. with numbers representing dates from 1970 to 2037).
<lsl>
<source lang="lsl2">
list UnixToDateTime(integer unix)
list UnixToDateTime(integer unix)
{
{
Line 26: Line 26:
           + unix%60;
           + unix%60;
}
}
</lsl>
</source>
Size in Mono: 492 bytes.
Size in Mono: 492 bytes.


This version also works with negative input:
This version also works with negative input:
<lsl>
<source lang="lsl2">
list UnixToDateTime(integer unix)
list UnixToDateTime(integer unix)
{
{
Line 57: Line 57:
           + unix%60;
           + unix%60;
}
}
</lsl>
</source>


Size in Mono: 556 bytes.
Size in Mono: 556 bytes.


[[Category:LSL User-Defined Functions]]
[[Category:LSL User-Defined Functions]]

Latest revision as of 14:31, 22 January 2015

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.