Skip to content

Instantly share code, notes, and snippets.

@twolfson
Last active June 10, 2023 08:23
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save twolfson/de1b004dd22536b8e668 to your computer and use it in GitHub Desktop.
Save twolfson/de1b004dd22536b8e668 to your computer and use it in GitHub Desktop.
timever, time based versioning

timever

time-ver

Time based versioning

Synopsis

For versioning published releases of websites/services, we use a datetime based string to denote different releases

DATE.TIME.SUBTIME

  • DATE, a YYYYMMDD formatted value
    • YYYY is a 4 digit year (e.g. 2015)
    • MM is a 2 digit month (e.g. 06)
    • DD is a 2 digit day (e.g. 08)
  • TIME, a HHMMSS formatted value
    • HH is a 2 digit hour (e.g. 08)
    • MM is a 2 digit minute (e.g. 25)
    • SS is a 2 digit second (e.g. 22)
  • SUBTIME, a N formatted value
    • N is a 9 digit nanosecond (e.g. 039235885)

// TODO: Maybe use date % notation instead?

Example:

20150608.082522.039235885

Generating on GNU/Linux:

date --utc +%Y%m%d.%H%M%S.%N

Why

When we began automating our release process for websites/services, we found there was no well formed solution to identifying what release is live.

  • semver doesn't play nice with automation, usually minor or patch is bumped without any consideration
    • Introducing actual semver releases into automated releases is possible but doesn't gain any value from a maintainer's perspective
  • Using revisions from git works but makes it hard for human's to refer to reference and has no intrinsic value

We solved this by using time; a very practical value from a human's perspective. From a given version, we know when it was created and can reuse that reference during the publication process.

Other benefits include:

  • Compatible with semver libraries (although, x and * lose meaning quickly)
  • Lexically sortable

Usage

We like to use our versioning in:

  • git tag at publication (e.g. creating/pushing a new release)
  • Folder/archive name for release (e.g. stored on server with archive for easy debugging of live version)
@twolfson
Copy link
Author

Alternative names:

  • timestamp ver
  • datetime ver
  • dt ver

@twolfson
Copy link
Author

OS X doesn't support the %N notation. As a result, we need to install coreutils which makes it gdate. Maybe we can document that as well as other language alternatives (e.g. python):

$ python -c "import datetime; print(datetime.datetime.utcnow().strftime('%Y%m%d.%H%M%S.%f000'))"
20150821.052303.269441000

@twolfson
Copy link
Author

Probably subconscious influence via Package Control

@twolfson
Copy link
Author

node flavor:

$ node --eval 'console.log((new Date()).toISOString().replace(/^(\d{4})-(\d{2})-(\d{2})T(\d{2}):(\d{2}):(\d{2}).(\d{3})Z$/, "$1$2$3.$4$5$6.$7000000"))'
20150821.053452.369000000

@twolfson
Copy link
Author

ruby flavor:

$ ruby -e "require 'date'; puts DateTime::now().strftime('%Y%m%d.%H%M%S.%N')"
20150821.004046.688937332

@twolfson
Copy link
Author

Simplfied ruby flavor (with UTC):

$ ruby -e "puts Time.now.utc.strftime('%Y%m%d.%H%M%S.%N')"

http://stackoverflow.com/questions/755669/how-do-i-convert-datetime-now-to-utc-in-ruby

@twolfson
Copy link
Author

twolfson commented Feb 7, 2018

Updated Node.js version:

$ node --print "new Date().toISOString().replace(/[-:Z]/g, '').replace('T', '.') + '000000'"
20180207.224159.441000000

There is process.hrtime() support for nanoseconds but it would require right padding with zeroes

@plippe
Copy link

plippe commented Jun 10, 2023

Java version that works in sbt for scala projects

DateTimeFormatter
      .ofPattern("yyyyMMdd.HHmmss.n")
      .withZone(ZoneOffset.UTC)
      .format(Instant.now()),

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment