Difference between revisions of "User:Pedro Oval/UnixToDateTime"
Jump to navigation
Jump to search
Pedro Oval (talk | contribs) m (Add category, fix sum spacing) |
m (<lsl> tag to <source>) |
||
(One intermediate revision by one other user not shown) | |||
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). | ||
< | <source lang="lsl2"> | ||
list UnixToDateTime(integer unix) | list UnixToDateTime(integer unix) | ||
{ | { | ||
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/ | integer b = c + 2442113 + a + a/(integer)-4; | ||
c = (b*20 + | c = (b*20 + (integer)-2442)/7305; | ||
b += c* | b += c*(integer)-365 + c/(integer)-4; | ||
a = b*1000/30601; | a = b*1000/30601; | ||
b += a* | b += a*(integer)-30 + a*(integer)-601/1000; | ||
return (list)( | return (list)((integer)-4716 + c + (a>13)) | ||
+ -~((a + 10)%12) | + -~((a + 10)%12) | ||
+ b | + b | ||
Line 26: | Line 26: | ||
+ unix%60; | + unix%60; | ||
} | } | ||
</ | </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: | ||
< | <source lang="lsl2"> | ||
list UnixToDateTime(integer unix) | list UnixToDateTime(integer unix) | ||
{ | { | ||
Line 38: | Line 38: | ||
if (unix & 0x80000000) | if (unix & 0x80000000) | ||
{ | { | ||
unix += | unix += (integer)-86400*~-c; // we're interested in unix mod 86400 from here on, | ||
// but mod doesn't work well with negatives either | // but mod doesn't work well with negatives either | ||
if (unix^86400) --c; // c needs fixup unless unix%86400 == 0 | if (unix^86400) --c; // c needs fixup unless unix%86400 == 0 | ||
Line 44: | Line 44: | ||
integer a = (c*4 + 102032)/146097 + 15; | integer a = (c*4 + 102032)/146097 + 15; | ||
integer b = c + 2442113 + a + a/ | integer b = c + 2442113 + a + a/(integer)-4; | ||
c = (b*20 + | c = (b*20 + (integer)-2442)/7305; | ||
b += c* | b += c*(integer)-365 + c/(integer)-4; | ||
a = b*1000/30601; | a = b*1000/30601; | ||
b += a* | b += a*(integer)-30 + a*(integer)-601/1000; | ||
return (list)( | return (list)((integer)-4716 + c + (a>13)) | ||
+ -~((a + 10)%12) | + -~((a + 10)%12) | ||
+ b | + b | ||
Line 57: | Line 57: | ||
+ unix%60; | + unix%60; | ||
} | } | ||
</ | </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.