Zach Holman2024-01-25T16:31:23+00:00http://zachholman.comZach HolmanHacking FIFA World Cup Rosters2023-10-11T00:00:00+00:002023-10-11T00:00:00+00:00http://zachholman.com/posts/hacking-fifa<p>I think one of the first signs of “ohhhhh they really fucked up” was seeing the passport number for the barber listed for a national team in last year’s 2022 Qatar FIFA™ World Cup®™.</p>
<p>Here’s a quick story of how I spent the run-up to the World Cup last November. If you’re one of those people who love reading detailed, cutting-edge technical analysis of security vulnerabilities available in the platform that runs the largest event on the planet… well, give an actual security researcher’s blog a try, because this story has none of that.</p>
<p>The killer technology used in this exploit is just three keyboard keys: command, <code class="language-plaintext highlighter-rouge">C</code>, and <code class="language-plaintext highlighter-rouge">V</code>. Copy and paste, baby.</p>
<h2 id="huh-that-url-looks-interesting">“Huh. That URL looks interesting.”</h2>
<p>Virtually anyone who has ever seriously created software for the web has (at least) one sick compulsion: we look at URLs differently. Can’t help it. We all make (at least!) one fuck-up early in our career and the rest of our lives are spent making sure we don’t fuck up the URL again.</p>
<p>One of my other sick compulsions is soccer. (Or football, for you freaks who later renamed the sport.) Love playing it, love watching it, love reading about it, love it all.</p>
<p>The name of the game is eNgAGemEnT these days, so most clubs and national teams love pushing behind-the-scenes videos: the players in training, the players doing weird shit like cooking on-camera, the players answering questions about Taylor Swift, things like that. Ahead of the World Cup, many national teams record things like the manager FaceTiming individual players and letting them know they made the roster.</p>
<p>One of the hip things to video was a staffer pressing the actual submit button on the official roster submission into FIFA. Neat! See, the button means it’s been sent off and now we’re actually ready to head to the World Cup! How exciting! ENGAGEMENT!!!</p>
<p>This is where both my compulsions met up: one of the national teams included the URL bar in their behind-the-scenes footage. Basically something like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>https://<roster submissions>.fifa.org/<sub directory>/45f8c989-4860-477e-8918-eef38805dc96
</code></pre></div></div>
<p>Those readers who are software developers will immediately notice the UUID at the end of the URL and already have this whole post figured out, of course, because you’re all a bunch of sick bastards. But I’ll dig into it a bit more.</p>
<h2 id="its-one-url-michael-what-could-it-cost-10-dollars">It’s one URL, Michael. What could it cost? 10 dollars?</h2>
<p>Any URL with a bunch of random characters in it will tend to raise eyebrows- though most of the time it won’t lead to security issues, <em>sometimes</em> it means the software developer is shoving something important where it shouldn’t be. In this case, it’s the key to the user session, which lets you do a kind of <a href="https://en.wikipedia.org/wiki/Session_fixation">session fixation attack</a> in order to hijack their session.</p>
<p>In basic terms, by having access to that URL, it’s like giving out the user’s username and password to log in as them. So like… yeah, not ideal, and something you learn pretty early on not to do. This is why it’s like catnip to developers; interesting-looking URLs are an exciting game of “oh shit, did they fuck that up?!”</p>
<h2 id="cmdc-cmdv">cmd+c, cmd+v</h2>
<p>This is always an easy thing to test- you just type in the URL and see what happens. But now that Apple has <a href="https://support.apple.com/en-us/HT212630">Live Text</a> you can just screenshot the video, highlight the URL, copy it and paste it, so it’s just laughably easy to test these things out.</p>
<p>In this case, you get dropped into FIFA’s internal national team management portal, logged in as whichever staffer clicked the button in the video.</p>
<p>A couple interesting things that could be seen here:</p>
<ul>
<li>The full 55-player provisional roster, in addition to staff, as well as all their DOB, passport numbers, legal name, things of that nature.</li>
<li>The full 26-player final roster and staff (including team barber and videographers and I think there was even a team chaplain listed).</li>
<li>The submission of uniform colors, flags, national anthem music, and similar details.</li>
<li>Legalese of team agreements to participate, similar documents.</li>
</ul>
<p>This was fairly alarming, and it raised the question of whether you could actually submit a <em>new</em> roster. My life-long dream of participating in a World Cup was inching closer and closer to reality (and all these other suckers had to work hard on their bodies for decades to get to that point, pffft! Shoulda just copied and pasted!)</p>
<p>The team I was looking at had already made their official roster submission, but the code was still there to make a submission. I believe they literally just commented out the form rather than hide it server-side, so it would have been pretty trivial to use the existing HTML to try crafting a new roster submission and seeing if that worked.</p>
<p>Alas, I am no World Cup-caliber talent, and it started feeling like wrapping up was the sensible thing to do. Read-only access is one thing, mutable access is another, and the latter is more questionable when your goal is to map out the vulnerability to get patched up.</p>
<h2 id="responsible-disclosure">Responsible disclosure</h2>
<p>One of the main takeaways besides “don’t write broken code” is to also assume you’re going to write broken code anyway and make it easy to report these problems to the right people. FIFA failed a bit on that account, but also did a lot better than I expected.</p>
<p>FIFA doesn’t have a specific <a href="https://en.wikipedia.org/wiki/Coordinated_vulnerability_disclosure">responsible disclosure</a> policy (although as an interesting side note, they do have a <a href="https://www.fifa.com/social-impact/fifa-guardians/reporting-system">reporting system</a> for disclosing physical safety concerns for children and vulnerable adults- goes to show that so often when we talk about “security” in the software industry, we forget how many organizations must describe “security” as far broader than just “software security”).</p>
<p>In lieu of an obvious reporting mechanism, I emailed <code class="language-plaintext highlighter-rouge">contact@</code> and <code class="language-plaintext highlighter-rouge">security@</code>, but also eventually found a more buried page about data protection (thank you EU!), and they were able to forward me to an information security email address for FIFA, in which case you kind of breathe a sigh of relief, because you finally found someone who knows something.</p>
<p>The process went really smoothly, in spite of global timezones. Took them a day or two to make changes to at least invalidate the session in question, which is pretty impressive considering the World Cup kicked off at that same time so I imagine they were pretty busy. I also contacted the federation who took down the original video within a couple hours and replaced it with the URL cut out of the shot (although strangely they never actually replied to my messages).</p>
<p>There are still some lingering concerns I had that I wasn’t able to confirm that they fixed up (can you iterate over the simple team ID parameter used all over the place to gain access to <em>every</em> team’s roster? etc), but such is software.</p>
<h2 id="a-happy-ending">A happy ending!</h2>
<p>A silly little error, sure, but I was pleasantly surprised to see a responsive technical team for a large organization able to make corrections quickly. AND! They’re going to give me a gift!</p>
<blockquote>
<p>As a small sign of appreciation and only I you want, the FIFA Data Protection and Cybersecurity Risk team would like to send you a small gift. If you are interested, please share with us your contact details, where we could send you something.</p>
</blockquote>
<p>So cool! Anyway, it’s been eleven months and I still haven’t received anything, FIFA. Maybe I fucked up with an address only on one continent <a href="https://www.bbc.com/sport/football/67010609">instead of the obvious three that’s needed for some reason</a>. My bad.</p>
How to Name a Startup2022-12-19T00:00:00+00:002022-12-19T00:00:00+00:00http://zachholman.com/posts/how-to-name-a-startup<p>You know the old joke… there are only two hard problems in computer science: NAMING YOUR STARTUP.</p>
<p>It’s always been hard to come up with a name for a new company, but it feels like over the last five years it’s gotten even goddamn harder. You spend a little time, brainstorm a solid name, discover six other startups — and fourteen open source projects — with the exact same name and all their derivatives, and you get a quote from the domain squatter with a really terrible .com variant of the name for a cool $150k.</p>
<p>Sheesh.</p>
<p>This is truly one of my least favorite parts of starting a company, but I’ve done it a number of times over the last decade or so, with pretty reasonable results: my calendar startup was <a href="https://during.com">during.com</a>, my hobby project was <a href="https://signed.com">signed.com</a>, and I’m just starting a new company now. (More on that… soon. We’re working on it.)</p>
<h2 id="start-in-your-feelings">Start in your feelings</h2>
<p>So what makes a good startup name? Like all Hard Things, there’s no fucking consensus here. It’s really subjective, and it’s heavily dependent on which compromises you’re willing to make in terms of uniqueness, brandability, domain availability, and whether its hot shit or not.</p>
<p>First step is to pull out your notes app and just regurgitate feelings onto the screen. Talk about emotions and thoughts you have while using your future product. Pull out nouns and verbs that describe your future workflows. Don’t think too much about concrete names; this is the brainstorm part, and you want to use this list in the future to generate names (and to refer <em>back</em> to days later when you realize your first attempts were all horseshit and went nowhere).</p>
<p>Then you can start building your list of names.</p>
<h2 id="whats-in-a-name">What’s in a name?</h2>
<p>The absolute best domain name is a short one-word dotcom that you can brand. And there’s one clear answer here: Stripe. It’s the goddamn best startup name and domain of all time. Six characters, easy to say, has a pleasant wordshape. It’s perfect. I’ve been trying to buy stripe.com from them over the last few years. They don’t seem receptive to switch their business to stripe.computers for my cool $6k offer, but I’m going to keep trying.</p>
<p>Barring getting stripe.com, there are a lot of other considerations to think about.</p>
<p>The first is: .com or otherwise? And this one I’ve torn my hair out for awhile. Previously I opted for .com, but it really feels like something’s turned the corner on domain valuations within the last three years in particular. We were getting quotes on dotcom, one-or-two word domains with a fairly consistent floor of $100k, with most reasonable domains around $200k-$750k (and up… it’s really not difficult to find domains in the millions).</p>
<p>I talked with a lot of others over the past few months, and it feels like there’s been a larger and more recent shift to non-dotcom acceptability. <code class="language-plaintext highlighter-rouge">.co</code> feels fairly weighty even compared to a traditional <code class="language-plaintext highlighter-rouge">.com</code>, and certain markets have a much easier time these days: AI and ML companies are slaying the <code class="language-plaintext highlighter-rouge">.ai</code> TLD, crypto has been pushing <code class="language-plaintext highlighter-rouge">.xyz</code>, and so on.</p>
<p><a href="https://twitter.com/lachygroom">Lachy Groom</a> had a good take: “I don’t think domains matter… not since the rise of search engines”.</p>
<p>So I’ve come around. We went with <code class="language-plaintext highlighter-rouge">.co</code> for our new company. I think PG’s tried-and-true “<a href="http://www.paulgraham.com/name.html">you must have a .com</a>” <em>might</em> be starting to crack.</p>
<p>I initially wrote the first draft of this post a few months ago, and I’ve been thinking about this particular point ever since (and have been actively studying new products as they launch). I think I feel more strongly about the “.coms aren’t the end-all be-all” now than I did previously. At some point, I think it might actually <em>flip</em>, where a highly desirable domain name might be seen as a red flag to have on day one unless you’ve raised millions pre-product. Even then… you’ve gotta have raised <em>millions</em>, because blowing an engineer’s entire salary (or three, or more) in the first few months on a domain is a pretty difficult ROI when you could be shipping.</p>
<h2 id="save-time-steal-other-peoples-work">Save time, steal other people’s work</h2>
<p>If you’re interested in something that isn’t <em>totally</em> unique — i.e., a combination of letters that haven’t even been registered yet — at this point it’s likely you’re going to have to go through a domain auction or otherwise buy the domain directly from an existing domain holder. Everything’s just been bought up years ago otherwise.</p>
<p>Once you go to one of the domain auction sites, you’ll quickly realize that 90% of the available domains are insane. xix00d0ll2.com, for example, might not be your idea of a truly great memorable name for your startup, but it’s going to fill up the domain results list, making it harder to sift out the diamonds.</p>
<p>But auction sites can be really helpful. I looked at a bunch of them throughout The Search, but I tend to keep going back to <a href="https://sedo.com">Sedo</a>. Their listings are dense, which means you can scan through them quickly, and they let you filter pretty effectively (“give me two word domains”, “put the keyword at the end”, etc.) <a href="https://dan.com">Dan.com</a> also wasn’t too bad.</p>
<p>The way I use these sites to “steal other people’s work” — read: be incredibly lazy — is to sort and filter by price (or traffic, or bids). There are literally too many domains for a single person to search through, so you can make use of what’s interesting to other people to slim down your own search. I found myself making a lot of searches around “show me domains more than $10k that are .com, max two words, no numbers or special characters, and related to [<em>keyword I was looking at</em>]”.</p>
<p>Another approach you can take to expand the possibilities here is to generate adjacent names. I found <a href="https://cunningbot.com">CunningBot</a> to be my favorite: it’ll generate gobs of domain possibilities, from related words to different domains with suffixes and popular word stems, as well as filtering only to domains that are available for registration.</p>
<p>If you find some interesting domains, toss them in The List.</p>
<h2 id="the-list">The List</h2>
<p>The List is simply a big ol’ list, one-per-line, of possible domains you think you could <em>potentially</em> be happy with. Include the price, if you know it. If you don’t think you’ll remember where you spotted it, add a URL (if it’s an auction or buy-it-now).</p>
<p>The idea is to generate a big list of these options. You’re still more or less in the brainstorming mode, so put them on there without too much consideration- a particular domain might not be <em>exactly</em> right, but it’s very possible it’ll trigger a better idea down the road.</p>
<p>For us, we ended up with around 50 options for domains to buy. Before that, we also had about 50 words or feelings around what we wanted to build.</p>
<p>If you, your cofounder, or someone you know is cursed and/or blessed with a level of <a href="https://en.wikipedia.org/wiki/Synesthesia">synesthesia</a>, this can help with narrowing down a list. I have a fairly mild form when it specifically comes to words, and I found it fairly helpful that I could look at a word and have a fairly good feel as to how pleasant the “shape” of the word felt. Whether or not that’s what others feel… well, who knows. But at least for me, the letters and the word itself can evoke a lot of different feelings and sensations that helped guide me a little.</p>
<h2 id="coming-to-agreement">Coming to agreement</h2>
<p>If it’s just you, great! You’re done! Find whichever one calls to you and/or is the cheapest or best.</p>
<p>If there’s two or more of you as cofounders or in the early team… it’s probably going to be hard to agree, one way or another. Because, again, at the end of the day, Stripe is the only one with the best name, and the rest of us are fucked. So there’s going to be a bit of compromise.</p>
<p>Don’t be afraid to share The List with other trusted people, though. After my cofounder and I went through a couple finalists, we showed those winning options to our spouses and… they both hated them (shocker, it wasn’t until we were almost ready to go with a final option that they finally had opinions! Much like code, no one really has a firm opinion until you say you’re about to make a decision.) But through that process we showed them The List and there was one that stood out that we looked at with fresh eyes, and… well, turns out we liked it after all. And then we bought it (for $5k, which was a lot more reasonable than others we were close to pulling the trigger on).</p>
<h2 id="other-considerations">Other considerations</h2>
<p>A few other thoughts that I’ve come to over the years:</p>
<ul>
<li>Capitalization and spacing can be strangely important, or absolutely drive you crazy. <code class="language-plaintext highlighter-rouge">GitHub</code> seems like a nice name, but I still go into a blinding rage every time I see someone type “Github” (and occasionally I’ll hear someone pronounce it “gith-ub”, but only once, because as soon as they mispronounce it that way they end up murdered, which is purely a coincidence, I swear).</li>
<li>That said, our next company is also that format, in that it’s TwoWords together, no spaces. This one bothers me to my core, but this time we have two more common easily-identifiable words, as opposed to “Git” and “Hub”, which are a bit more awkward. So we’ll roll the dice here.</li>
<li>If you’re having issues generating ideas and possible words, read a whole bunch. Don’t necessarily <em>read</em>, but look through blog posts and books and articles in your chosen product area and just look at all those words in a big block. See what jumps out at you. I found that to be super helpful in finding those “idea-adjacent” words that you won’t directly think up, but might work for a name.</li>
</ul>
<p>Overall… naming things sucks. There’s no way around it. But something to keep in mind: your name feels really permanent, but it’s not <em>really</em> permanent. If you hit a home run and find yourself with a $100M run rate, well, who gives a shit, just plop five million on the perfect domain name- you’ll be able to afford it at that point.</p>
<p>And you can change your legal name, too (not that it has to match your DBA name, either). GitHub was legally Logical Awesome, LLC for years until <a href="https://github.blog/2010-01-22-new-year-new-company/">we switched to GitHub, Inc.</a>. Seems daunting when you’re just getting started… but everything’s a lot easier down the line when you’re making revenue and have many other employees to help you make that transition.</p>
<p>But yeah, naming things. Terrible stuff. On the other hand, “TerribleStuff” might be a great ironic name for a company, so give that a shot.</p>
The Kobayashi Maru of Comparing Dates with Times2022-02-12T00:00:00+00:002022-02-12T00:00:00+00:00http://zachholman.com/posts/kobayashi-maru-of-comparing-dates-with-times<p>Saw a fascinating tweet this morning from the excellent <a href="https://userlist.com">Userlist</a> team.</p>
<center>
<blockquote class="twitter-tweet" data-theme="light"><p lang="en" dir="ltr">We just had a lengthy, one hour discussion with <a href="https://twitter.com/leoeuclids?ref_src=twsrc%5Etfw">@leoeuclids</a> and <a href="https://twitter.com/uibreakfast?ref_src=twsrc%5Etfw">@uibreakfast</a> in the <a href="https://twitter.com/userlist?ref_src=twsrc%5Etfw">@userlist</a> Slack about comparing dates with times… 🙈<br /><br />Does anyone have opinions on this? 🤪 <a href="https://t.co/G0muPbOhS9">pic.twitter.com/G0muPbOhS9</a></p>— Benedikt Deicke (@benediktdeicke) <a href="https://twitter.com/benediktdeicke/status/1492163503519670272?ref_src=twsrc%5Etfw">February 11, 2022</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</center>
<div class="my-8"></div>
<p>At a minimum, one hundred replies in a Slack thread is the going rate for asking a question about an edge case about times and dates in programming. Just for future reference.</p>
<p>Since Twitter embedding crops things a bit aggressively, here’s the image in the tweet directly:</p>
<p><a href="https://twitter.com/benediktdeicke/status/1492163503519670272"><img src="https://pbs.twimg.com/media/FLU6y_tWYAMAZc3?format=jpg&name=large" alt="Tweet screenshot" /></a></p>
<p>Immediately, the tweet replies were chaos. The answers included “Yes/Yes/No”, “No/No/No” (which was my initial response, but I’ve also chaotically changed my mind since then), “No/No/Yes”, “Dates are the worst”, and “Have you tried using 🍺? Maybe lots and lots of 🍻 and then maybe just like pretending this never happened?”</p>
<p>As someone who wrote <a href="/talk/utc-is-enough-for-everyone-right">entirely too much</a> about dates and times and edge cases, I found this discussion to be an exciting, total waste of time, and I really couldn’t wait to dig into it some more.</p>
<h2 id="first-of-all-its-all-wrong">First of all, it’s all wrong</h2>
<p>If you find yourself in this position, clearly something has gone wrong. And I say this without judgement, because unless you work in a clean room on a product that has no users and the code is no more than one hour old, you’re going to have issues with inconsistent data, and inconsistent storage of datestamps and timestamps is incredibly common. I ran into a similar problem this <em>just this week</em> with a multitude of inconsistent datestamps and timestamps I had inherited.</p>
<p>And that’s what happened here:</p>
<center>
<blockquote class="twitter-tweet"><p lang="en" dir="ltr">These are inputs from the user interface and data from a database. So it’s also very much about what (both technical and non-technical) people expect to happen.</p>— Benedikt Deicke (@benediktdeicke) <a href="https://twitter.com/benediktdeicke/status/1492457115851665408?ref_src=twsrc%5Etfw">February 12, 2022</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</center>
<div class="my-8"></div>
<p>What’s more, there’s an additional issue in the original question that was left out, which astute readers of <em>UTC is Enough for Everyone, Right?</em> might have picked up on already: there’s no timezone data! That’s fairly understandable for the date values, since timezones don’t tend to be needed (which, like most things in this realm, is not always true), but it would be needed for the time values to ensure a valid comparison (conceivably a comparison of <code class="language-plaintext highlighter-rouge">00:00:00</code> and <code class="language-plaintext highlighter-rouge">12:00:00</code> on the same “day” could be off by as much as a couple of actual days, depending on the timezone). And, of course, you’d need to store <a href="/talk/utc-is-enough-for-everyone-right#properly-storing-timezone-aware-times">more than just the offset</a> if you properly wanted to account for historical daylight saving time.</p>
<h2 id="apples-and-oranges-and-orange-colored-apples">Apples and oranges and orange-colored apples</h2>
<p>So this is kind of a no-win solution. I can make a valid argument for pretty much every answer in the tweet replies (especially the one about beer). The reason why it’s particularly frustrating is because we make these snap decisions all the time in our day-to-day lives, and it’s pretty easy. When I tell you to meet me for lunch at noon today, there’s a highly likely possibility that we’re talking about being in the same place, the same timezone, and the same day as each other, so we don’t have to spend a lot of time thinking about this.</p>
<p>The issue is that dates and times are kind of supersets of each other. Which is a bit of a paradox. But let’s look at it further:</p>
<ul>
<li>A <em>Date</em> can be thought of a superset of a <em>Time</em>, because all hours and minutes and seconds naturally belong to a certain day.</li>
<li>A <em>Time</em> can be thought of a superset of a <em>Date</em>, if you consider timespans to be an extention of a particular <em>Time</em>. Noon to noon spans two separate days. Or, well, just one day, if it’s a 24 hour day instead of calendar day. Even my paradox explanations have paradoxes in them.</li>
</ul>
<p>Both of these are kind of wrong definitions, and also kind of right, which is why you can make these justifications for so many answers here. It really comes down to <em>what you value</em>.</p>
<h2 id="literally-were-all-just-making-it-up">Literally we’re all just making it up</h2>
<p>This is the crux of why I find this stuff so fucking fascinating. We programmers famously tend to view the world in a real binary sense: the code runs or it doesn’t. The tests pass or they don’t. The record is valid or it isn’t. It’s a very helpful way of looking at the world… until it isn’t. Usually it’s not baked directly into the system, though.</p>
<p>There are certain examples where inherently correct answers don’t exist. My favorite example of this — and yes, I have favorite examples of time issues — is recurring events over a location-dependent daylight saving boundary.</p>
<p>Say you have a weekly 10am Pacific Time recurring calendar event with the rest of your dev team. Like a proper remote-first company, you’re <a href="/posts/remote-first#other-ways-to-not-fuck-up-remote-work">broadly distributed</a> instead of just having a main team in one city and one rando working “remote”. That’s great, but it also increases the odds of having one city or region or country having different daylight saving policies than the others (if they even have one at all).</p>
<p>You keep having your 10am call for a few months, and then Virginia, who lives in West Virginia, starts her daylight saving time in March. So now the 10am Pacific meeting time, which was 1pm her time, would still be 1pm for her since Pacific time always follows DST, too (except for Yukon, in Canada, which decided in 2020 to stop following DST, of course). But your teammate Brooklyn, who lives in Phoenix, doesn’t have daylight saving time because she lives in Arizona, which doesn’t follow daylight saving time (but don’t forget that the Navajo Nation in the northern part of Arizona <em>does</em> follow DST, so be sure to keep that in mind, too).</p>
<p>So: does Brooklyn keep at her normal 11am meeting time, or does she move forward with Brooklyn and have to start meeting at noon? Nothing in her life changed. It’s weird for a meeting to suddenly span her lunch break when it didn’t before.</p>
<p>The answer is: there is no answer. We’re just making it up. And <em>that’s</em> the answer. Google has a writeup on their <a href="https://developers.google.com/calendar/api/concepts/events-calendars">developer API docs for Calendar</a> broadly talking about how recurring events interact with invited attendees. One aspect:</p>
<blockquote>
<p>For recurring events a single timezone must always be specified.</p>
</blockquote>
<p>This is really the only reasonable approach that can be taken here. They decided that the creator of the original event wins out, and the effects of that permeate out to attendees as well.</p>
<p>This is also detailed in <a href="https://datatracker.ietf.org/doc/html/rfc5545">RFC 5545</a>:</p>
<blockquote>
<p>* The “DTSTART” and the “TZOFFSETFROM” properties MUST be used when generating the onset DATE-TIME values (instances) from the “RRULE”.</p>
</blockquote>
<p>(RFC 5545 is a great, titillating read, too. Thought I was reading a Harlequin romance novel with how vividly they describe all the <code class="language-plaintext highlighter-rouge">RRULE</code> specifications and permutations.)</p>
<h2 id="so-just-make-it-up">So just make it up</h2>
<p>So: bringing it back to the original topic at hand… I think this is a case where we get to just make the arbitrary decision. There’s no “right” or “wrong” answer.</p>
<p>I was curious how others broadly thought about the question, so I looked into it some more.</p>
<p>Ruby has a <a href="https://ruby-doc.org/stdlib-3.1.0/libdoc/date/rdoc/DateTime.html#class-DateTime-label-When+should+you+use+DateTime+and+when+should+you+use+Time-3F">lovely treatise about Shakespeare</a> while they discuss using <code class="language-plaintext highlighter-rouge">Time</code> versus <code class="language-plaintext highlighter-rouge">DateTime</code> which touch on some of these issues- it’s worth reading the whole section, but this part is most relevant here:</p>
<blockquote>
<p>So when should you use <code class="language-plaintext highlighter-rouge">DateTime</code> in Ruby and when should you use <code class="language-plaintext highlighter-rouge">Time</code>? Almost certainly you’ll want to use <code class="language-plaintext highlighter-rouge">Time</code> since your app is probably dealing with current dates and times. However, if you need to deal with dates and times in a historical context you’ll want to use DateTime to avoid making the same mistakes as UNESCO. If you also have to deal with timezones then best of luck - just bear in mind that you’ll probably be dealing with local solar times, since it wasn’t until the 19th century that the introduction of the railways necessitated the need for Standard Time and eventually timezones.</p>
</blockquote>
<p>.NET also kind of goes with a <a href="https://docs.microsoft.com/en-us/dotnet/api/system.datetime.kind?view=net-6.0">“oh god just try to avoid any of this type of thing”</a> philosophy:</p>
<blockquote>
<p>To determine the relationship of <code class="language-plaintext highlighter-rouge">t1</code> to <code class="language-plaintext highlighter-rouge">t2</code>, the Compare method compares the Ticks property of <code class="language-plaintext highlighter-rouge">t1</code> and <code class="language-plaintext highlighter-rouge">t2</code> but ignores their <code class="language-plaintext highlighter-rouge">Kind</code> property. [Ed. note: <code class="language-plaintext highlighter-rouge">Kind</code> here is effectively timezone-related data.] Before comparing <code class="language-plaintext highlighter-rouge">DateTime</code> objects, ensure that the objects represent times in the same time zone.</p>
</blockquote>
<p>Something called a “TIBCO ActiveMatrix BPM 4.2” <a href="https://docs.tibco.com/pub/amx-bpm/4.2.0/doc/html/bpmhelp/GUID-D7D6CA9D-FE7F-4F7E-A882-DC4332EB1B9F.html">punted on it entirely</a>:</p>
<blockquote>
<p>The method still works if the date/times are more than 14 hours apart, but if they are less than 14 hours apart, the result is deemed to be indeterminate.</p>
</blockquote>
<p>Moment.js <a href="https://momentjs.com/docs/#/query/is-same/">also has some caveats</a> with comparisons:</p>
<blockquote>
<p>As the second parameter determines the precision, and not just a single value to check, using day will check for year, month and day. [Ed. note: this basically means you have to choose which precision to decide- in the case of the original tweet, you’d pick either days or seconds.]</p>
<p>[ … ]</p>
<p>If the two moments have different timezones, the timezone of the first moment will be used for the comparison.</p>
</blockquote>
<h2 id="i-dont-believe-in-the-no-comparison-date-scenario">I don’t believe in the no-comparison date scenario</h2>
<p>This whole post is basically a long-winded way of reiterating that humans create some very weird scenarios when it comes to dates and times. Raphael Schaad, founder of the fantastic <a href="https://cron.com">Cron</a> calendar, has a <a href="https://twitter.com/raphaelschaad/status/1424033683481284612">long-running thread</a> on broken assumptions of calendaring that, frankly, don’t always have logical solutions. It’s all a bunch of trade-offs.</p>
<p>And that’s why I found the original tweet so interesting. We’ve all had situations where the data wasn’t consistent, or a third party munged data incorrectly for us, or where we’ve inherited data that was saved under incorrect assumptions (correct as they might have been at the time). The thought process can lead to a hundred-reply Slack thread. Or an entirely too-long and too-detailed Saturday morning post about dates and times.</p>
<p>So, with all that said… enjoy the rest of your Saturday!</p>
<p>Just kidding. I know some of you are on to Sunday already. And some of you will — gasp — read it years from now! Pretty sure no one read this a week ago, though. If you did, please remind me a few days ago that I will need to write this a few hours ago from now.</p>
<div class="bg-gray-200 mt-12 p-4 text-sm rounded text-center">
You can <a href="https://news.ycombinator.com/item?id=30315984">discuss this on Hacker News</a> if you'd like.
</div>
How does Angel Investing?2021-05-13T00:00:00+00:002021-05-13T00:00:00+00:00http://zachholman.com/posts/how-does-angel-investing<blockquote>
<p><strong>“You either die a hero, or live long enough to see yourself become a venture capitalist.”</strong><br />
<small>— Unofficial motto of Party Tent, the famous two-faced venture-backed startup that imploded one dark night when their lead designer got busted for not paying the font licensing fees for Gotham</small></p>
</blockquote>
<h2 id="making-the-jump-from-software-to-investing">Making the jump from software to investing</h2>
<p>I started making the transition from software into angel investing a couple years ago. A few things immediately became apparent:</p>
<ul>
<li>I don’t know what I’m doing</li>
<li>I wish I had paid more attention (and had more access) to financial discussions at previous startups I worked at</li>
<li>And oh neat: this is pretty exciting</li>
</ul>
<p>It’s been a couple years now, and I’ve learned a lot. And since I’ve recently seen <em>so many</em> developers start showing an interest in making a similar leap… I thought I’d share some thoughts on making that transition.</p>
<p>Don’t worry about a possible impending global financial crash or the fact that valuations are totally bonkers because of all the other new investors jumping into the mix: you’re an investor now, dammit, and metrics and forecasting don’t need to be your priority anymore. (Kidding. Probably.)</p>
<h2 id="the-cold-start">The cold start</h2>
<p>I think it’s understandable that most people who have worked for startups in the past have no idea how the whole industry really works. They might be able to build an amazing, scalable backend perfectly written in eight different programming languages (except JavaScript), but when it comes to raising money, when it comes to stock treatment and valuation differences, when it comes to analyzing a new company — which might still be just a single person and a napkin sketch! — it’s just not their wheelhouse.</p>
<p>Part of that is a failure of previous work experiences: as an industry, we don’t do a really great job at teaching these things, or even worse, we hide them behind the “that is confidential information!” justification. At the first startup I worked at, our CEO walked us all through our books line-by-line and described how the business worked, saying “if a company hides this from you, treat it as a red flag”. I think about that a lot.</p>
<p>So the trick is to cram all that information you had missed out on and get yourself up to speed quickly. One straightforward way to start is to — unsurprisingly — read. There’s a lot of great information out there: I’m a fan of Holloway’s <a href="https://www.holloway.com/b/angel-investing">guide to angel investing</a>, which is a deep-dive into angel investing in particular. But don’t forget that there are always <em>two sides</em> to every angel investment transaction: yours and the founder’s. So I also think it’s super helpful to read up on “how to raise” resources, too. Brad Feld and Jason Mendelson’s <a href="https://www.venturedeals.com">Venture Deals</a> is kind of the gold standard. That’s actually what I first read before starting to raise money for <a href="https://zachholman.com/posts/staying-productive-solo-founder">During</a> a few years back. There’s a ton of overlap between raising money and investing in companies, and if you’re looking to do one of them, I highly suggest doing the other, too. You learn so much about investing from trying to raise money. And you learn so much about raising money by investing.</p>
<h2 id="investing-without-money">Investing without money</h2>
<p>One of the first things I hear from others who are interested in becoming an angel is “what’s the minimum check size to get started”? And, naturally, that’s an important question to ask, especially because people are all sorts of gradients between “I don’t have any extra money for this” and “I own Amazon”.</p>
<p>The minimum check size is <strong>zero</strong>.</p>
<p>The thing I hate <em>most</em> about investing is that the iteration cycle is so expensive. Both in terms of money — it’s your money, and you ostensibly don’t want to piss it away — and it’s especially expensive in terms of time. Think you found a breakout company? Cool, now just wait 5-10 years before you can get a full result. Makes you pine for software, where you can make a mistake, discover it when you deploy it three minutes later, push a fix, and redeploy, all within ten minutes. The investing iteration cycle sucks. And if you’re just getting started, it can be <em>really</em> expensive before you even start becoming competent.</p>
<p>Something I tried to leverage before taking investing seriously is to do it without money at first. There are a few ways to do that:</p>
<ul>
<li><strong>Advising</strong>. I advised companies for years before investing in a single startup. I had similar goals going in: I had some domain knowledge that could be helpful for founders, and I wanted more chips on the table to increase chances of making money on startups. (Being involved in <a href="https://angel.co/blog/venture-returns">more companies leads to better returns than being involved in good companies alone</a>.) Being a startup advisor is a good way to gain insight into the executive-level decisions you may not have had much exposure to in the past, and it also helps you expand your mindset into more companies than just the one you’re working full-time on. It also prepares you as a future angel investor to help figure out how to be an asset to a company when you’re not dealing with them on a daily basis. That’s one of the trickier things of being an angel, I think; you have to be clear where you can help at the drop of a hat, and be clear to the founder when you’re out of your depth. Being an advisor to a company comes with it a slew of other considerations; might have to write more about that in the future (<a href="https://twitter.com/holman">let me know</a> if you’re interested!)</li>
<li><strong>Syndicates</strong>. Angel syndicates have been around for decades, but recently they’ve become far easier to get into as a newbie. <a href="https://angel.co/syndicates">AngelList Syndicates</a> is the most well-known these days, and it does make it easy to get started if you’re an <a href="https://help.venture.angel.co/hc/en-us/articles/360048803251">accredited investor</a>. One of the best things you can do is to join one (or preferably many) syndicates. You’ll get deals in your inbox every couple days and you can use that to use a critical eye and ask yourself, “well, would I actually invest in this, or not?” Most syndicates have a minimum investment amount — usually $1,000 or $5,000 — but the real minimum is zero: you can just decide not to invest in the deal. More deal flow (especially if you don’t have a ton of connections yet) means you can iterate far quicker on “is this startup a good investment”? It’s helpful for future founders, too, since the more pitches you see, the better off you’ll be in making your own pitch. Really can’t stress how helpful this was for me: I spent a few months basically just monitoring deals, making mental notes as to how I analyze a pitch, and then I slowly started making small investments here and there until I became more comfortable. Certain syndicates are even more helpful with this, too: I’m currently setting up <a href="https://angel.co/s/xubbers/drdiJ">a syndicate for former GitHub employees</a> with an emphasis of being a gentle start to gain an understanding (and exposure) to the process. Take a look if a previous employer you worked at had an alumni investment group. Your university might have one as well.</li>
<li><strong>Crowdfunding</strong>. This is really enabled by very recent changes in US law allowing different treatment of crowdfunded investment rounds. <a href="https://republic.co">Republic</a> seems to be one of the early winners of this kind of approach: they host crowdfunded raises for vetted companies that you can invest in, some for as low as $100. But you can also browse through their existing public pitches and help your iteration cycle, too. (Take a look at <a href="https://republic.co/gumroad">Gumroad’s $5M raise</a>, for example.) Again, the name of the game is getting your eyes on as many deals as possible so you can learn and evolve your own instinct for your own later investments.</li>
</ul>
<p>Another option, if you’re feeling lonely, is to just add the phrase “angel investor” to your Twitter profile. You’ll start getting lots of randos sending you weird pitches. It’s… uh, not necessarily a recommended approach.</p>
<h2 id="how-can-i-be-helpful">How can I be helpful?</h2>
<p>One of the common jokes is that every investor will inevitably end an email with the phrase “How can I be helpful?” It comes from a good place, of course — sure, everyone <em>wants</em> to be helpful — but just expressing the desire to be helpful isn’t really… well, <em>helpful</em>.</p>
<p>Before really jumping into investing, it’s worthwhile to really ask yourself how you’re <em>actually</em> planning on being helpful. Otherwise… why are you even doing this? Just throw a bunch of call options on $GME or some shit instead. Part of the benefit of angel investing is using your background to hopefully improve your return on investment.</p>
<p>There are a lot of ways to be helpful, but I’ve found for early-stage startups that are three main areas where help is always sorely needed:</p>
<ul>
<li><strong>Hiring</strong>. Hiring hiring hiring. Hiring is always the problem. Most startups you invest in probably have at least some network they can fish for leads, but the first 10-20 hires are critically important, and they can be tricky to find. This is where generalists get their time to shine, and attracting these types of people (or even just discovering them) can be difficult. Being able to mine your own network for possible hires, or simply being available to talk to the founder about candidates, is really helpful. One of the startups I’ve invested in does a good job of letting targeted hires talk directly to an existing investor, and that’s been really valuable to landing hires that otherwise might head elsewhere. You want to be that kind of person who can help out in this sapce.</li>
<li><strong>Customers</strong>. After hiring, I think helping with customers (depending on the business) is the second most important thing for an early startup. You’ll start getting your monthly investor updates from your portfolio company, and more often than not they’ll reach out for leads into companies of <em>x</em> size in <em>y</em> industry. It’s good to be able to make those introductions to potential customers. Revenue, as you might imagine, turns out to be a good thing.</li>
<li><strong>Domain knowledge</strong>. This one really depends on the circumstances, but sometimes there’s just a great fit between you and your portfolio company. Maybe you’ve worked on something similar in the past, or are a huge user of the product they’re building. Or, maybe the company is really struggling with marketing, and that’s something you love digging into. This area can change a lot as a company grows, so it’s worth thinking prior to putting in a check about what’s special about you now and what’s special about you a few years down the line, when things are different. And yes, I think you’re special; don’t be so hard on yourself.</li>
</ul>
<h2 id="you-and-them">You and them</h2>
<p>There’s a lot more to dig into; if you’ve never done this before, virtually everything is a learning process. I’m still learning what feels like new things every day. But it’s really been fun, especially if you have some experience in the industry and you find yourself getting burned out on the software side of things. Just talking to other companies, seeing different approaches and mentalities of how they attack problems… it can be pretty eye-opening. And a lot of the time the advice you give as an investor or advisor doesn’t even have to be perfect advice. Sometimes it’s just helpful to say “whoa, don’t do that, because I did that early on at this other startup and it was a fucking <em>terrible</em> decision, and here’s why”.</p>
<p>The only other aspect that ties into all of this is to keep remembering what you’re doing here. For these companies you’re a source of capital. And that’s great- that’s how big things can come from humble starts. Hopefully you’re a source of reassurance, wisdom, and encouragement, too. But you’re not changing the world; the founders and their team are. You’re not some sort of ridiculous genius savant for picking winners; you might just be competent at wiring money back and forth. It’s worth pointing that out because the power dynamics here are totally fucked up. People come to you for money, and you get to make the ultimate decision: <strong>yes</strong> or <strong>no</strong>. Easy to get wrapped up in that… but try not to.</p>
<p>Try to help people, try to make good decisions, and hopefully things work out for everyone.</p>
My Favorite Tweet2020-11-17T00:00:00+00:002020-11-17T00:00:00+00:00http://zachholman.com/posts/my-favorite-tweet<p>I wrote my favorite tweet way back in 2013:</p>
<div class="my-16">
<blockquote class="twitter-tweet tw-align-center" data-theme="light"><p lang="en" dir="ltr">So excited to announce something I’ve been working on for ages… a new todo app: <a href="https://t.co/TAjy0z6snK">https://t.co/TAjy0z6snK</a><br /><br />It uses touch, so it’s webscale.</p>— Zach Holman (@holman) <a href="https://twitter.com/holman/status/364509812962242560?ref_src=twsrc%5Etfw">August 5, 2013</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>
<p>That tweet <a href="https://github.com/holman/dotfiles/commit/d774e970a88a04aca8024178849301af6d6ac5c3">links to a file</a> which is virtually a bash one-liner:</p>
<div class="language-sh highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">touch</span> ~/Desktop/<span class="s2">"</span><span class="si">$(</span><span class="nb">echo</span> <span class="nv">$@</span><span class="si">)</span><span class="s2">"</span>
</code></pre></div></div>
<p>I fucking love this tweet. It’s simple, and it’s hilarious. The idea was — especially back then, during the era of Wunderlist and Things and new todo apps being released seemingly every week — that everyone was spending incredibly too much time coming up with ridiculous task systems and convoluted organizational hierarchies. Really, the easier thing is to just drop a blank file on your desktop to remind you to do something, and when you’re done with it, delete the file. Easy. That was <a href="https://zachholman.com/posts/inbox-zero-everything-zero/">my process</a> for getting things done. I’d tried so many different systems… they were all so fucking complicated.</p>
<p>I fucking love this tweet because it’s 100% correct. Circa 2013 me absolutely worked in this manner. I’d have a couple week-long tasks I’d want to build out, or do, or accomplish that week, and then I’d leave a couple of reminders to myself throughout the day as I move in and out of different tiny tasks. It was incredibly insightful to cut through the bullshit and realize I didn’t <em>need</em> anything more complex.</p>
<p>I fucking love this tweet because it’s <strong>completely and utterly wrong</strong>. I still work in this manner — I have a single file on my desktop right now that’s only there to remind me to try installing <a href="https://www.room-assistant.io/">room-assistant</a> in the next week or so. And that’s how I use it: “let me kind of keep this in mind to do eventually”. But the thought of basing my whole life and workflow off of such a simple system today seems completely bonkers; it really cracks me up.</p>
<h2 id="same-but-different">Same, but different</h2>
<p>Like most people, my life’s gotten more complicated as I’ve gotten older. Gone are the days of my singular focus being that day’s work tasks; they’ve been replaced with needs to keep track of like, paying a bill every thirteen and a half weeks and I really can’t forget that otherwise I don’t know the world will explode or something. I use <a href="https://culturedcode.com/things/">Things</a> pretty religiously these days, and, much like my calendar, if it’s not on there I’m simply not going to do it.</p>
<p>It’s wrong to couch this as simply a “young people are idiots” tale, though. I mean, yes, they are, but that’s besides the point. I fucking love this tweet because it shows how <em>I’ve changed</em> since then. And I don’t mean that in a negative way: it’s just what ended up happening. Maybe I’ll eventually go back to a simpler approach, maybe I won’t. It’s what works for me now.</p>
<p>I fucking love this tweet not because it’s a good reminder that what someone says today isn’t what they might say the next day or year or decade. Again, it doesn’t make them <em>wrong</em>; it just makes you really question the context of what’s being said (which is something we should all get better at anyway). Someone can both say something that’s wrong <em>to you</em> and correct <em>for them</em>. And sometimes those two people are the same person.</p>
<p>Also I love this tweet because all jokes written out in POSIX shell are hilarious to me.</p>
<p>So yeah, I think it’s a good tweet. It reminds me of where I was and where I am. So it’s my favorite tweet.</p>
<p>I mean, for now.</p>
Write Angry2020-11-11T00:00:00+00:002020-11-11T00:00:00+00:00http://zachholman.com/posts/write-angry<p>I <a href="https://twitter.com/holman/status/1325906595973197825">redesigned my blog</a> this week, and as part of that I ended up going through every single blog post I’ve written over the past eleven years.</p>
<p>It’s a strange experience to write publicly for this long. There’s an awful amount of blog posts I just simply don’t agree with anymore. A lot of the posts from early 2010-2012 GitHub seem hopelessly <a href="https://zachholman.com/posts/scaling-github-employees/">optimistic and romantic</a> these days. Some posts <a href="https://zachholman.com/posts/swearing/">blew up in the industry</a> for a week and completely stressed me out to write. Now they’re just amusing to think back on as even being stressful now.</p>
<p>Regardless of how I feel about them today, though, I’m still pretty proud that I tried to <strong>write while angry</strong>. Or, put another way: I chose to write about things that I cared deeply about and <em>felt like I had a secret perspective on</em>. You should be pissed that everyone else doesn’t agree with you, or that many people are doing things wrong.</p>
<p>This is <a href="https://speaking.io/plan/talks-are-entertainment/">the case for public speaking</a> as much as it is for writing. Especially in tech, I see a lot of milquetoast blog posts and talks from people trying to make a name for themselves with a bland viewpoint. If you’re not contributing to changing people’s minds, then there’s no point in writing. You’re just contributing some vanilla shit to all the other vanilla noise we have out there.</p>
<h2 id="playing-the-heel">Playing the heel</h2>
<p>I never had much of a problem being the bad guy with this stuff. Not in terms of being <em>morally</em> wrong, but in terms of being fairly black-and-white when it comes to my arguments made.</p>
<p>Take “meetings are bullshit”, which pops up in my talks and posts in the early 2010s a fair amount. I fucking hate meetings. I think things like email and chat are better ways to build software (and indeed, the rise of Slack has proven that to be true). But it’s not that we didn’t have meetings at GitHub, or get together for synchronous meetups from time to time. That also was a big component of work. But it’s much easier for someone in a small company to tell their boss “HEY THE GITHUB GUYS FUCKING HATE MEETINGS LET’S CHANGE THINGS UP TOO!” And usually that company would find their own happy balance of what worked for them.</p>
<p>Getting people — and especially companies — to change how they work, or what tools they use, or how they interact with their coworkers is really goddamn hard to do. But I think it’s just more effective to position yourself on the far extreme and let people discuss it from there. For one, it forces people in Hacker News comments, on Twitter, at lunch, to clarify their own opinions and make a stance of their own. You end up with people finding their own common ground with the kernel of what you’re trying to argue for.</p>
<h2 id="belittle-the-process-not-the-rationale">Belittle the process, not the rationale</h2>
<p>Everyone thought GitHub’s main competition early on was Subversion, which was completely wrong. Our largest competitor was <code class="language-plaintext highlighter-rouge">HeaderFile_FINAL_2.2009.JOHN-checkpoint_FINAL.jpeg</code>. People didn’t know Git, much less version control in general. And when you’re trying to convince potential customers that your way is better, you can’t just settle with “yeah this will help you keep cleaner filenames”- you have to go really fucking strong and point out that the way they’re doing things is <em>wrong</em> and life will be <em>so much better</em> with these changes.</p>
<p>The most ideal behavior for a society? Maybe not. But I think that last point is the key: you can get angry about things, but always keep it pointed squarely at an aim to improving people’s lives. You can be negative, but only if you try to uplift through that negativity. Belittle the existing process, not the existing people or decisions of how they got to that point.</p>
Double Shipping2018-08-08T00:00:00+00:002018-08-08T00:00:00+00:00http://zachholman.com/posts/double-shipping<div class="mb-16">
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">If you’ve built, written or created something new, talk about it publicly more than just once. You don’t need to go overboard, but people generally want to know what you’re doing, want to support what’s new, and sometime miss things. 👏 It’s cool to be proud of what you’ve done.</p>— Zach Holman (@holman) <a href="https://twitter.com/holman/status/1026893425575165952?ref_src=twsrc%5Etfw">August 7, 2018</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>
<p>The smaller you are, be it scrappy startup or just someone doing something solo on the side, the more important it is to stretch your own network out and get eyeballs where you can. Even <a href="https://zachholman.com/posts/open-source-marketing/">marketing open source</a> is worth talking about; projects don’t <em>just happen</em> to get popular, even if it’s a free altruistic thing. Sometimes it just takes effort to get the word out.</p>
<p>One way of doing this is to increase the volume: crank that Marketing Tool™ SaaS you pay money to each month and auto-tweet daily in all caps broadcasting to the void until, dammit, you get some fucking leads.</p>
<p>You don’t need to be that jerk, though. There’s a lot of reasonable things you can do to get the word out without driving people bonkers. Early on at GitHub we called this “double shipping”: namely, taking something you’ve done and finding ways to announce it more than once.</p>
<h2 id="talks-arent-valuable-as-just-talks">Talks aren’t valuable as just talks</h2>
<p>Public speaking can be a bit scary. It’s not just the talk prep that sucks; for almost everyone, getting up on stage is a little terrifying. And “just imagine everyone is naked!” is <a href="https://speaking.io/">terrible advice</a>.</p>
<p>I always thought the 200 people in front of me at the conference was the real audience for a talk. And then I realized that, potentially, it’s just a small, small segment. A few years ago I started <a href="https://zachholman.com/talk/utc-is-enough-for-everyone-right">writing up</a> long-form <a href="https://zachholman.com/talk/firing-people">versions</a> of <a href="https://zachholman.com/talk/move-fast-break-nothing/">my talks</a>. I’d do it right after I gave the talk (usually on the flight home, when it’s still fresh in my mind and I can easily regurgitate it into words), then I’d slap a nice design on it, and publish it like any other post or thing I did.</p>
<p>The result? The dozens of hours of preparation I put into the talk for the 200 people in the room ends up getting viewed by hundreds of thousands of people online. The physical talk itself ends up being kind of the small side show.</p>
<p>Leverage the work you’ve already finished so a wider audience can see it. Switching mediums can make for a much bigger impact; it’s neat.</p>
<h2 id="the-long-tail">The long tail</h2>
<div class="my-16">
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">As a jr. dev I was floored by how all the famous tech industry people had so much open source, blog posts, and *stuff* out there. Made me feel tiny.<br /><br />I didn’t realize how much time plays a role, though. Give it a few years and you’ll be surprised at what you’ve built and learned.</p>— Zach Holman (@holman) <a href="https://twitter.com/holman/status/1026890404271202304?ref_src=twsrc%5Etfw">August 7, 2018</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
</div>
<p>This one took me a long time to really see for myself. I mean, I’d <em>see</em> it, when The Famous Blogger I Like keeps self-referencing great content in blog posts and tweets. But I just took this as, wow, this person is truly a Very Smart Person, look at all the stuff they’ve done!</p>
<p>It wasn’t until I started hanging around these Very Smart People when it became clear that they’re just Very Normal People Who Happen To Have Spent More Time In The Industry Than I Have.</p>
<p>The longer you build things, the more of a base you can leverage. It’s kind of hard to appreciate, at times. For example: <strong>I’ve been doing this to you all over this damn post</strong>. Up until this point, I’ve:</p>
<ul>
<li>Embedded two of my own tweets</li>
<li>Linked to one of my blog posts</li>
<li>Linked to three of my own talks</li>
<li>Linked to an entire content site I’ve built</li>
</ul>
<p>Some of these things I’ve linked to are years old and, hell, I don’t even know if I really agree with them anymore. But the point is: it’s pretty easy to slide these things in, since the longer you write, the easier it is to fall back on something tangentially related to what you wrote in the past.</p>
<p>And it does work: I’ll embed an older tweet or link in a post, and sure enough, I’ll start seeing it get picked up again. Sure, now that I’ve brought your attention to this trick, I’m not sure it’ll still work the rest of this post, but who knows.</p>
<p>Anyway, what I’m really saying is that <a href="https://zachholman.com/posts/startup-interviewing-is-fucked/">technical programming interviews in our industry are really fucked up right now</a>, and somehow that relates to all this.</p>
<h2 id="two-step-ship">Two-step ship</h2>
<p>One of the things we did all the time at early GitHub was a two-step ship: basically, ship a big launch, but days or weeks afterwards, ship a smaller, add-on feature. In the second launch post, you can refer back to the initial bigger post and you get twice the bang for the buck.</p>
<p>This is even more valuable than on the surface, too: you get to split your product launch up into a few different pieces, which lets you slowly ease into the full usage — and server load — of new code.</p>
<p>We did this <em>all the time</em>. I’m surprised more people didn’t call us out on this, really. When I shipped <a href="https://blog.github.com/2014-07-28-the-new-github-issues/">GitHub Issues</a>, from the start we had always intended to ship <a href="https://blog.github.com/2014-10-06-managing-issues-and-pull-requests-across-repositories/">Issue and Pull Request Dashboards</a> soon afterwards.</p>
<p><a href="https://blog.github.com/2010-08-10-github-jobs/">GitHub Jobs</a> had a <a href="https://blog.github.com/2010-08-03-github-jobs-pre-launch/">pre-launch</a> post and a <a href="https://blog.github.com/2009-11-24-looking-for-a-job-let-github-help/">pre-pre-launch post</a>.</p>
<p>When we shipped <a href="https://blog.github.com/2010-06-29-introducing-organizations/">GitHub Organizations</a> in 2010, it generated a pretty ugly pricing reaction, which was a bit of a bummer. We waited a day, then posted a <a href="https://blog.github.com/2010-06-30-organizations-for-small-businesses/">pricing update</a> which fixed the problems… but also kept us in the headlines another day. (This time in a more positive light, luckily. But regardless, a lot of people knew that we had launched Organizations.)</p>
<p>Awhile back, I got into a lot of trouble with thought leaders on the internet who didn’t like that I had said Bad Words, like “fuck” and “shit” and possibly truly offensive things like “I like shell scripting”. Some creepy uncle took time out of his talk to complain that I had swore in my earlier talk (neglecting to notice that he ended up swearing <em>more</em> in his own talk; and yes, I later counted). Then the blog posts and tweets and comments started.</p>
<p>First post was <a href="https://www.hanselman.com/blog/ProfanityDoesntWork.aspx">2011/11/03</a>, second was <a href="https://web.archive.org/web/20170614161951/http://rob.conery.io/2011/11/08/some-people-not-have-way">2011/11/08</a>, and I finally decided to write about it myself on <a href="https://zachholman.com/posts/swearing/">2011/11/09</a>. Didn’t bother me too much; everyone on Hacker News was talking about me and my talk for the entire week. It was great. Don’t underestimate spreading these things out if it fits the bill.</p>
<h2 id="double-shipping">Double shipping</h2>
<p>My primary concern isn’t that people will abuse all this and become annoying as they talk their book over and over again; that happens, but there’ll always be those people out there.</p>
<p>I’m more concerned about the number of people who spend hours — or much, much longer! — on something they care about, make a small tweet about it, and get dismayed that it didn’t immediately blow up and take the world by storm. And then that impacts their motivation to work on future projects.</p>
<p>It’s fine to hit the notes you want to hit more than once, especially if you can bring new value each time. (And in the tech world, adding simple follow-on features can be a great way to do that.)</p>
<p>Everyone’s not always standing by 24/7 to read up on what you’re doing. People want to see what you’re working on, and people will support you… if you help them help you.</p>
UTC is Enough for Everyone, Right?2018-05-29T00:00:00+00:002018-05-29T00:00:00+00:00http://zachholman.com/talk/utc-is-enough-for-everyone-right<div class="pa6-l pa3">
<div class="w-60-l">
<h2 id="since-the-dawn-of-time">Since the dawn of time</h2>
<p>Years ago, I worked with a friend who had built a few scheduling calendars in a previous freelancing gig.</p>
<p>Sometimes we’d be working on something that tangentially related to time, and as kind of a recurring in-joke he’d always tell me:</p>
<blockquote class="mv4 bg-white black pv4 b--pink bw3 f4">
Zach, whatever you do: just don't <em>ever</em> build a calendar.
</blockquote>
<p>Anyway, I’m Zach Holman and I’m <a href="http://during.com">building a calendar</a>.</p>
<p>I guess I never could follow directions very well.</p>
<p>Building a calendar sucks. Like there’s really cool shit you can do, since every calendar out there today is basically straight outta 2005, but at the end of the day you’re stuck dealing with all of the edge cases that all your dork friends have warned you about since the dawn of time. (Like literally, <em>the dawn of time</em> is a separate edge case you have to account for as well.) So there’s been a lot of heinous stuff we’ve had to work with.</p>
</div>
<div class="flex-l items-start">
<div class="w-60-l">
<p>I’ve made notes of the egregious things I’ve learned about programming with time and pulled them together as a talk. This is the written companion piece, which is sort of a super set of the talk, since I had way more notes than what I could shove in a single talk.</p>
<p>Beyond that, though, there’s also a lot about time itself that is properly hilarious, and it’d be a travesty to not talk about the country that recently decided to skip a certain day, or that the Unix epoch isn’t technically the number of seconds since January 1970, or that February 30 happened at least twice in history.</p>
<p>It turns out humans have had a long, long history of poorly dealing with time, so when you hammer your head against the wall trying to deal with a timezone bug, well, you’re just the last in a long, long line of human beings that are terrible at all this! Congrats. You’re pretty unremarkable.</p>
</div>
<div class="w-40-l mt4 ml4-l bg-white black f6 pa3 br1 lh-copy flex">
<div class="flex-column">
<i class="fal mr3 fa-2x">lightbulb</i>
</div>
<div class="flex-column">
<p class="ma0">I've given this talk three times: at <a href="https://www.youtube.com/watch?v=aEvB98CstOk">RubyConfIndia</a>, RubyConf Australia, and Balkan Ruby. (Don't worry, non-Rubyists; there's no Ruby in this post. The conference topics were just happenstance. Also I love the word "happenstance".)</p>
<p>Each of those talks were filmed, and I'll link to each of them above once the recording's been made available, in case you're more of a watch-and-listen kind of person.</p>
</div>
</div>
</div>
</div>
<div class="video">
<video class="z-1" src="/video/utc-one.mp4" poster="/images/talks/utc/poster-one.jpg" width="100%" preload="" autoplay="" loop="" muted="" playsinline=""></video>
<div class="absolute top-0 white z-2 w-50 mt2 ml5 o-80">
<h1 class="lh-solid">
<div class="bg-yellow black dib tracked-tight avenir tc" style="width: 30vw; font-size: 4vw">What is</div>
<div class="" style="font-size: 12vw">Time?</div>
</h1>
</div>
</div>
<div class="pa6-l pa3 intro">
<div class="w-60-l">
<h2 id="what-is-time">What is time?</h2>
<p>What <em>is</em> time? Well, that’s a question as old as… time.</p>
</div>
<div class="flex-l items-start">
<div class="w-60-l">
<p>But yeah, basically time is like, just a social construct, mannnnnnnnnn. 🌱💨 Physicists are <a href="https://www.quantamagazine.org/a-debate-over-the-physics-of-time-20160719/">still debating on whether or not time actually exists</a> in the universe. This quickly gets us into the territory of asking ourselves really weird things that hurts our brain, like what is time, or what is physics, or if you only eat one donut from Krispy Kreme, did you even actually go there?</p>
<p>So to avoid all of this, I’m just going to say that no, time doesn’t exist, therefor writing code for it doesn’t matter, so boom, we’re done here! Thanks for reading.</p>
<p>Okay you’re not getting out of this that easy. But I think it is worthwhile to take a quick look at the history of time so we can figure out why it’s so goddamn hard to do things with timestamps.</p>
</div>
<div class="w-40-l mt4 ml4-l bg-black white f6 pa3 br1 lh-copy flex">
<div class="flex-column">
<i class="fal mr3 fa-2x">lightbulb</i>
</div>
<div class="flex-column">
<p class="ma0">This stuff gets wild to read more about, in the existential <em>what-even-is-anything-anyway?</em> category of questions in life.</p>
<p>Apparently <a href="https://www.sciencealert.com/physicists-find-as-clocks-get-more-precise-time-gets-more-fuzzy">time gets more fuzzy</a> as clocks get more and more accurate.</p>
<p>Pretty sure this confirms we're living in a simulation, and the programmers were too lazy to fully flesh the code out before they reached their ship deadline.</p>
</div>
</div>
</div>
<div class="w-60-l mt6">
<h2 id="a-brief-timeline-of-time">A brief timeline of time</h2>
<ol class="timeline">
<li>
<span class="bg-black white pa3">4000+ BC</span> Astronomical clocks
<div>We start seeing a bunch of "clocks" pop up. But like, they were shitty clocks: basically they'd be like the equivalent of looking up, seeing a sun, and like boom, I guess it's daytime.</div>
</li>
<li>
<span class="bg-black white pa3">1500 BC</span> Sundial subdivisions
<div>
<p>Oh rad, now we start getting some nifty stuff. We start seeing more sundials split up into subdivisions, so we can be more specific about how far through the day we are.</p>
<p>Egypt was the first ones to really start doing this: they had a duodecimal system already, so that's why it was split as base twelve, or our two parts of twelve hours in a day.</p>
<p>If you're like me and immediately said <em>ohhhhhhhhhhhh, so THAT'S why there's twelve hours in a day!</em> and immediately followed it up with: <em>wait, why the fuck are they using twelve instead of ten? Base ten is lit and doing everything in twelve feels so uncivilized</em>, well good use of "lit" there.</p>
<p>It's most likely because <a href="https://www.scientificamerican.com/article/experts-time-division-days-hours-minutes/">you have twelve joints in your hands</a>: three in each of the four fingers, excluding the thumb. I thought that was pretty nifty to discover. Like, I had never looked at my hands before, really. Hands are really wild, when you think about it. 🌱💨</p>
</div>
</li>
<li>
<span class="bg-black white pa3">14th century</span> Fixed-length hours
<div>
<p>European clocks started standardizing on fixed-length hours; before, a lot of clocks would change the duration of an hour depending on the season.</p>
<p>Basically anything with time that seems weird like this can probably be summed up with "the goddamn farmers did it", since, you know, growing seasons were really important to figure out when you couldn't just walk down the block and go to a Taco Bell Cantina® for a Baja Blast™.</p>
</div>
</li>
<li>
<span class="bg-black white pa3">16th century</span> Minutes
<div>
<p>Wasn't until around the 16th century before we started seeing minutes. Before then, nobody really cared, and mechanical clocks weren't good enough to count 'em accurately, anyway.</p>
<p>Probably around this time your first boss's ancestors were also discovering minutes as a good way to make sure your ancestors got to work on time: "You're exactly 56 minutes late today, Holman, what the fuck is wrong with you? Go shave the sheep!"</p>
</div>
</li>
<li>
<span class="bg-black white pa3">17th century</span> Seconds
<div>
<p>Did you hear about the clock maker who was the first to add a second hand to a clock?</p>
<p>His first prototype was a complete failure, but he got it working the second time.</p>
</div>
</li>
<li>
<span class="bg-black white pa3">1883</span> USA standardizes time
<div>
<p>We start seeing some actual standardization on time itself.</p>
<p>In what is the most bourgeoisie example of the most bourgeoisie era, a bunch of rich, white railroad tycoons met at a fancy Chicago hotel to agree on a standard timezone so their trains would work better together. They used the new-fangled telegraph to synchronize time signals between cities.</p>
<p>Other countries would do the same thing around this era. Previously, it was basically a free for all as to what time it would be in any given city:</p>
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">Lamenting over timezone programming led me to this 1857 chart, and suddenly timezones seem GREAT. (At noon in DC, it was 12:08 in Philly!) <a href="https://t.co/mSYyUKL6lX">pic.twitter.com/mSYyUKL6lX</a></p>— Tess Rinearson (@_tessr) <a href="https://twitter.com/_tessr/status/900870734238449664?ref_src=twsrc%5Etfw">August 25, 2017</a></blockquote> <script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>So, consider yourself playing in easy mode today. You can't <em>imagine</em> how much harder it would be to be a JavaScript programmer in 1882.</p>
</div>
</li>
<li>
<span class="bg-black white pa3">1967</span> Atomic standard
<div>
<p>The world started standardizing on what time measurements actually <em>are</em>.</p>
<p>If you have a pile of Cesium atoms sitting in your backyard, go out sometime and measure <a href="https://www.nist.gov/pml/walk-through-time-atomic-age-time-standards">9,192,631,770 energy transitions of a single atom of Cesium</a>: because that is exactly the duration of a second, settled upon in 1967 by a bunch of scientists.</p>
<p>Nowadays, our atomic clocks are accurate to losing a single second over the course of a few hundred million years. This is something like only losing two nanoseconds of accuracy a month, which definitely accounts for why I'm always late to your meetings on Monday morning.</p>
<p>The clocks being worked on today, though, are even better: optical clocks "tick" about a hundred thousand times faster than atomic clocks, which can lead to way higher accuracy. Basically if you somehow started one of these bad boys right at the Big Bang about 14 billion years ago and somehow kept it going, it would have <a href="https://physicsworld.com/a/new-optical-clock-breaks-accuracy-record/">only lost a few seconds of accuracy</a>.</p>
</div>
</li>
<li>
<span class="bg-black white pa3">2018</span> You fuck up yet another timezone bug
<div>
You didn't think I'd forget about you, did you?
</div>
</li>
</ol>
</div>
</div>
<div class="intro">
<div class="white tc f3">
<span class="fal fa-spin fa-pulse mh3">clock</span>
<span class="fal fa-spin mh3">hourglass-start</span>
<span class="fal fa-spin fa-pulse mh3">watch</span>
<span class="fal fa-spin mh3">alarm-clock</span>
<span class="fal fa-spin fa-pulse mh3">stopwatch</span>
</div>
</div>
<div class="pa6-l pa3 intro">
<div class="flex-l">
<div class="w-60-l">
<p>Everything we just covered revolves around a single question:</p>
<h2 id="what-time-is-it">What time is it?</h2>
<p>At a certain point we started asking this question. This became important to know when you could finally head home after work, for example (answer: never early enough). And for a long time that was fine, but that wasn’t <em>entirely</em> the question we were asking. There was a hidden implicit part of the question we were never asking:</p>
<p><span class="ml3"><strong>What time is it <em>here</em>?</strong></span></p>
<p>Once we started getting planes and trains and automobiles, we had movement, we had transportation, we could be in two distant places within hours. So we started asking this question:</p>
<p><span class="ml3"><strong>What time is it <em>there</em>?</strong></span></p>
<p>This question ruined everything.</p>
<p>Now we had to deal not just with one time (here), not two times (here and there), but a multitude of times, all interacting with each other (everywhere). This complicated everything, and made obvious the notion that writing timezone code was some of the worst things you have to do in our field.</p>
<p>It’s so predictable that developers will pooh-pooh having to write timezone code, almost as much as it is predictable that some clueless commenter on Hacker News will complain that this page has autoplaying video on it. And then someone will calmly quote this passage in response, quietly pleased with themselves that the initial commenter was rude and certainly didn’t read the post at all. Then a third person will chime in on the thread saying the author was playing you all like a fiddle anyway, and the real problem is that the post was way too long to start with.</p>
</div>
<div class="pa5 mv4 w-40-l">
<a href="https://en.wikipedia.org/wiki/File:Universal_Dial_Plate_or_Times_of_all_Nations,_1854.jpg" class="no-slide"><img src="https://upload.wikimedia.org/wikipedia/commons/thumb/d/d8/Universal_Dial_Plate_or_Times_of_all_Nations%2C_1854.jpg/757px-Universal_Dial_Plate_or_Times_of_all_Nations%2C_1854.jpg" /></a>
<em class="f6">This is terrifying. It's a <a href="https://en.wikipedia.org/wiki/File:Universal_Dial_Plate_or_Times_of_all_Nations,_1854.jpg">"Universal Dial Plate"</a>, showing times of individual cities of the world, from 1854. Gulp.</em>
</div>
</div>
<div class="mt5 w-60-l">
<h2 id="timezones">Timezones</h2>
<p>So you’re starting out fresh, building a completely new global time structure.</p>
<p>Clearly, since you’re a programmer, you already have an innate distrust of timezones, so you’re going to get rid of them entirely, a la <a href="https://en.wikipedia.org/wiki/Swatch_Internet_Time">Swatch Internet Time</a>, which demonstrates why you are the beautiful human you are, you dashing human you.</p>
<p>In fact, the title of this post is wrong: UTC isn’t enough for everyone; you should get rid of UTC and move all your servers to use Swatch Internet Time instead.</p>
<p>Okay, now that we got that tomfoolery out of the way, we start asking questions about what time should look like. And if we do have timezones, the obvious thing to you is to split the world up into twenty four timezones, one for each hour in the day, so it’s all very neat and orderly.</p>
<p>Spoiler alert! Nothing is neat and orderly when it comes to time. There’s something like 39 timezones at time of writing.</p>
<p>This, like all of the problems with time, is political. Timezones get added gradually, over time, depending on political whims, geographical reality, and economic plausibility (more on a lot of these later). So, as a common theme you’ll see, this is just one example where we try to graft an irregular system (time and timezones) over a regular system (the duration from time point A to time point B).</p>
<p>This stuff moves a lot, too: the <a href="https://en.wikipedia.org/wiki/Tz_database">tz database</a> (also known as the Olson database), which is the listing of timezone rules we use as programmers to calm this chaos, gets updated many times a year.</p>
<p>It’s also worthwhile to point out here that timezones aren’t tied to hours: many timezone offsets happen at 30 minutes, 45 minutes, and so on. So we need to stop thinking purely about “hours” and start thinking about offsets, in a way.</p>
<p>Timezones are weird. Time is weird.</p>
</div>
</div>
<div class="video">
<video class="z-1" src="/video/utc-two.mp4" poster="/images/talks/utc/poster-two.jpg" width="100%" preload="" autoplay="" loop="" muted="" playsinline=""></video>
<div class="absolute top-0 white z-2 w-100 mt2 o-80">
<h1 class="lh-solid">
<div class="white dib tracked-tight avenir" style="margin-left: 30%; font-size: 4vw">Why</div>
<div class="georgia i" style="font-size: 12vw; margin-left: 30%">Time</div>
<div class="dib bg-blue black dib f1 tracked tc ph4" style="font-size: 5vw; margin-left: 35%">is so hard</div>
</h1>
</div>
</div>
<div class="pa6-l pa3 bg-blue blue">
<div class="w-60-l">
<h2 id="who-needs-december-30-2011-anyway">Who needs December 30, 2011 anyway</h2>
<p>Let me tell you a quick story.</p>
<p>Do you remember what you were doing on December 30, 2011? You have three seconds. Go.</p>
<p>Nope? Nothing? Well then, if you don’t know what you were doing December 30, 2011, then there’s one obvious explanation for this: <strong>you must be Samoan</strong>.</p>
<p>You see, Samoa didn’t have December 30, 2011. They went straight from December 29 to December 31, do not pass Go, do not collect $200.</p>
<div class="shadow-1 mv4">
<video class="db" src="/video/utc-samoa.mp4" poster="/images/talks/utc/poster-samoa.jpg" width="100%" preload="" autoplay="" loop="" muted="" playsinline=""></video>
</div>
<p>Samoa used to be east of the International Date Line. I mean, it still is (they didn’t physically move the country, which would be a pretty impressive feat, now that I think of it), but it used to actually follow the date line accordingly. In the years before 2011, Samoa looked up and realized that hey, most of our major trading partners — China, Australia, New Zealand, and the like — are on the <em>other</em> side of the date line, so when we’re dutifully working away at the office on Friday, the rest of the people we actually do business with have already fucked off for the weekend. The Kiwis are probably off grilling meat somewhere, never to be heard from until Monday, if we’re <em>lucky</em> to hear from them ever again at all.</p>
<p>So Samoa decided to change timezones so that they could line up better economically.</p>
<p>It’s also important to note that Samoa is about 100km away from American Samoa. Not super far at all.</p>
<p><img src="/images/talks/utc/samoa-american-samoa.png" alt="Samoa and American Samoa map" /></p>
<p>So at this point in my talk I say the next part <em>real fast</em>, so like, just read it real fast and we’ll try to approximate me. It’s best if you do a pile of cocaine before reading the next part. I’ll wait.</p>
<p>Okay, so:</p>
<div class="f5 ph4">
<p>At the start, Samoa and American Samoa were in the same timezone, the <em>Samoa Time Zone</em>, which encompasses the two different countries, except it’s actually one country and one unincorporated territory of the United States (American Samoa), so when Samoa pulled out of this time zone it switched to the <em>West Samoa Time Zone</em> which was UTC +12:00 compared to <em>Samoa Time Zone</em> which stayed at UTC -11:00 which meant West Samoa Time Zone was 24 hours ahead of Samoa Time Zone which isn’t entirely accurate because sometimes it would be 25 hours ahead of Samoa Time Zone because Samoa Time Zone doesn’t observe Daylight Saving Time and, of course, West Samoa Time Zone also doesn’t observe Daylight Saving Time except it <em>does</em> observe it starting in 2009, wait that’s not true they had to push that back to 2010 because of the Samoa Earthquake and Tsunami which messed everything up; now naturally all of this may sound familiar to you because this is the mirror reverse of what happened on July 4, 1892 when the <em>opposite</em> happened when they looked around and said hey our major trading partner is the United States, why are we in a totally different day than these Yanks, so let’s do July 4, 1892 twice (which is doubly awesome and hella <em>🇺🇸 🎆 P A T R I O T I C 🎇 🗽</em>, since it’s Independence Day in the USA); it’s also important to note that Tokelau, a nearby territory of New Zealand, saw all this happening so they got in on the action and did the same thing and moved to West Samoa Time also on December 30, 2011.</p>
</div>
<p>When all of this happened, <a href="http://www.bbc.co.uk/news/mobile/world-asia-16351377">the BBC sent a journalist to Samoa</a> to see how they were taking it:</p>
<blockquote>
<p>You can hear the sound of a lot of vehicles going round town, going round the town centre clock and tooting their horns. People screaming.</p>
<p>“We have once again achieved another milestone in our history of Samoa.”</p>
</blockquote>
<p>I don’t know who they interviewed for this piece, but what I do know is whoever said this thing never had to fucking deal with fucking timezone exceptions in code before. Fuck.</p>
<p>Working with time is hard. There can be little edge cases like this every step of the way.</p>
<blockquote>
<p><strong>UPDATE: September 23, 2021</strong></p>
<p>Here it is, three years later since I originally wrote this, and the journey is still ever-changing. Samoa <a href="https://www.timeanddate.com/news/time/samoa-removes-dst.html">just announced</a> that they’re getting rid of Daylight Saving Time. They were supposed to switch over in three days, but now… they’re just… not.</p>
<p>Time is great!</p>
</blockquote>
</div>
</div>
<div class="bg-blue">
<div class="white tc f3">
<span class="fal fa-spin fa-pulse mh3">clock</span>
<span class="fal fa-spin mh3">hourglass-start</span>
<span class="fal fa-spin fa-pulse mh3">watch</span>
<span class="fal fa-spin mh3">alarm-clock</span>
<span class="fal fa-spin fa-pulse mh3">stopwatch</span>
</div>
</div>
<div class="pa6-l pa3 bg-blue blue">
<div class="w-60-l">
<h2 id="no-russian">No Russian</h2>
<p>The Russian Olympic shooting team, pleased to represent their country on <em>The Big Stage</em>, was proud to head to London for the Games in 1908. They hit the road… <a href="https://www.reddit.com/r/todayilearned/comments/6ltsnz/til_in_1908_the_russian_olympic_team_arrived_at/?st=J4UA4D2H&sh=fe9e2e7a">and made it to London twelve days too late</a> and missed their event.</p>
<p>Turns out, in 1918, Russia switched to the Gregorian calendar. This was neat, because that moved yet another country to using Gregorian, so we could all be on the same page.</p>
<p>In 1908, though, they were still on the Julian calendar. England, the host of the Olympics, was on the Gregorian calendar. So when they told them to show up at a certain date, the two calendars didn’t match up. Whoops.</p>
<p>This mix-up was a bummer, but possibly not too unfamiliar for Russia, as the same thing happened in 1805 during the <a href="https://en.wikipedia.org/wiki/Battle_of_Austerlitz">Battle of Austerlitz</a>. Napoleon was doing his thing and invading Austria, and the Austrians, assured that Russian reinforcements would show up, you know, in time, was sad to also discover the woes of different calendars as reinforcements showed up twelve days too late. Napoleon ended up winning.</p>
</div>
</div>
<div class="bg-blue">
<div class="white tc f3">
<span class="fal fa-spin fa-pulse mh3">clock</span>
<span class="fal fa-spin mh3">hourglass-start</span>
<span class="fal fa-spin fa-pulse mh3">watch</span>
<span class="fal fa-spin mh3">alarm-clock</span>
<span class="fal fa-spin fa-pulse mh3">stopwatch</span>
</div>
</div>
<div class="pa6-l pa3 bg-blue blue">
<div class="w-60-l">
<p>Other interesting factoids that I could expand upon, you know, if only I had the <em>time</em>:</p>
<ul>
<li><a href="https://www.timeanddate.com/date/february-30.html">February 30 happened at least twice</a> in history.</li>
<li><a href="https://www.reddit.com/r/askscience/comments/6c3t0s/if_each_day_is_only_23h56m4s_over_the_course_of_4/">An Earth “day” is different</a> from the time that it takes for the Earth to rotate on its axis once. This is because the Earth is <em>also</em> rotating around the sun at the same time, so that measurement is actually something like 361° of rotation instead of the normal 360°.</li>
<li>You ever forget if “12am” means noon or midnight? I always felt stupid having to think about this every time, but I feel less bad after reading this <a href="https://ell.stackexchange.com/a/152729">excellent Stack Exchange answer</a> that details the entire history of this. My favorite part: the United States government decreed that “12am” meant “noon”… up until 2008, when the United States Government Printing Office reversed their position and swapped to using “12pm” as “noon”.</li>
</ul>
<p>Time is hard, and you’re not the only one screwing all this stuff up.</p>
</div>
</div>
<div class="video">
<video class="z-1" src="/video/utc-three.mp4" poster="/images/talks/utc/poster-three.jpg" width="100%" preload="" autoplay="" loop="" muted="" playsinline=""></video>
<div class="absolute top-0 white z-2 w-50 mt2 ml5 o-80">
<h1 class="lh-solid flex items-center">
<div class="bg-green black dib tracked-tight avenir" style="padding: 0 2vw; margin-top: -10vw; font-size: 6vw">Code</div>
<div class="dib white" style="font-size: 30vw">&</div>
<div class="bg-green white i dib tracked-tight avenir" style="padding: 0 2vw; margin-top: 10vw; font-size: 6vw">Time</div>
</h1>
</div>
</div>
<div class="pa6-l pa3 bg-green green">
<div class="flex-l items-start">
<div class="w-60-l">
<p>While I was initially building this talk, I found myself listening to the words of my absolute favorite modern-day philosopher: Nas.</p>
<blockquote>
<p>You got CD-ROM, everythang operates by computers</p>
<p>Then what happens when circuit breaks?</p>
<p>Y2K’s the big scare</p>
<p>Scientists say we ain’t prepared</p>
<div class="mt4 tr i fw5">- Nas, "New World", 1999</div>
</blockquote>
<p>I’m not really sure what to take from all this, other than if Nas is really concerned about computer science and how it relates to time, then dammit, we should be concerned, too.</p>
</div>
<div class="w-40-l ml4-l">
<img src="/images/talks/utc/nas.png" class="shadow-0" alt="Nasty Nas" />
</div>
</div>
</div>
<div class="pa6-l pa3 pt3-l bg-green green">
<div class="w-60-l">
<h2 id="storing-time">Storing Time</h2>
<p>The very first thing you need to start worrying about when you build smart, time-aware software is how you store time. For many, databases will be the tool they’ll reach for. And there’s a lot of things to consider when it comes to <em>how</em> you store that data in a database.</p>
<p>Step one: <strong>use UTC</strong>. Okay I’m not going to suddenly say all this advice we’ve been giving for years and years is wrong. UTC is a fine standard to base all your times off of. So use it. Don’t do something silly and <a href="https://twitter.com/awscloud/status/997174917908004864?lang=en">change your servers’ timezones from UTC</a>.</p>
<p>Now, I’ve been burying the lede here for quite some time. It’s worthwhile to talk quickly about UTC, and why it’s a good default when we tell developers “Just use UTC”.</p>
<p>UTC, of course, stands for:</p>
<div class="courier">
<blockquote>
<p> <strong>U</strong>niversal<br />
Coordina<strong>T</strong>ed…?<br />
<del> <strong>C</strong> </del> um… lemme figure this out…
<b>T</b>ime?<br /></p>
</blockquote>
</div>
<p>Time standards bodies got us making scratch pads like some Zodiac Killer letter. Didn’t even know Ted Cruz cared about timezone issues.</p>
<p>But yeah, this <code class="language-plaintext highlighter-rouge">UTC</code> initialism doesn’t make any sense. Let’s dig into this a little more.</p>
<p>So you’ve got a bunch of scientist types around 1960 who are like, hey, time is all screwy we should totes make a standard. And some of them spoke English, and some of them spoke French, which, of course, is the cause of so much conflict over so many generations. (In hindsight, maybe we should have split all those troublemakers up from the start.)</p>
<p>The English-speaking folk were like yo, this definitely sounds like <strong>Coordinated Universal Time</strong>, boom, ship it. And the French speakers were like yeah that makes total sense! <strong>Temps Universel Coordonné</strong> DOES work out well in our language, too, ship it! Then they both looked up and realized cool, they’ve created both <strong>CUT</strong> and <strong>TUC</strong> for acronyms. Shit.</p>
<p>When your standard — that is expressly meant to <em>standardize</em> time — doesn’t even standardize on a standard <em>acronym</em>, well, damn, that probably doesn’t bode well for your standard.</p>
<p>Or, actually, now that I think about it, this might be the most perfect metaphor about time itself ever created. Maybe we should give them some credit for that. Time never makes sense.</p>
<p>Anyway, the compromise that arose was that if everyone is special, <em>no one is special</em>, so they created an entirely new set of letters that has no direct relation to any real words for the compromise: <strong>UTC</strong>.</p>
<p>Whew.</p>
<p>So. We use UTC because it has an <em>offset</em> of 00:00: in other words, it has no timezone offset. Other timezones are offset from <em>UTC</em>, not the other way around.</p>
<p>It’s important to note that UTC is <em>not</em> GMT. GMT is Greenwich Mean Time, which historically was the center of time in the world. They both have an offset of 00:00. But you shouldn’t use GMT on your server, for example, because UTC is a <em>standard</em>, but GMT is a <em>timezone</em>. People actually live in locations whose time is GMT; UTC isn’t directly used by people (unless they’re really weird).</p>
</div>
<div class="flex-l items-start">
<div class="w-60-l">
<p>This may sound like such a small difference of wankery, but the more relevant part is that <em>some</em> users of GMT observe Daylight Saving Time (but not all). UTC has no concept of Daylight Saving Time at all. So if you base everything in GMT, well, who knowssss what will happen.</p>
</div>
<div class="w-40-l mt4 ml4-l bg-dark-green f6 pa3 br1 lh-copy flex">
<div class="flex-column">
<i class="fal mr3 fa-2x">lightbulb</i>
</div>
<div class="flex-column">
<span class="fw5">Quick side note</span>: it's Daylight <em>Saving</em> Time, not Daylight <em>Savings</em> Time. You don't want to sound like a total tool in front of all six of us who care about this stuff.
</div>
</div>
</div>
<div class="w-60-l">
<p>One question you might want to ask right from the start is: <strong>do you really <em>need</em> to store time?</strong></p>
<p>As programmers, we’re kind of inherently built to want the ABSOLUTE BEST HIGHEST FIDELITY FORMATS OF ALL TIME. Like dammit, I <em>need</em> the timestamp down to the micromillinanosecond for every cheeseburger that gets added to my bespoke <em>Watch-The-BK-Throne</em> app. If I do not have this exact knowledge to the millisecond of when I consumed this BBQ Bacon WHOPPER® Sandwich From Burger King® I may die.</p>
<p>But we sometimes don’t need all this data, and that’s cool, so be sure to ask yourself if you really need this data, or you just want this data. The rule of the game for programming with time is that you should opt to go as simple as possible as soon as possible. A good example of this are birthdays. Birthdays are kind of like floating events; it doesn’t really matter where you are on the planet; if the numerical day matches up with what’s on your driver’s license we’re set. Storing these things as a timestamp column instead of just a date column in your database can end up complicating your code down the line.</p>
<h3 id="properly-storing-timezone-aware-times">Properly storing timezone-aware times</h3>
<p>On the other hand, you may actually want to track time. In those cases, there’s a few ways of doing this, particularly if you know that fidelity of hour or minute is going to be important for your use case.</p>
<p>Say you have an <code class="language-plaintext highlighter-rouge">events</code> table in your database, and you toss in a column to keep track of when the event starts:</p>
<table class="bg-white mv4 center w-75 ">
<thead>
<th>Name</th>
<th>Type</th>
</thead>
<tr class="striped--near-white">
<td class="pa2">starts_at</td>
<td class="pa2">timestamp</td>
</tr>
</table>
<p>This is neat and obvious, since you want to store a time as a timestamp in whatever database you’re using. But if it’s important that you don’t end up being an hour off when something actually happened, you’d need to store the originating timezone as well:</p>
<table class="bg-white mv4 center w-75 ">
<thead>
<th>Name</th>
<th>Type</th>
</thead>
<tr class="striped--near-white">
<td class="pa2">starts_at</td>
<td class="pa2">timestamp</td>
</tr>
<tr class="striped--near-white">
<td class="pa2">starts_at_tz</td>
<td class="pa2">string</td>
</tr>
</table>
<p>By adding the offset as a string in your database, you gain some additional powers. For one, it gives you a closer idea of when <em>specifically</em> the event happened.</p>
</div>
<div class="flex-l items-start">
<div class="w-60-l">
<p>One way to do this is to treat this column as an integer; say, store <code class="language-plaintext highlighter-rouge">-240</code> in a row to represent a shift of 4 hours (4*60 minutes). That’s cool, and it does get you closer, but again, we’re talking about a use case where it actually does matter to be as accurate as possible (and being off an hour might lead to nonsensical data). Just having a numerical offset doesn’t give you fidelity of location. Was it during Daylight Saving Time? What about comparing that to today’s time; do we account for DST or not? Also, do we need to account for changes in timezones that might have happened since that point in time?</p>
<p>Instead of a numeric offset, use a string. Specifically, use the <a href="https://en.wikipedia.org/wiki/List_of_tz_database_time_zones">full qualified name</a> in the Olson database, so something like <code class="language-plaintext highlighter-rouge">Australia/Adelaide</code> or <code class="language-plaintext highlighter-rouge">America/Los_Angeles</code>. These are standardized descriptors of the timezones used in the world, and you can use these in pretty much every programming language ever used in the last few decades.</p>
<p>Again, all of this probably isn’t relevant for <em>every</em> app — who cares if someone’s browsing the article <em>Brad Pitt’s Beautifully Coiffed Hair: Friend or Foe to the Proletariat?</em> and my six comments are <em>technically</em> listed as an hour earlier than they actually were. Regardless of timing, my comments were perfectly relevant and explored the issue perfectly. But for some apps it might make sense to get this detailed, particularly if you’re comparing a lot of times to each other (like, say, a calendar).</p>
</div>
<div class="w-40-l mt4 ml4-l bg-dark-green f6 pa3 br1 lh-copy flex-ns">
<div class="flex-column">
<i class="fal mr3 fa-2x">lightbulb</i>
</div>
<div class="flex-column">
The historical side of this stuff gets kinda cool, too. One of my favorite examples is in <a href="https://tools.ietf.org/html/rfc3339#page-9">RFC 3339</a>:
<div class="mv4 f7 bl b--white bw2 pl3">
<b>1937-01-01T12:00:27.87+00:20</b><br /><br />
This represents the same instant of time as noon, January 1, 1937,
Netherlands time. Standard time in the Netherlands was exactly 19
minutes and 32.13 seconds ahead of UTC by law from 1909-05-01 through
1937-06-30. This time zone cannot be represented exactly using the
HH:MM format, and this timestamp uses the closest representable UTC
offset.
</div>
So if you really get down into the rabbit hole and find yourself needing historically-accurate times across decades, you might need to backtrack over multiple previous timezone changes in order to get to that point.
Also if you find yourself at this critical juncture, you might want to just give up programming entirely, because that sounds horrible.
</div>
</div>
</div>
<div class="mt5 flex-l items-start">
<div class="w-60-l">
<h2 id="transiting-time">Transiting Time</h2>
<p>Aight, cool, you’re storing your times correctly; now we can take a look at how we transit those times to our clients.</p>
<p>Number one rule: <strong>stay consistent</strong>.</p>
<p>The number one way to address that number one rule: <a href="https://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a>.</p>
<p>ISO 8601 is one of my favorite standards and/or RFC out there. And yes, you <em>should</em> definitely have a favorite. (My all-time fave is <a href="https://tools.ietf.org/html/rfc2606">RFC 2606</a>, thanks for asking! I’m in awe of that absolute unit. Where would we be without that banger? We’d be in complete fucking chaos, that’s where.)</p>
<p>ISO 8601 was a standard that came out in 1988, so it’s probably older than all you lot who are reading this, now get off my damn Friendster lawn. It was re-upped in 2004, 2014, and is anticipating a new draft by the end of this year. It basically defines THE way of writing a timestamp.</p>
<p>Here: I’ll even be nice and show you an example:</p>
<div class="ml4 f4 fw5">
<script type="text/javascript">
document.write(new Date().toISOString())
</script>
</div>
<p>In JavaScript land, this is simple: it just uses the <code class="language-plaintext highlighter-rouge">toISOString()</code> function:</p>
<div class="language-js highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">new</span> <span class="nb">Date</span><span class="p">().</span><span class="nx">toISOString</span><span class="p">()</span>
</code></pre></div> </div>
<p>The astute among you might see a few reasons right away why this is such a dope format:</p>
<ul>
<li><strong>Easy sorting</strong>: It arranges all components from large to small, so pretty much any novice in a programming language could easily sort a list of timestamps from latest to oldest.</li>
<li><strong>Timezone information</strong>: At the far end it includes the offset: <code class="language-plaintext highlighter-rouge">-08:00</code>, for example (well, not in this above example specifically, since in JavaScript you’d also need to parse this out manually with <code class="language-plaintext highlighter-rouge">getTimezoneOffset()</code>). This isn’t as high-fidelity as when we were talking earlier about storing the qualified string version of a timezone, but it does give us information we wouldn’t have otherwise. You don’t get this if you pass around <a href="https://en.wikipedia.org/wiki/Unix_time">UNIX epoch time</a>, for example.</li>
<li><strong>No locale problems</strong>: You don’t have problems with Month/Day/Year formats getting confused with Day/Month/Year formatted dates. More on this in a few.</li>
</ul>
<p>So yeah, use ISO 8601 over the wire. It’s the most popular way of tackling a shared standard for time, so don’t be the jerk who does it in some fancypants custom manner.</p>
<h3 id="rfc-3339">RFC 3339</h3>
<p>Wanted to mention <a href="https://tools.ietf.org/html/rfc3339">RFC 3339</a> briefly as well, since sometimes you’ll see its mean mug pop up in APIs and other spots from time to time.</p>
<p>RFC 3339 came out in 2002. This is a simplification, but it’s kind of a subset of ISO 8601. It requires timestamps — ISO 8601 allows you to omit them and just use it for a date — and in general it’s slightly more strict. It lets you get away with less.</p>
<p>Effectively they’re sort of interchangeable. Most people and API platforms just say they comply with ISO 8601, so that’s probably going to be fine for you, too.</p>
</div>
<div class="w-40-l mt4 ml4-l f6 pa3 br1 lh-copy flex">
<a href="https://xkcd.com/1179/" class="no-slide"><img alt="xkcd on ISO 8601" title="ISO 8601 was published on 06/05/88 and most recently amended on 12/01/04.
See, that's the actual xkcd alt text for this; you didn't think I'd manually add it in this embed, did you. Well you're in luck: I did. Just for you, the xkcd obsessive. <3" src="https://imgs.xkcd.com/comics/iso_8601.png" /></a>
</div>
</div>
<div class="mt5 w-60-l">
<h2 id="displaying-time">Displaying Time</h2>
<blockquote class="twitter-tweet" data-lang="en"><p lang="en" dir="ltr">British press corp is locked outside the White House because our birthdates were submitted in UK format and secret service don't get it. 🇬🇧</p>— Jim Waterson (@jimwaterson) <a href="https://twitter.com/jimwaterson/status/825017459530936320?ref_src=twsrc%5Etfw">January 27, 2017</a></blockquote>
<script async="" src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
<p>You’ve got some time, you’ve sent it to the client or to the user… now you have to display it, with hopefully minimal amount of confusion with the United States Secret Service.</p>
<p>I don’t know if you’ve noticed this yet, but Americans aren’t perfect. We use this fucked up date format, MM/DD/YYYY. Like under no circumstances does this make any sense. But if you switch that around and try to show someone from the US a date like 24/6/18… well that’s just going to be weird. People like their locale-based date formatting, and you should try to respect that as much as you can.</p>
<p>One of the ways you can do this on the web is using the <a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl"><code class="language-plaintext highlighter-rouge">Intl</code> API</a>. <code class="language-plaintext highlighter-rouge">Intl</code> supports a number of different hooks and abilities to handle locale- and language-based changes for numbers, plurals, and dates and times.</p>
<p>Beyond that, if you’re going to be doing anything fancier with dates and times beyond, say, just printing something to the page, you should really start using a proper time library. Things like adding two dates together while still tracking DST and a multitude of other time rules… well, it’s all really difficult to do yourself. Stand on the shoulders of giants, and steal from someone else. Just how Open Source was intended.</p>
<p>Some solid libraries to take a gander at:</p>
<ul>
<li><a href="https://momentjs.com">moment.js</a> The classic time library in JavaScript. Date manipulation, formatting, pretty much everything you’d need.</li>
<li><a href="https://date-fns.org">date-fns</a> More modern approach to a moment.js-like experience for handling dates on the web.</li>
<li><a href="https://github.com/github/time-elements">github/time-elements</a> Web component extension to the <code class="language-plaintext highlighter-rouge"><time></code> element. Also includes auto-updating timestamps, as well as some locale help.</li>
</ul>
</div>
<div class="w-60-l mt5">
<h2 id="accessibility">Accessibility</h2>
<p>There’s something that tends to be left out of discussions about time (or discussions about any technology, really): accessibility. There’s a few things here that you can do for your human users and computer users that’ll help everyone out.</p>
<p>In a lot of hip social apps, you’ll have something like this:</p>
<p><img src="/images/talks/utc/social-mockup.png" alt="Mockup of social app" /></p>
<p>And on the bottom footer of that component you’ll frequently see a relative datestamp:</p>
<p><img src="/images/talks/utc/relative-datestamp.png" alt="Relative datestamp" /></p>
<p>That’s all well and good, but there’s a few problems with this. For one, this doesn’t automatically update on-page, so if you open the page in a tab an hour ago, it’ll still show something as happening a couple minutes ago. Step one might be to have a lightweight timer on your page that auto-updates all relative date/times and updates them every minute. Keeps everything fresh.</p>
<p>Secondly, as time moves on you’ll start seeing a lot of stuff like this:</p>
<p><img src="/images/talks/utc/relative-year.png" alt="Relative year" /></p>
<p>I always hate stuff like this, because I’m always like, well, when the fuck did this actually happen? Like does this mean five months ago and they’re rounding up to a year? Or does it mean 23 months ago, which is wayyyy different from five months ago? WHAT DOES “ABOUT” MEANNNNN?</p>
<p>A few things you can use here. One of the things I always liked about GitHub is that they’ve always shown a full timestamp in the <code class="language-plaintext highlighter-rouge">title</code> of any relative time on-page. I think we started adding that way back in 2010 or so, something like that. Always made it really easy to find out when specifically some event happened: you just mouseover the element.</p>
</div>
<div class="w-80-l mv4">
<video class="shadow-2" src="/video/utc-github-relative-titles.mp4" poster="/images/talks/utc/poster-github-relative.jpg" width="100%" preload="" autoplay="" loop="" muted="" playsinline=""></video>
</div>
<div class="w-60-l">
<p>You can achieve this by just dropping this data into a <code class="language-plaintext highlighter-rouge"><span></code>, but the best practice nowadays is to use the <code class="language-plaintext highlighter-rouge"><time></code> element. So you print things relatively like usual:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><time></span>six minutes ago<span class="nt"></time></span>
</code></pre></div> </div>
<p>Then you add a human-friendly string to the <code class="language-plaintext highlighter-rouge">title</code> attribute:</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><time</span> <span class="na">title=</span><span class="s">"May 28, 2018, 3:47 PM PST"</span><span class="nt">></span>six minutes ago<span class="nt"></time></span>
</code></pre></div> </div>
<p>The last bit is that the <code class="language-plaintext highlighter-rouge"><time></code> element also allows for a <code class="language-plaintext highlighter-rouge">datetime</code> attribute. This is a way to get past all your fancy relative formatting, or human formatting, and let clients parse out the <em>actual</em> timestamp correctly. If you’re wondering how you format this particular string, you haven’t been reading at all (and you’re going to miss all my good time puns, you heartless fiend, so go read it a <em>second</em> time).</p>
<p>But yes: it’s our pal the friendly ISO 8601-formatted string. It’s everywhere!</p>
<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt"><time</span> <span class="na">title=</span><span class="s">"May 28, 2018, 3:47 PM PST"</span> <span class="na">datetime=</span><span class="s">"2018-05-28T15:47:57-08:00"</span><span class="nt">></span>six minutes ago<span class="nt"></time></span>
</code></pre></div> </div>
<p>If you ever print out a relative date or time to a page, you should follow this format everywhere. Extract it into a component or utility function or however it is your weirdo team does it, and you’ll make the most amount of people happy.</p>
</div>
<div class="w-60-l mt5">
<h2 id="inputting-time">Inputting time</h2>
<p>I don’t know if you’ve tried date pickers and time pickers over the years, but they’re awful.</p>
<p><img src="/images/talks/utc/pickers.png" alt="Date pickers" /></p>
<p>Maybe it’s just me, but I still haven’t found the perfect time and date picker yet. Either there’s accessibility problems, or design problems, or dependency and size problems, or something else entirely. This probably why there are so many of them: everyone says the same thing and tries to reinvent the wheel, thus perpetuating the cycle. I’m sure During will feel the need to create and open source our own at some point, too.</p>
<p>Part of this stems from there not being a real, viable browser option. At a certain point browser makers realized this was a problem and got to work on adding <code class="language-plaintext highlighter-rouge">type=date</code> and <code class="language-plaintext highlighter-rouge">type=time</code> to the verable <code class="language-plaintext highlighter-rouge"><input></code> element. And that sort of worked.</p>
<p>Here’s <code class="language-plaintext highlighter-rouge"><input type="date" /></code> in Chrome:</p>
<video class="shadow-2 mv3" src="/video/utc-type=date.mp4" poster="/images/talks/utc/poster-type=date.jpg" width="100%" preload="" autoplay="" loop="" muted="" playsinline=""></video>
<p>It… you know, works. Ugly as sin, though, and that’s the first problem: there aren’t enough hooks into the element to comprehensively style it as you’d like.</p>
<p>Here’s <code class="language-plaintext highlighter-rouge"><input type="time" /></code> in Chrome:</p>
<video class="shadow-2 mv3" src="/video/utc-type=time.mp4" poster="/images/talks/utc/poster-type=time.jpg" width="100%" preload="" autoplay="" loop="" muted="" playsinline=""></video>
<p>Also, here’s <code class="language-plaintext highlighter-rouge"><input type="date" /></code> in Safari:</p>
<video class="shadow-2 mv3" src="/video/utc-type=safari.mp4" poster="/images/talks/utc/poster-type=safari.jpg" width="100%" preload="" autoplay="" loop="" muted="" playsinline=""></video>
<p>Safari, continuously behind on virtually every interesting standard on the planet these days, doesn’t support it at all. So yeah, everything is terrible.</p>
<p>I asked someone far more knowledgeable than me on <code class="language-plaintext highlighter-rouge"><input></code> about when we can finally start using a cross-platform, extensible, great option for date pickers. Her answer was an immediate <strong><em>oh god probably never</em></strong>. Neat! The web is great!</p>
<p>So yeah, at the end of the day I’ve taken peace with trying to find the best crappy option, restyling it so it doesn’t look terrible, and then ignoring it and throwing my laptop into a lava flow. Just make peace with it.</p>
</div>
<div class="mt5 w-60-l">
<h2 id="recurring-events">Recurring events</h2>
<p>If someone held a gun to your head and demanded in the next week you either 1) programmed a comprehensive system that included full support for recurring events, or 2) invent full-scale ready-to-go-to-market cold fusion, then you should abolutely start brushing up on atomic physics. Recurring events is a true shit show.</p>
<p>It starts normally enough, of course. You have an innocent phrase that you want to apply to your system, like:</p>
<div class="ml5 fw5 f4">"Every Tuesday at 2pm"</div>
<p>Awesome. So you start modeling it in your database. You say, hey, I’ll just create an event with a <code class="language-plaintext highlighter-rouge">starts_at</code> value of next Tuesday. And then you save another row for the Tuesday after that. And then another row for the Tuesday after that. And after that. And after that. You do this for 70 occurrences before you start realizing, hey, I think this goes to infinity. (Don’t ask me why it took you that long to figure this out; you’re the one who’s a little slow on the update. I figured it out by the 52nd occurrence.)</p>
<p>Being that even AWS doesn’t have a hard drive with literal infinite space (yet), you realize you need to figure out another way to deal with this. Maybe you can just create a shorthand of rules that defines when things happen.</p>
<p>Martin Fowler has a <a href="https://martinfowler.com/apsupp/recurring.pdf">really great whitepaper</a> on recurring events. It’s short, and walks you through figuring all this out in code-agnostic, plain English. (Definitely check it out if you get really excited about reading whitepapers. Also get yourself checked out if that’s actually the case.)</p>
<p>Fowler called these shorthands <em>temporal expressions</em>. It’s a way of defining the problem space so your system can do something with it. And luckily, we have a standardized way of thinking about this, too, in <a href="https://tools.ietf.org/html/rfc5545">RFC 5545</a>. These are called <code class="language-plaintext highlighter-rouge">RRULEs</code>, or <strong>recurrence rules</strong>. So “Every Tuesday” might look like this:</p>
<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>FREQ=WEEKLY;BYDAY=TU;INTERVAL=1
</code></pre></div> </div>
<p>By using something like this, you basically can get away with pre-generating only <em>one</em> event/instance/recurrence, and then in your client, or in-memory, or through some other approach, you generate these occurrences on-demand as you go.</p>
<p>This might seem simple enough. And for very simple cases, yeah, it might not be too bad. But it’s all just a race against <em>time</em>. Because:</p>
<ul>
<li>What about Daylight Saving Time? If this is a time accessed by multiple users, whose particular brand of DST wins out? What happens if you observe DST but I don’t?</li>
<li>What about exceptions? Maybe one of the Tuesdays is a holiday, so you don’t want to have an occurrence on that day.</li>
<li>What about exceptions that are subsequently moved? Say Tuesday is a holiday, so we move it to Wednesday. Oops, no now we’ve moved it to Thursday. How do we efficiently model all that without going nuts?</li>
</ul>
<p>The erm… rules… in <code class="language-plaintext highlighter-rouge">RRULE</code> all handle this. There are rules like <code class="language-plaintext highlighter-rouge">EXDATE</code>, <code class="language-plaintext highlighter-rouge">EXRULE</code>, <code class="language-plaintext highlighter-rouge">UNTIL</code>, <code class="language-plaintext highlighter-rouge">DTEND</code>, <code class="language-plaintext highlighter-rouge">COUNT</code>, and many more. It’s an attempt to help model all of these extra problems you might run into… but at the expense of really cluttering up your domain logic.</p>
<p>My advice for all of this is to go as simple and as inefficient as you can, at least initially. I guess that’s the opposite of what our usual goals are in software, but I think it’s good advice for time code. The more complex your time logic is, the more it picks up steam, like a snowball rolling down a cliff. Every little bit adds up and compounds.</p>
<p>So try going simple at first, if you can. Instead of modeling a <code class="language-plaintext highlighter-rouge">RRULE</code> for a weekly reoccurrence, maybe you can just pre-generate all of the events ahead of time, but just for a year. Then on January 1, regenerate a new set of events in your database. This makes it 1) easy to reason about, 2) easy to query (it’s just a normal SQL query), and 3) gives you the benefit of having real database records backing each of your events (once you generate “virtual” events through <code class="language-plaintext highlighter-rouge">RRULEs</code>, it makes things like associations that much harder, since you don’t have a database ID to associate with).</p>
</div>
</div>
<section class="mt6">
<div class="center lh-copy dark-blue f3 white w-60-l pa3">
<p class="ma0 f2"><span class="pink">Programming time</span> is pretty weird.</p>
<p class="mv5">It can sometimes make you feel week in the knees, and very days and confused about how it all fits together. But watch it: this is hour burden to bear, and we can't just let it past us over.</p>
<p class="mv5">
We've been working on building <a href="http://during.com">During</a> for awhile now, and most of the time I've been tryna keep my sanity, but every now and then I take a step back and say wait a minute, how does any of this work? How does society work? Do users actually need all-day, floating, recurring events with exceptions spread over multiple Daylight Saving Time boundaries? Or should I just go tell users to eat one and go live a simpler life in the woods?
</p>
<p class="mv5">Anyway, what I mean is that I've been in time-headspace for awhile now. Here's a few last thoughts:</p>
<p class="mv5"><span class="pink">Keep everything simple</span> as much as possible. Even if it means being really inefficient, or redundant, or ugly. Everything adds up, and I think usually programmers overthink time. (Leave overthinking for the times where it's actually critical to overthink.)</p>
<p class="mv5"><span class="pink">Handle more in the client.</span> This is a little bit of an odd piece of advice, but especially when you have a central service (GraphQL, REST API, some central interface, particularly when hooked up with a single page app, mobile clients, or other clients), I think it's more important to have as simple a central service as possible. This means it should basically only speak UTC, and might not even handle a lot of the more complicated logic around recurring events, timezones, and so on. It adds redundancy in your clients, but I think it makes it easier to understand overall.</p>
<p class="mv5"><span class="pink">Leverage standards</span> and let others do the heavy lifting. Obviously that means using the <em>Brightest Point in Human History</em>, also known as ISO 8601, but it also means using premade time libraries, resources like the Olson database, and leveraging other people's existing work as much as possible. Let someone else figure out the really gnarly edge cases so you can work on your domain's edge cases.</p>
<p>Anyway, our time is up. ⌚️👀</p>
<h2 class="mt6 db">Additional reading</h2>
<p class="mv5">And finally, now that I've suckered you into caring this much about time, you might want to keep on reading. Here's some interesting links if all this text wasn't enough for you:</p>
<ul class="list ml0 pl0 f5 links-list lh-copy">
<li><a href="http://infiniteundo.com/post/25326999628/falsehoods-programmers-believe-about-time">Falsehoods Programmers Believe About Time</a> and its sequel, <a href="http://infiniteundo.com/post/25509354022/more-falsehoods-programmers-believe-about-time">More Falsehoods Programmers Believe About Time</a>. These get into some really nitty-gritty on programming time edge cases and weird things to keep in mind as you go. Lovely stuff, and if you haven't read them yet (or even if you haven't read them recently), you should go and give 'em a read now.</li>
<li>There's a ton of amazing things to learn on the Wikipedia page for <a href="https://en.wikipedia.org/wiki/Unix_time">Unix time</a>. I started including some of these things here and there, but really you should just go through the whole thing. There's a lot of talk about Unix and how they deal and think about time. Some nice little nuggets in there, like why Unix epoch came before the standardization of UTC, and why the epoch is not exactly the number of seconds since 1970 (see: leap seconds).</li>
<li>I don't know what my favorite George Carlin bit of all time is (okay, I do: it's <a href="https://www.youtube.com/watch?v=MvgN5gCuLac"><em>Stuff</em></a>), but <a href="https://www.youtube.com/watch?v=zaR3sVpTB98">this bit on time</a> is pretty great too. He had a way with words.</li>
<li>From Hodinkee: <a href="https://www.hodinkee.com/articles/why-clocks-run-clockwise">Why do clocks run clockwise?</a> — I love stuff like this.</li>
<li><a href="https://nylas.com/blog/rrules/">The deceptively complex world of calendar events and RRULEs</a>. Great post on breaking down how to think about RRULEs from a calendaring and system perspective.</li>
<li>Wikipedia's <a href="https://en.wikipedia.org/wiki/Time_formatting_and_storage_bugs">Time formatting and storage bugs</a> is worth a look just for the sheer number of upcoming time-related bugs we know are coming. Y2K was just the start.</li>
<li>The <a href="https://en.wikipedia.org/wiki/Happy_Monday_System">Happy Monday System</a>, which honestly I just loved based on the name of it alone. Shows how Japan has moved their holidays schedules around just to make people happier with a longer weekend.</li>
<li>Time smearing links <a href="https://developers.google.com/time/">from Google</a> and <a href="https://aws.amazon.com/blogs/aws/keeping-time-with-amazon-time-sync-service/">from Amazon</a>. I didn't even get to cover time smearing, leap seconds, leap years, and all of the little ways we correct how we measure time. Leap seconds are a pretty interesting subject, particularly since they're nonstandard: the need to add another leap second can depend on if a lot of seismic activity happened recently, for example.</li>
<li>Another plug for reading <a href="https://tools.ietf.org/html/rfc3339">RFC 3339</a>. It's very clearly written, not too long, and has a lot of examples like the aforementioned 1937 Netherlands example, as well as how they suggest displaying a leap second in an RFC 3339-formatted string, and the possibility of only emitting UTC time from a server as a security precaution. ("Others might consider this to be loss of useful functionality at the hands of paranoia.")</li>
</ul>
</div>
</section>
<div class="mt6 ph3 f4 bg-pink pa4">
<div class="mv5 flex w-60-l center">
<div class="flex-column tc" style="min-width: 120px">
<img src="/images/holman.jpg" alt="Holman's avatar" class="br-100 shadow-0 b--white ba bw3" width="100" height="100" />
</div>
<div class="flex-column ml4 lh-copy">
<div class="f3"><a href="/about">Zach Holman</a></div>
<div class="mv4">I cofounded <a href="http://during.com">During</a>, a neat new calendar for people who <em>live</em> in their calendar.</div>
<div class="mv4">I swear we're going to ship it soon, too.</div>
<div class="mv4"><a href="https://twitter.com/holman">Follow me on Twitter</a> and I promise I won't waste your... <em>time</em>.</div>
<div class="mv4 f6">I also promise that was the last pun.</div>
<div class="mv4 f6">...until next time!</div>
</div>
</div>
</div>
None of My Apple Gear Connects Together, Dammit2018-02-13T00:00:00+00:002018-02-13T00:00:00+00:00http://zachholman.com/posts/apple-accessories-ecosystem-problem<p>Here I am, out at a cafe, with nearly $4000 worth of the latest Apple hardware around me, and none of four fucking devices plug directly into each other. Even when they do, I can’t help but feel worse off using Apple’s own accessories and hardware today when than I did four years ago.</p>
<p>What is going on with Apple’s accessory ecosystem these days?</p>
<h2 id="the-2016-macbook-pro">The 2016 MacBook Pro</h2>
<p>At a certain point, I had lost more screws in my old MacBook Pro than I had remaining. So when Apple dropped the long-awaited MacBook Pro updates in 2016, I figured I should probably bite the bullet:</p>
<div class="my-8">
<blockquote class="instagram-media" data-instgrm-captioned="" data-instgrm-permalink="https://www.instagram.com/p/BNXcRo8gTOT/" data-instgrm-version="8" style=" background:#FFF; border:0; border-radius:3px; box-shadow:0 0 1px 0 rgba(0,0,0,0.5),0 1px 10px 0 rgba(0,0,0,0.15); margin: 1px; max-width:658px; padding:0; width:99.375%; width:-webkit-calc(100% - 2px); width:calc(100% - 2px);"><div style="padding:8px;"> <div style=" background:#F8F8F8; line-height:0; margin-top:40px; padding:50.0% 0; text-align:center; width:100%;"> <div style=" background:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACwAAAAsCAMAAAApWqozAAAABGdBTUEAALGPC/xhBQAAAAFzUkdCAK7OHOkAAAAMUExURczMzPf399fX1+bm5mzY9AMAAADiSURBVDjLvZXbEsMgCES5/P8/t9FuRVCRmU73JWlzosgSIIZURCjo/ad+EQJJB4Hv8BFt+IDpQoCx1wjOSBFhh2XssxEIYn3ulI/6MNReE07UIWJEv8UEOWDS88LY97kqyTliJKKtuYBbruAyVh5wOHiXmpi5we58Ek028czwyuQdLKPG1Bkb4NnM+VeAnfHqn1k4+GPT6uGQcvu2h2OVuIf/gWUFyy8OWEpdyZSa3aVCqpVoVvzZZ2VTnn2wU8qzVjDDetO90GSy9mVLqtgYSy231MxrY6I2gGqjrTY0L8fxCxfCBbhWrsYYAAAAAElFTkSuQmCC); display:block; height:44px; margin:0 auto -44px; position:relative; top:-22px; width:44px;"></div></div> <p style=" margin:8px 0 0 0; padding:0 4px;"> <a href="https://www.instagram.com/p/BNXcRo8gTOT/" style=" color:#000; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px; text-decoration:none; word-wrap:break-word;">gonna be weird to have a machine which still has half its screws in and isn't in danger of falling apart. gonna miss this dork tho, we did six continents and a couple dozen countries together. also, this is a nice metaphor happenin here.</a></p> <p style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; line-height:17px; margin-bottom:0; margin-top:8px; overflow:hidden; padding:8px 0 7px; text-align:center; text-overflow:ellipsis; white-space:nowrap;">A post shared by <a href="https://www.instagram.com/holman/" style=" color:#c9c8cd; font-family:Arial,sans-serif; font-size:14px; font-style:normal; font-weight:normal; line-height:17px;"> Zach Holman</a> (@holman) on <time style=" font-family:Arial,sans-serif; font-size:14px; line-height:17px;" datetime="2016-11-28T19:53:59+00:00">Nov 28, 2016 at 11:53am PST</time></p></div></blockquote> <script async="" defer="" src="//www.instagram.com/embed.js"></script>
</div>
<p>I generally like my MacBook Pro. It could just be that my older one was falling apart, but the performance and form factor with their latest generation is pretty great, and it’s held up pretty well over the last few years, aside from a key that’s falling apart from all the the commands I must be giving it:</p>
<p><img src="/images/posts/apple-connects-cmd.jpg" /></p>
<p>A lot of ink has been spilled regarding <a href="https://www.bloomberg.com/news/articles/2018-02-12/how-apple-plans-to-root-out-bugs-revamp-iphone-software">Apple’s rumored refocus on software quality</a>, and thoughts on their hardware comes down to either “the Touch Bar is clearly dooming the entire company!”, or “AirPods are the greatest piece of engineering of all time!!!!1”. I’m more interested in talking about specifically their accessories: cables, chargers, and connectors. And all of this starts with the MacBook Pro’s choice to head to USB-C.</p>
<h2 id="usb-c">USB-C</h2>
<p>I really dig USB-C. I was fine being an early adopter where none of my shit worked and I had to carry an endless supply of dongles and adapters for awhile, because I’m into the long-term idea of getting the entire industry on one very capable standard.</p>
<p>The world of USB-C is still pretty wild; I’d guess maybe half of the adapters I order from Amazon straight-up don’t work because it’s a money grab for cheap-o Chinese manufacturers, who in turn don’t confirm to the spec correctly. I expect that from that shady underworld, but not from Apple.</p>
<p>And Apple’s capable of good stuff, of course. Nathan K, the intrepid Google engineer who has gained notoriety for <a href="https://plus.google.com/collection/UQ94NB">reviewing USB-C cables accessories for quality</a>, says that Apple’s USB-C charge cable is the best he’s ever seen. But from an end user perspective, the high-level approach of what Apple’s doing here is maddening.</p>
<p>The MacBook Pro drops all ports in favor of USB-C; great, I can get behind that. But it’s like they got into the Red Zone and decided to punt at the six yard line instead of taking the easy three points.</p>
<p>People oft-repeat the charge that Apple has released an iPhone that you can’t plug into its own laptops out-of-the-box, but it’s even worse than that. Here’s what I carry around:</p>
<ul>
<li>MacBook Pro, which charges via USB-C</li>
<li>iPhone X, which charges via Qi and Lightning</li>
<li>Apple Watch Series 2, which charges via proprietary inductive charging</li>
<li>AirPods, which charge via Lightning</li>
</ul>
<p>Wireless charging is probably the way forward, although 1) it’s slow, and 2) “fast” charging is <a href="https://www.macrumors.com/guide/iphone-x-fast-charging-speeds-compared/">only available through some Qi chargers</a> that have been blessed by Apple. Apple Watch Series 3 will have <em>some</em> Qi charging, but apparently <a href="http://appleinsider.com/articles/17/09/21/apple-watch-series-3-confirmed-to-work-with-select-qi-wireless-chargers">that also depends on the charger</a>.</p>
<p>All of this will be fixed for me whenever Apple manages to release AirPower, a long-delayed, possibly really expensive, multi-device charger that will charge all my things at once, provided I drop the money on AirPower, new AirPods, a new Apple Watch, and decide to bring the whole charging setup with me to a cafe. Then I’ll be set to slowly charge all my devices at once.</p>
<p>They didn’t even name the damn thing Apple Juice, either.</p>
<h2 id="skipping-on-both-convenience-and-standards">Skipping on both convenience <em>and</em> standards</h2>
<p>Giving up some convenience for a standardized port makes sense. I really miss MagSafe, but was willing to move to USB-C Power Delivery for the speed and consistency in standard. But I’m not sure the trade off was worth it in practice.</p>
<p>I’ve been using Apple’s new charger for a year and a half now, and it’s generally worse than what we’ve had for the last decade. No MagSafe means that it frequently slides out of my MacBook Pro if I made a small adjustment. What’s worse, that can happen while it’s still physically <em>in the port</em>. The number of times I’ve gotten up to head out for work or a conference, only to realize I have a half-drained battery because the cabling had slid out <em>just a little bit</em> is just way too high.</p>
<p>What’s worse, I’m so damn angry at the cable itself. I like that it’s USB-C on both ends, so I can pop it out and use it to charge other devices (but <em>not</em> transfer data, because Apple’s charging cable doesn’t support that mode of Type-C at all, which is probably going to confuse so many people in the future). But the cable is much thicker than previous Apple laptop chargers, which makes it harder to wrap around something. And most egregious of all, there’s no pop-up cable wrapping helpers on the brick itself.</p>
<p><img src="/images/posts/apple-connects-power.jpg" /></p>
<p>This means it’s become tricky to toss my charger into my bag without it becoming a goddamn mess, both when I put it in there, and especially when I pull it out. I know there was a concern with old power chargers of frayed cabling from people wrapping it too tightly around the cable wrappers, but those people are stupid anyway and probably put their fingers inside power sockets too.</p>
<p>The cable itself is so thick that it ends up tightly twisting in on itself pretty frequently, which likely isn’t great for the longevity of the cable anyways. At this point I’ve found it’s just best to shove the whole thing into my bag and hope for the best.</p>
<h2 id="gimme-some-more">Gimme some more</h2>
<p>The other thing that really kills me is alright, Apple’s way forward is to buy all of their accessories, got it. But their own coverage of their own ecosystem is terrible:</p>
<ul>
<li>There’s no USB-C Apple Watch charger. If you want to charge your Watch off of your laptop using Apple’s blessed accessories, you’ll need to get a long Apple Watch cable, and then plug it into their $20 USB-C to USB-A adapter.</li>
<li>There’s no short Apple cables. The shortest Apple Watch cable is a foot long, and the shortest Lightning cable is a foot and a half. There’s no real option for something tiny you can just toss into a bag and forget about (and in the case of Apple Watch, you can’t buy this from a third-party either, since Apple refuses to certify non-propriety cables, which also means there are <em>zero</em> options if you want a USB-C Apple Watch charger).</li>
<li>Apple hasn’t really updated their wall chargers in quite some time, either. In the iPhone X box — The Most Advanced Phone For The Next Decade — <a href="https://twitter.com/holman/status/907683124145876994">you get a piddly 5W charger</a>. Would love to see the base model bumped up, but also some more engineering work done on their size and form of their chargers. There’s plenty of <a href="https://twitter.com/holman/status/883420626987479042">small tweaks</a> that could be done to improve what we’ve been stuck with for over a decade.</li>
<li>Lightning is my favorite port of all time. It feels so damn great. But Apple has to let the past die. Kill it, if you have to. The entire planet is going to be moving to USB-C, and the sooner you get on board with that now, the sooner you’ll look less like an idiot when you inevitably do anyway. I know; I’m going to miss that <em>click</em> too. But the port’s dead, Jim.</li>
</ul>
<p>All of this would be fixed if Apple fully embraced standards, but what Apple is doing is even worse than that: they force USB-C on their laptops, but they ignore components like an Apple Watch USB-C adapter at the same time they prevent third parties from building their own solutions.</p>
<p>So I still continue to bring my box of cables and chargers and adapters and shit every time I travel.</p>
<h2 id="living-in-apples-future">Living in Apple’s Future</h2>
<p>Part of this is sour grapes for being an early adopter, I know. I’m sure there’ll be hot takes about yet another Apple sucker getting their just rewards. I’m mostly just bummed that I’ve been buying into Apple’s future, but Apple <em>themselves</em> haven’t bought into their fucking future. It’s not even a matter of supporting two ecosystems while USB-C battles plays themselves out; it’s that Apple has just thrown their hands up and completely ignored these problems.</p>
<p>Which, to be fair, isn’t necessarily such a bad thing necessarily, but it’s a little hard to spend hours of keynotes patting themselves on the back for making such <em>INNOVATIVE, ADVANCED PLATFORMS THAT WILL LAST FOR THE NEXT DECADE</em> at the same time they ignore all this.</p>
<p>It seems like they’re asleep at the wheel, or, more likely, there’s no one team in charge of accessories and the ecosystem anymore at Apple. Like a committee came up with some broad thoughts for the next five years and expected teams to adapt to that whenever they’d like to. Which also again, isn’t necessarily out of the ordinary for most companies… but it doesn’t scream “Apple”.</p>
<p>It’s not new revolutionary iPhone technology we’re talking about there, either; it’s relatively cheap cables that have to conform to a standard. Wireless will probably be a thing at some point in time, but that’s a lot further way than a couple of USB-C ports today.</p>
<p>Anyway, none of this would have happened if Steve would have been there. Is that how I’m supposed to close this? Think that’s in the Apple gripes template somewhere.</p>
A Stack Story2018-01-12T00:00:00+00:002018-01-12T00:00:00+00:00http://zachholman.com/posts/a-stack-story<p>Something remarkable has happened in our industry. I wouldn’t have thought it would even remotely been a possibility three years ago. But if you look at the facts, you really think about what has happened, the conclusion is inescapable:</p>
<p>I’m now a JavaScript developer.</p>
<p>This is weird.</p>
<p>More than a decade ago I started writing Ruby professionally. I loved Ruby, and still love it. I can solve pretty much all of my problems in Ruby, and I was content with that. I was never one of those polyglots that bounce around every six months on something new. Ruby was just a tool, and I never really cared much about tools. They just existed for me to use. And that was just fine.</p>
<p>I first started writing JavaScript almost two decades ago, and I got good at it. Well, not at JavaScript, but at copy and pasting snippets. First Dynamic HTML fireball cursors, and then jQuery plugins and approaches. But whatever, I was a Ruby developer, that was my game.</p>
<p>But I’ve been <a href="/posts/start-up-your-startup">building my own company</a> and I’ve found myself with an app that’s half Ruby, half JavaScript. And… I… like… it?</p>
<p>This got me to thinking. I mean, I don’t really care about Ruby, or JavaScript, or whatever language you use, or how you use it. But I started thinking a lot recently about the tools and stacks we choose, and how they impact our companies.</p>
<h2 id="companies">Companies</h2>
<p>One odd thing that jumped out at me is that no one really chooses their company’s development stack.</p>
<p>Isn’t that weird? We have a gajillion blog posts and hot takes on which programming language is better, or faster, or hipper. But there’s only three times in the lifetime of a company where you make decisions on which stack to pick. The first and biggest is when the company is founded. Most reasonable technology companies will just coast on related technologies from whatever your founder initially picked. So tip number one: don’t work for shitty founders.</p>
<p>The second is when you’re spreading around the edges. You stand up a small service to do handle some small problem. And most importantly, that’s a small enough thing where you can write it in that Cool New Language you’ve been messing with, and no one will really get too mad at you. That’s really how you can build things at larger companies: just don’t mess with anything big, and hopefully no one will care enough about you long enough for you to innovate something dumb before they stop you.</p>
<p>The final, of course, is The Big Rewrite. You legitimately are running into problems with your tools and feel like starting from scratch will improve your life in measurable ways. I think this happens less regularly than most people think. You’re up against a lot of problems, though: you’ve already hired a lot of people who might have to change skill sets, and they’ll sometimes work against these big changes if it makes their own stature in the company less valuable. It also takes time to change everything over, too, and most companies are terrible at doing a big rewrite while at the same time pushing forward on new features and functionality.</p>
<p>These big platform changes don’t happen very often in reasonable tech companies, and usually not all at once.</p>
<p>But even though it might not happen often… it’s still worth being critical and thinking about what this impact means for us.</p>
<h2 id="technology-leadership">Technology leadership</h2>
<p>I joined GitHub in 2010. Saw us go from nine people to 250 people, and now they’re closing in on 800 employees.</p>
<p>GitHub’s always been a leader in the Ruby community. And it’s been really interesting — in hindsight — thinking about taking a leadership position in a programming language. There were others, of course: Basecamp, Engine Yard, Shopify, Heroku, Square, and Stripe have all had big impacts in the Ruby world, but GitHub was the most obvious example of a “Ruby shop” to most people.</p>
<p>We benefited immeasurably from that depth into a particular technology. For one, we could hire anyone. Pretty sure for awhile there if you had vaguely heard of metaprogramming we would have thrown you a sack full of money, an option grant, and access to the main github/github repo.</p>
<p>That’s the benefit of being locked-in to a particular set of technology. Of being known for that technology.</p>
<p>And that’s the whole point of a startup: you feel like you have a perspective on the universe that’s obvious to you and non-obvious to everyone else. And if your bet wins, well, you really, really do well.</p>
<p>So being known for a language, framework, or whatever it is… getting really deep into a particular language… that’s good stuff if you’re right. We weren’t already right, though.</p>
<p>GitHub’s an interesting example to look at because it’s so heavily dogfooded. We could build a great product because we ran into those pains ourselves. But years ago those cracks had started to show in the product.</p>
<p>Take a look at it this way. GitHub internally, from the start, is primarily one giant Rails application. There was always a smaller constellation of microservices surrounding it, but most of the product work is going to be bottlenecked in that one repository.</p>
<p>Why is it so hard to do work across multiple repositories in GitHub? Because a lot of their product people only work in one repository every day.</p>
<p>Why do you think it took almost a decade for GitHub to add unlimited private repositories? Because every GitHubber already had free private repositories as an employment perk. They didn’t face the pain that others did.</p>
<p>Why do you think GitHub still doesn’t have deeper integrations with Docker? Because GitHub had written its own library with Puppet to handle development environments, and hardly anyone had used Docker in a professional context. GitLab, for example, came up a little later, and had a team with a broader, fresher background, and that helped lead them to build out a container registry inside the product.</p>
<p>None of this is to say that what GitHub is doing is bad, or good, or anything, really. They’re just tradeoffs. This goes back to an ancient discussion of do you want a lot of depth in one thing, or a lot of breadth across a lot of things?</p>
<p>And there’s a point you reach where you need to start looking at those tradeoffs you’re making and determine if the tradeoffs you made in the past are still valued the same today.</p>
<h2 id="20-time">20% Time</h2>
<p>Google’s 20% time is, as far as I can tell, bullshit, resulting in requiring 120% of your time. But the sentiment is still worth considering.</p>
<p>If you get away from the math of whatever percentage you’re talking about, what 20% time means is that the company is paying you to work on something that isn’t necessarily your job. It’s a forcing function to get more eyeballs on processes in the company that otherwise wouldn’t be able to justify changes, or a rewrite, or auxiliary services. It gets you explicitly thinking about bigger-picture questions that the company would otherwise not want to address.</p>
<p>I think that’s a powerful thing. If some new technology comes around that legitimately is a game changer, you need people with the experience to have used it in a professional context prior to adding it to your production stack. And you’re never going to have the ability to do that unless you’re uncomfortable enough to build this type of self-reflection into your own workflows. Because if you don’t, you’ll never get to it. There’s <em>always</em> more work to do. More work that needs to be done before you can rewrite this. More work that needs to be done before you can optimize this. More work, more work. Not enough time to dance around and experiment, so you can catch those order-of-magnitude jumps when they do pop up.</p>
<p>So this is how your company can build upon your existing stack, and level it up. Your old way of thinking might have worked in the past, but maybe it’s time for something new. It’s important to challenge yourself, to put yourself in a position of failing.</p>
<h2 id="you">You</h2>
<p>Some of you might have picked up that I’m not really talking about companies. I could give two shits about companies, really. I care about you. I care about me. I care about people. So this talk isn’t <em>about</em> companies. It’s about the people at those companies.</p>
<p>You should spend some time thinking about the tools you use. Not all the time, not even a lot of the time. But sometimes. Ask yourself if the values you held years ago still ring true today. They might, and that’s fine. They might not, and that’s fine. But sometimes you have to make that self-assessment of your own environment.</p>
<p>Sometimes it’s the opposite: you can have just as much problems from bouncing around between technologies too much. Sometimes you just need a home. Depth is just as important as breadth. But again, just thinking about these issues is the important part.</p>
<p>It’s easy to be jaded in this industry. It’s easy to become complacent.</p>
<h2 id="failing-fast">Failing fast</h2>
<p>The Fresh Prince himself, Will Smith, of all people, had <a href="https://www.youtube.com/watch?v=rBUSsP9rDsw&t=1s">this pretty good Instagram story this week</a>. He talked a lot about failing fast, and failing forward. That you can’t really get ahead without fucking up, and embracing those fuckups. Part of that is understanding that complacency can be a killer. I wasn’t asking enough of myself, and as such, I found myself complacent. I’d go to the same conferences, see the same people, build the same apps. And again, that’s cool — it’s good to get deeper on concepts, just as much as it is to go broad on other concepts. But I wasn’t self-critical about myself enough to see the problems until I had incurred enough debt to where it was hard to unbury myself.</p>
<p>Again, no one really should care much about developer tools, not really. I’m not really trying to talk like switching to JavaScript holds the secret to happiness. I mean, the language doesn’t have static typing. But developer tools are a small part of life, and a big part of how we express our professional careers.</p>
<p>A lot of this just depends on identifying what you want out of your career. Are you focusing on upward mobility? Do you want to manage people? Do you want to be a senior engineer? A founder? An investor? I wish I would have asked these questions of myself a lot earlier. Because once you start asking these questions of yourself, you start making changes to make it to that result earlier.</p>
<p>Anyway, all of this is just a long winded way of saying: ask yourself questions, see where you’re at, and if you’re not happy with where you’re going, make some changes. I know way too many people who get complacent and then wonder why everything around them sucks.</p>
<p>So get ahead of the curve and start thinking about <em>your</em> Big Rewrite before you actually need it.</p>