Do you have a better solution how to convert today's dates to Stardate? Is there any agreed on (by fans, anyways) standard that I simply missed?
Do you have a better solution how to convert today's dates to Stardate? Is there any agreed on (by fans, anyways) standard that I simply missed?
Oooh, neat question! I remember pondering this when I was a teenager in the 90s.
I actually realized early on that the standard ISO date format is the best: YYYY-MM-DD (although I didn't use hyphens at the time, as stardates don't have hyphens), and started using YYYYMMDD for my digital diary way back then (long lost, sadly, or maybe not SO sadly, if you knew me as a teenager, lol)
But the canonical system of #Stardate as of the TNG era was 40000 + 1000 * season_number + "day", where the "day" was something like (day_of_year / 365 * 999)
So, since season 1 was 1987, the "current" stardate would be something like 2025-1987 + 41 = 79000
As far as the non-sequential order of TOS stardates goes, this is because NBC did not air the episode in the order they were made. They were produced sequentially, but not aired sequentially.
The other problem is that the stardates are tied to the beginning of TNG seasons (in the fall), and not the beginning of calendar years. That makes things more difficult, but I guess the best solution would be to use the number of days since Encounter at Farpoint aired? (1987-09-28)
Here's what I came up with using bash, bc (which you may need to install) and awk:
$ echo "( $(date +%s) - $(date +%s -d 1987-09-28) ) / 365.25 / 24 / 3600 * 1000 + 41000" |bc -l |awk '{printf "%.1f\n", $1}'
78967.2
@mirabilos @nazgul @amin @bugbear
How do you set the decimal precision without -l? I'm a total noob.
@rl_dane @nazgul @amin @bugbear -l just loads the library (for sinus, etc). You need set the scale, even if you load the library.
RTFM bc(1), dc(1), 06.bc(USD), 05.dc(USD)
@rl_dane @amin @nazgul @bugbear (though I just noticed that it’s apparently normal that loading the math lib sets the scale to 20)
As to the original problem:
# inlining 559785600=$(date +%s -ud 1987-09-28)
# to stay portable to systems without GNU date
printf '%s\n' \
'scale=9' \
"v=($(date +%s) - 559785600) * 1000 / 60 / 60 / 24 / 365.2425" \
scale=1 '(v+.05)/1' | bc
This even solves the rounding, no need to awk around.
Tbh it’s ugly, and I’d rather just define the generic-correct bc rounding function first, then just use it:
bc <<EOF
define r(x,n) {
auto o
o = scale
if (scale < (n + 1)) scale = (n + 1);
/* assume sign is positive instead of getting the sign first
x += v(x) * 0.5 * A^-n
*/ x += 0.5 * A^-n
scale = n
x /= 1
/* drop trailing zeroes */
/* commented out for this use case
for (scale = 0; scale <= o; scale++) {
if (x == x/1) {
x /= 1
break
}
}
*/
scale = o
return (x)
}
scale=9
r(($(date +%s) - 559785600) * 1000 / 60 / 60 / 24 / 365.2425, 1)
EOF
I commented out stuff that requires use of a separate function to get the sign…
define v(x) {
if (x < 0) return (-1)
if (x > 0) return (1)
return (0)
}
… and that removes trailing 0s at the end asuming you always want d+.d precision for your “star dates”.
@mirabilos @amin @nazgul @bugbear
That is... a lot more complex than just calling bc -l ;)
@mirabilos @amin @nazgul @bugbear
I'm willing to call another fork() for the sake of simplicity, especially when it's not in a loop.
@mirabilos @bugbear @nazgul @amin
I mean, it's a full programming language in its own right, of course, and I'm using it in probably the dumbest way, but for all its internal complexity, it performs this one simple job very well.
¯\_(ツ)_/¯