User:Pedro Oval/UnixToDateTime
< User:Pedro Oval
Jump to navigation
Jump to search
Revision as of 14:53, 21 July 2014 by Pedro Oval (talk | contribs) (Use the newly discovered sign trick to make it more readable)
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). <lsl> 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;
} </lsl> Size in Mono: 492 bytes.
This version also works with negative input: <lsl> 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;
} </lsl>
Size in Mono: 556 bytes.