Skip to content

Instantly share code, notes, and snippets.

@WaffleLapkin
Last active December 8, 2023 14:41
Show Gist options
  • Save WaffleLapkin/e72aff8d10d15bbc83ed250c13c4a2ac to your computer and use it in GitHub Desktop.
Save WaffleLapkin/e72aff8d10d15bbc83ed250c13c4a2ac to your computer and use it in GitHub Desktop.
Calculates the best time to release a daily version
#!/usr/bin/env rust-script
/*!
Shebang is using <https://github.com/fornwall/rust-script>.
Date: 2023-12-08.
Data taken from <https://observablehq.com/@mattdzugan/population-by-time-zone-creating-a-dataset>.
Ideally I'd re-compute it here (and it will probably be faster than their js lol), but I'm too lazy atm.
This is very jank way to find at what point it's the most noon / the most distance from date change.
This is nice for releasing daily versions of software, to prevent off-by-one errors with version naming like Rust's nightly has.
*/
use std::{fs, str};
fn main() {
let zone_pops = fs::read("./zonePops@1.csv").expect("couldn't read population file :c");
let zone_pops = str::from_utf8(&zone_pops).expect("non utf-8 population file :c");
// Ideally we'd have a proper csv parser, which returns proper errors, etc..
// But again: too lazy, doesn't matter.
let zone_pops = zone_pops
.lines()
.skip(1)
.map(TimeZonePopulation::parse_csv_line)
.collect::<Vec<_>>();
// (utc offset, the range should probably be chosen better because of tz weirdness idk)
let in_quarter_hour_increments = (-12 * 4..12 * 4).map(|x| x as f64 * 0.25);
let mut result = in_quarter_hour_increments
.map(|offset| {
// When it's 12+offset in UTC, how distant are the people from 12 in their tz
let total_distance_from_noon = zone_pops
.iter()
.map(|p| {
// it's 12+offset UTC, so it's 12+offset+p.offset TZ, so the distance from 12 is offset+p.offset
let distance = (offset + p.offset as f64).abs();
distance * p.pop
})
.sum::<f64>();
(total_distance_from_noon, offset)
})
.collect::<Vec<_>>();
result.sort_by(|(distance_a, _), (distance_b, _)| distance_a.total_cmp(&distance_b));
println!("Time UTC | Total distance");
result.into_iter().for_each(|(total_distance, offset)| {
println!(
"{time_utc: <9}|{total_distance: >13.0}",
time_utc = hours_to_time(12. + offset)
)
});
}
struct TimeZonePopulation {
pop: f64,
offset: f64,
}
impl TimeZonePopulation {
fn parse_csv_line(l: &str) -> Self {
// name,pop,number,centroid_lat,centroid_lon
let mut parts = l.split(',');
let _name = parts.next().unwrap();
let pop = parts.next().unwrap().parse().unwrap();
let number = parts.next().unwrap().parse().unwrap();
let _centroid_lat: f64 = parts.next().unwrap().parse().unwrap();
let _centroid_lon: f64 = parts.next().unwrap().parse().unwrap();
Self {
pop,
offset: number,
}
}
}
fn hours_to_time(f: f64) -> String {
if (f.fract() - 0.00).abs() <= f64::EPSILON {
return format!("{:02}:00", f.floor());
}
if (f.fract() - 0.25).abs() <= f64::EPSILON {
return format!("{:02}:15", f.floor());
}
if (f.fract() - 0.50).abs() <= f64::EPSILON {
return format!("{:02}:30", f.floor());
}
if (f.fract() - 0.75).abs() <= f64::EPSILON {
return format!("{:02}:45", f.floor());
}
panic!("time is sad")
}
{
"sysroot_src": "/home/waffle/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library",
"crates": [
{
"root_module": "./best-daily-release-time.rs",
"edition": "2021",
"deps": []
}
]
}
name pop number centroid_lat centroid_lon
+8 1679526842.3174655 8 29.167381377303034 114.40537618281842
+5.5 1412024492.5365999 5.5 22.57460831025738 80.28549532525135
+1 857443515.4230063 1 27.98546057451415 9.206860102301311
+2 609921155.778181 2 69.79870572710442 34.27138129077332
+3 496279977.69005316 3 53.46254200373548 28.060355799363528
+7 439650258.6088599 7 54.45137243736661 82.45302297763921
-5 332101899.5759011 -5 22.934562350438622 -77.56054292741445
+5 305642188.5871171 5 40.143206330968276 65.39358482784355
0 285534677.74817115 0 52.735095466042495 -2.1741815211365463
-6 272974492.2278151 -6 25.342290909203125 -94.91660600665132
-3 248013633.1840175 -3 -20.382170060207862 -48.27674906032608
+9 220112826.38805962 9 53.26871407009662 105.34876053822889
+6 199668329.4785298 6 49.64866594642483 67.39307395123679
+4 129089229.8974205 4 51.498500061989866 41.516025199485526
+3.5 81889886.42699996 3.5 34.21113683955241 51.92501375706545
-4 77707712.2094911 -4 -10.169244981297592 -65.6180334211847
-8 66121602.89525824 -8 71.5 -125.47915980797731
+6.5 50112751.353199996 6.5 19.63448063610078 96.20054447282587
+5.75 46921450.199999996 5.75 27.491308020142995 84.91573258321841
-7 41542592.61694991 -7 36.03427160193931 -109.48220605918692
-4.5 31923862.6107414 -4.5 9.822971935670893 -67.88786887491592
+4.5 31042662.160000008 4.5 34.63481031518593 67.69458248551192
+10 29482066.186867144 10 55.1158068032147 123.47670732895372
+12 6112395.685136859 12 57.39505054341126 157.2598123561538
+11 5267268.0348348 11 67.95166682415585 136.0905939874974
-2 4855177.195979999 -2 -7.929009537234731 -34.498948352697774
-1 3285250.089709 -1 68.73537542352209 -20.1013686044013
-10 1853786.6872550002 -10 70.5 -144.98033241190655
+9.5 1814484.2278491103 9.5 -32.388789637676155 137.77305038474307
-9 639138.6229801651 -9 61.63613222447218 -148.76912410796504
-3.5 499933.0969 -3.5 48.060333294068805 -54.12711167543027
+13 308148.24164100003 13 -16.06757662245485 -172.98188317573457
-11 57839.297831699994 -11 -2.5 -171.5
+14 11448.336 14 2.892943830439638 -158.6521927728187
-9.5 8566.932469999998 -9.5 -9.157454959487971 -139.9044079385629
+11.5 2062.40457 11.5 -29.489440689612124 167.5
+12.75 591.133 12.75 -43.76014500966787 -176.5
+10.5 360.1646 10.5 -31.5 159.5
+8.75 37.16319 8.75 -31.499999999999996 128.5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment