On my latest blog post, I wanted to try something new. When publishing, I wanted to publish on a future date (specifically at midnight the next day). I set up the date of the post to include the next day, and then planned to go onto Travis at midnight to build the newest version of the site… with the new blog post. And then I continued working on my website for the night.
But what ended up happening was Travis CI built on my
release branch at 6:15pm… and suddenly my new blog post was live 😱! What happened? Well, Travis CI by default runs in UTC. So, since 6:00pm in CST is midnight in UTC, Travis CI determined it was time to publish the blog post. I quickly reverted that commit on my
gh-pages branch to hide the new post once again, and then worked to find a solution to make Travis CI behave for the remainder of the night.
What I ended up finding was this. By adding these lines to the
.travis.yml file, we can override Travis CI’s default time zone and have it bundle in CST.
before_install: - export TZ=America/Chicago
I thought I would be satisfied with this. I develop my site in CST (or CDT in the summer), and now Travis will also bundle in that time zone. But, after more thought, I realized that this is really just a bandaid fix 🤕. What if I move across the country and now live in a different time zone permanently? What if I’m traveling internationally (say in France), and I’m blogging while I’m there. I’m no longer going to be thinking in terms of
America/Chicago time zone… say I publish a blog post at 12pm noon in France. When I get home to Minneapolis, should the blog post still show up as having been published at 12pm noon? Or should it properly show a 6–7 hour time difference?
So after a lot of thinking, I decided that the best (and most sustainable) way to design a website is so that all dates/times are UTC in the database (Jekyll doesn’t have a DB, so just in the HTML,
sitemap.xml). Then, we can convert all UTC date/times to become in a user’s local time when they navigate to my site ⏱.
Time zones are complicated. I’ve dabbled with them a little bit, but they tend to make my head spin 💫. So, I made hefty goal for myself 🥴. When I publish a blog post, I can specify the publish date/time in my local time zone. Jekyll will build the blog post as having been published at the corresponding UTC time. And when a reader looks at the blog post on the website, it’ll give the date/time in their local time zone (which may be my time zone, but it could also be different).
Let’s look at an example. I publish a blog post at 10:15pm in CST on Jan. 17, 2020:
2020-01-17 22:15:00 -0600
Jekyll will compile and store the blog post as having been published in UTC (notice the date change):
2020-01-18 04:15:00 +0000
But when a reader looks at the blog post online, it will show in their local time zone (I normally hide the specific times when showing publishing dates):
### CST - Minnesota January 17, 2020 22:15 ### PST - California January 17, 2020 20:15 ### CEST - France January 18, 2020 05:15
Most of the time, I publish my blog posts at midnight on a specific date. This means that to everybody in
America/Chicago and east of me, the date should be that specific date. But technically, to everybody west, the blog post went live on the day before.
So, with this as my final goal, I went ahead to try to implement this in five steps:
1️. The entire Jekyll site must build in UTC
This was easy. I set the following in my
I also took this opportunity to remove the
export TZ=America/Chicago from my
.travis.yml, since now the Jekyll site and Travis CI will naturally be on the same wavelength.
2️. Add the specific date/time of each blog posts’ publish time
This was also pretty easy. You can just add the date to the front matter of each blog post:
date: 2020-01-17 22:15:00 -0600
You can specify the time the post should be published as well, although, as I stated above, I normally just use
00:00:00, or midnight. For what I’m working with, the last part is important. That’s the time zone offset. In Minnesota, that’ll be
-0600 in the winter time (CST), or
-0500 in the summer (CDT)—I always used to get those two mixed up. But, I’ve decided that I want this to be easy for me to use going forward… so I should always write the date/time as I’m looking at my clock (in 24 hour time of course) with my current time zone offset 📝.
3️. Jekyll will store the blog post as being published in UTC
When I put both of these pieces together, the result was immediate. As soon as I ran
jekyll serve on my website, I noticed that the
sitemap.xml label the published date/time as in UTC! Yes! Nice and quick.
4️. Show the users the published date/time in their local time zones
The entire script locates all of the HTML elements with the class
var monthNames = ['January', 'February', 'March', 'April', 'May', 'June', 'July','August', 'September', 'October','November', 'December' ]; var dateArray = '2020-01-18 04:15:00 +0000'.split(/[^0-9]/); // localDate = Fri Jan 17 2020 22:15:00 GMT-0600 (Central Standard Time) var localDate = new Date( Date.UTC(dateArray, dateArray-1, dateArray, dateArray, dateArray, dateArray) ); var day = localDate.getDate(); // 17 var year = localDate.getFullYear(); // 2020 var monthIndex = localDate.getMonth(); // 0 return monthNames[monthIndex] + ' ' + day + ', ' + year; // January 17, 2020
All together, this now looks like this:
I’m hiding a lot of the effort this took me… don’t get me wrong, it took me what felt like hours to develop this method, and I’m still finding bugs in it 🦟.
5️. Don’t show the published date in the URL of the blog posts
In our example, I published a post on the 17th of January at night in CST. But we see now, that if I travel to France and look back at past blog posts, it’ll look as if it was published on the 18th of January. BUT, the URL of the blog post will include the published date. See an example below:
If the date the site is showing the reader is moving around depending on the readers’ location, then this is confusing—the URL date won’t change!
If I’m honest, having the date in the URL was never my favorite thing… it always bugged me. I just never cared quite enough to change it, and to deal with the redirects I’d have to set up. But given this inconsistency, I decided that I finally cared enough to make the shift ↪.
I added the
jekyll-redirect-from plugin to my
_config.yml. And from there, redirecting is actually quite easy. In the front matter of each blog post, I add the new URL of the blog post, and then redirect to the new URL from the old URL:
Now, when I navigate to my blog posts at the old URL, my browser automatically redirects to the new URL. Hopefully that prevents my SEO ranking from going down 😬.
At the end of the day, this goal maybe wasn’t too hefty. It maybe took about six hours of total effort. I haven’t traveled yet to see if it works as expected, but I have a trip planned in about a month, so we’ll see then 🤷🏻♀️.
The moral of the story is that time zones are complicated, but the most robust websites will take them into account. If your website has date/times, then you should show them to your users in their local times, if possible. And you should be careful when storing data with date/times to make sure they are all stored in the same time zone, so they don’t get conflicted.
EDIT: Since writing this blog post, I’ve moved my default branch to be
main, instead of
source. I originally named it
release because the documentation I was following named it that, but realized later that the name
main fit my workflow better. Also, I’ve moved my
master branch to be called
gh-pages, and I’ve updated this blog post accordingly.