Difference between revisions of "User:Pedro Oval/UnixToDateTime"
Jump to navigation
Jump to search
Pedro Oval (talk | contribs) (Create page) |
Pedro Oval (talk | contribs) (Add version that accepts negatives) |
||
Line 1: | Line 1: | ||
Convert a Unix timestamp (e.g. as obtained by [[llGetUnixTime]]) to a UTC date and time. | 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 <code>[year, month, day, hours, minutes, seconds]</code> (UTC). | Returns a list with the format <code>[year, month, day, hours, minutes, seconds]</code> (UTC). | ||
Line 9: | Line 13: | ||
integer c = unix/86400; | integer c = unix/86400; | ||
integer a = (c*4 + 102032)/146097 + 15; | integer a = (c*4 + 102032)/146097 + 15; | ||
integer b = c + 2442113 + a + a/0xFFFFFFFC; // -4 | integer b = c + 2442113 + a + a/0xFFFFFFFC; // 0xFFFFFFFC=-4 | ||
c = (b*20+0xFFFFF676)/7305; // -2442 | c = (b*20 + 0xFFFFF676)/7305; // 0xFFFFF676=-2442 | ||
b += c*0xFFFFFE93 + c/0xFFFFFFFC; // -365, -4 | b += c*0xFFFFFE93 + c/0xFFFFFFFC; // 0xFFFFFE93=-365; 0xFFFFFFFC=-4 | ||
a = b*1000/30601; | |||
b += a*0xFFFFFFE2 + a*0xFFFFFDA7/1000; // 0xFFFFFFE2=-30; 0xFFFFFDA7=-601 | |||
return (list)(0xFFFFED94 + c + (a>13)) // 0xFFFFED94=-4716 | |||
+ -~((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 += 0xFFFEAE80*~-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/0xFFFFFFFC; // 0xFFFFFFFC=-4 | |||
c = (b*20+0xFFFFF676)/7305; // 0xFFFFF676=-2442 | |||
b += c*0xFFFFFE93 + c/0xFFFFFFFC; // 0xFFFFFE93=-365; 0xFFFFFFFC=-4 | |||
a = b*1000/30601; | a = b*1000/30601; | ||
b += a*0xFFFFFFE2 + a*0xFFFFFDA7/1000; // -30 | b += a*0xFFFFFFE2 + a*0xFFFFFDA7/1000; // 0xFFFFFFE2=-30; 0xFFFFFDA7=-601 | ||
return (list)(0xFFFFED94+c+(a>13)) + -~((a+10)%12) + b + unix/3600%24 + unix/60%60 + unix%60; | return (list)(0xFFFFED94 + c + (a>13)) // 0xFFFFED94=-4716 | ||
+ -~((a + 10)%12) | |||
+ b | |||
+ unix/3600%24 | |||
+ unix/60%60 | |||
+ unix%60; | |||
} | } | ||
</lsl> | </lsl> | ||
Size in Mono: 556 bytes. |
Revision as of 11:22, 14 May 2014
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/0xFFFFFFFC; // 0xFFFFFFFC=-4 c = (b*20 + 0xFFFFF676)/7305; // 0xFFFFF676=-2442 b += c*0xFFFFFE93 + c/0xFFFFFFFC; // 0xFFFFFE93=-365; 0xFFFFFFFC=-4 a = b*1000/30601; b += a*0xFFFFFFE2 + a*0xFFFFFDA7/1000; // 0xFFFFFFE2=-30; 0xFFFFFDA7=-601
return (list)(0xFFFFED94 + c + (a>13)) // 0xFFFFED94=-4716 + -~((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 += 0xFFFEAE80*~-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/0xFFFFFFFC; // 0xFFFFFFFC=-4 c = (b*20+0xFFFFF676)/7305; // 0xFFFFF676=-2442 b += c*0xFFFFFE93 + c/0xFFFFFFFC; // 0xFFFFFE93=-365; 0xFFFFFFFC=-4 a = b*1000/30601; b += a*0xFFFFFFE2 + a*0xFFFFFDA7/1000; // 0xFFFFFFE2=-30; 0xFFFFFDA7=-601
return (list)(0xFFFFED94 + c + (a>13)) // 0xFFFFED94=-4716 + -~((a + 10)%12) + b + unix/3600%24 + unix/60%60 + unix%60;
} </lsl>
Size in Mono: 556 bytes.